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"
62 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
65 #include "gstab.h" /* for N_SLINE */
68 #ifndef TARGET_NO_PROTOTYPE
69 #define TARGET_NO_PROTOTYPE 0
72 #define min(A,B) ((A) < (B) ? (A) : (B))
73 #define max(A,B) ((A) > (B) ? (A) : (B))
75 /* Structure used to define the rs6000 stack */
76 typedef struct rs6000_stack {
77 int reload_completed; /* stack info won't change from here on */
78 int first_gp_reg_save; /* first callee saved GP register used */
79 int first_fp_reg_save; /* first callee saved FP register used */
80 int first_altivec_reg_save; /* first callee saved AltiVec register used */
81 int lr_save_p; /* true if the link reg needs to be saved */
82 int cr_save_p; /* true if the CR reg needs to be saved */
83 unsigned int vrsave_mask; /* mask of vec registers to save */
84 int push_p; /* true if we need to allocate stack space */
85 int calls_p; /* true if the function makes any calls */
86 int world_save_p; /* true if we're saving *everything*:
87 r13-r31, cr, f14-f31, vrsave, v20-v31 */
88 enum rs6000_abi abi; /* which ABI to use */
89 int gp_save_offset; /* offset to save GP regs from initial SP */
90 int fp_save_offset; /* offset to save FP regs from initial SP */
91 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
92 int lr_save_offset; /* offset to save LR from initial SP */
93 int cr_save_offset; /* offset to save CR from initial SP */
94 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
95 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
96 int varargs_save_offset; /* offset to save the varargs registers */
97 int ehrd_offset; /* offset to EH return data */
98 int reg_size; /* register size (4 or 8) */
99 HOST_WIDE_INT vars_size; /* variable save area size */
100 int parm_size; /* outgoing parameter size */
101 int save_size; /* save area size */
102 int fixed_size; /* fixed size of stack frame */
103 int gp_size; /* size of saved GP registers */
104 int fp_size; /* size of saved FP registers */
105 int altivec_size; /* size of saved AltiVec registers */
106 int cr_size; /* size to hold CR if not in save_size */
107 int vrsave_size; /* size to hold VRSAVE if not in save_size */
108 int altivec_padding_size; /* size of altivec alignment padding if
110 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
111 int spe_padding_size;
112 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
113 int spe_64bit_regs_used;
117 /* A C structure for machine-specific, per-function data.
118 This is added to the cfun structure. */
119 typedef struct GTY(()) machine_function
121 /* Some local-dynamic symbol. */
122 const char *some_ld_name;
123 /* Whether the instruction chain has been scanned already. */
124 int insn_chain_scanned_p;
125 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
126 int ra_needs_full_frame;
127 /* Flags if __builtin_return_address (0) was used. */
129 /* Cache lr_save_p after expansion of builtin_eh_return. */
131 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
132 varargs save area. */
133 HOST_WIDE_INT varargs_save_offset;
134 /* Temporary stack slot to use for SDmode copies. This slot is
135 64-bits wide and is allocated early enough so that the offset
136 does not overflow the 16-bit load/store offset field. */
137 rtx sdmode_stack_slot;
140 /* Target cpu type */
142 struct rs6000_cpu_select rs6000_select[3] =
144 /* switch name, tune arch */
145 { (const char *)0, "--with-cpu=", 1, 1 },
146 { (const char *)0, "-mcpu=", 1, 1 },
147 { (const char *)0, "-mtune=", 1, 0 },
150 /* String variables to hold the various options. */
151 static const char *rs6000_sched_insert_nops_str;
152 static const char *rs6000_sched_costly_dep_str;
153 static const char *rs6000_recip_name;
156 static const char *rs6000_abi_name;
157 static const char *rs6000_sdata_name;
160 /* Support targetm.vectorize.builtin_mask_for_load. */
161 static GTY(()) tree altivec_builtin_mask_for_load;
163 /* Set to nonzero once AIX common-mode calls have been defined. */
164 static GTY(()) int common_mode_defined;
166 /* Label number of label created for -mrelocatable, to call to so we can
167 get the address of the GOT section */
168 static int rs6000_pic_labelno;
171 /* Counter for labels which are to be placed in .fixup. */
172 int fixuplabelno = 0;
175 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
178 /* Specify the machine mode that pointers have. After generation of rtl, the
179 compiler makes no further distinction between pointers and any other objects
180 of this machine mode. The type is unsigned since not all things that
181 include rs6000.h also include machmode.h. */
182 unsigned rs6000_pmode;
184 /* Width in bits of a pointer. */
185 unsigned rs6000_pointer_size;
187 #ifdef HAVE_AS_GNU_ATTRIBUTE
188 /* Flag whether floating point values have been passed/returned. */
189 static bool rs6000_passes_float;
190 /* Flag whether vector values have been passed/returned. */
191 static bool rs6000_passes_vector;
192 /* Flag whether small (<= 8 byte) structures have been returned. */
193 static bool rs6000_returns_struct;
196 /* Value is TRUE if register/mode pair is acceptable. */
197 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
199 /* Maximum number of registers needed for a given register class and mode. */
200 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
202 /* How many registers are needed for a given register and mode. */
203 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
205 /* Map register number to register class. */
206 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
208 /* Reload functions based on the type and the vector unit. */
209 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
211 /* Built in types. */
212 tree rs6000_builtin_types[RS6000_BTI_MAX];
213 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
215 /* Flag to say the TOC is initialized */
217 char toc_label_name[10];
219 /* Cached value of rs6000_variable_issue. This is cached in
220 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
221 static short cached_can_issue_more;
223 static GTY(()) section *read_only_data_section;
224 static GTY(()) section *private_data_section;
225 static GTY(()) section *read_only_private_data_section;
226 static GTY(()) section *sdata2_section;
227 static GTY(()) section *toc_section;
229 /* True for any options that were explicitly set. */
231 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
232 bool alignment; /* True if -malign- was used. */
233 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
234 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
235 bool spe; /* True if -mspe= was used. */
236 bool float_gprs; /* True if -mfloat-gprs= was used. */
237 bool long_double; /* True if -mlong-double- was used. */
238 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
239 bool vrsave; /* True if -mvrsave was used. */
240 bool cmodel; /* True if -mcmodel was used. */
241 } rs6000_explicit_options;
243 struct builtin_description
245 /* mask is not const because we're going to alter it below. This
246 nonsense will go away when we rewrite the -march infrastructure
247 to give us more target flag bits. */
249 const enum insn_code icode;
250 const char *const name;
251 const enum rs6000_builtins code;
254 /* Describe the vector unit used for modes. */
255 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
256 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
258 /* Register classes for various constraints that are based on the target
260 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
262 /* Describe the alignment of a vector. */
263 int rs6000_vector_align[NUM_MACHINE_MODES];
265 /* Map selected modes to types for builtins. */
266 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
268 /* What modes to automatically generate reciprocal divide estimate (fre) and
269 reciprocal sqrt (frsqrte) for. */
270 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
272 /* Masks to determine which reciprocal esitmate instructions to generate
274 enum rs6000_recip_mask {
275 RECIP_SF_DIV = 0x001, /* Use divide estimate */
276 RECIP_DF_DIV = 0x002,
277 RECIP_V4SF_DIV = 0x004,
278 RECIP_V2DF_DIV = 0x008,
280 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
281 RECIP_DF_RSQRT = 0x020,
282 RECIP_V4SF_RSQRT = 0x040,
283 RECIP_V2DF_RSQRT = 0x080,
285 /* Various combination of flags for -mrecip=xxx. */
287 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
288 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
289 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
291 RECIP_HIGH_PRECISION = RECIP_ALL,
293 /* On low precision machines like the power5, don't enable double precision
294 reciprocal square root estimate, since it isn't accurate enough. */
295 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
298 /* -mrecip options. */
301 const char *string; /* option name */
302 unsigned int mask; /* mask bits to set */
303 } recip_options[] = {
304 { "all", RECIP_ALL },
305 { "none", RECIP_NONE },
306 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
308 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
309 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
310 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
311 | RECIP_V2DF_RSQRT) },
312 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
313 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
316 /* 2 argument gen function typedef. */
317 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
320 /* Target cpu costs. */
322 struct processor_costs {
323 const int mulsi; /* cost of SImode multiplication. */
324 const int mulsi_const; /* cost of SImode multiplication by constant. */
325 const int mulsi_const9; /* cost of SImode mult by short constant. */
326 const int muldi; /* cost of DImode multiplication. */
327 const int divsi; /* cost of SImode division. */
328 const int divdi; /* cost of DImode division. */
329 const int fp; /* cost of simple SFmode and DFmode insns. */
330 const int dmul; /* cost of DFmode multiplication (and fmadd). */
331 const int sdiv; /* cost of SFmode division (fdivs). */
332 const int ddiv; /* cost of DFmode division (fdiv). */
333 const int cache_line_size; /* cache line size in bytes. */
334 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
335 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
336 const int simultaneous_prefetches; /* number of parallel prefetch
340 const struct processor_costs *rs6000_cost;
342 /* Processor costs (relative to an add) */
344 /* Instruction size costs on 32bit processors. */
346 struct processor_costs size32_cost = {
347 COSTS_N_INSNS (1), /* mulsi */
348 COSTS_N_INSNS (1), /* mulsi_const */
349 COSTS_N_INSNS (1), /* mulsi_const9 */
350 COSTS_N_INSNS (1), /* muldi */
351 COSTS_N_INSNS (1), /* divsi */
352 COSTS_N_INSNS (1), /* divdi */
353 COSTS_N_INSNS (1), /* fp */
354 COSTS_N_INSNS (1), /* dmul */
355 COSTS_N_INSNS (1), /* sdiv */
356 COSTS_N_INSNS (1), /* ddiv */
363 /* Instruction size costs on 64bit processors. */
365 struct processor_costs size64_cost = {
366 COSTS_N_INSNS (1), /* mulsi */
367 COSTS_N_INSNS (1), /* mulsi_const */
368 COSTS_N_INSNS (1), /* mulsi_const9 */
369 COSTS_N_INSNS (1), /* muldi */
370 COSTS_N_INSNS (1), /* divsi */
371 COSTS_N_INSNS (1), /* divdi */
372 COSTS_N_INSNS (1), /* fp */
373 COSTS_N_INSNS (1), /* dmul */
374 COSTS_N_INSNS (1), /* sdiv */
375 COSTS_N_INSNS (1), /* ddiv */
382 /* Instruction costs on RIOS1 processors. */
384 struct processor_costs rios1_cost = {
385 COSTS_N_INSNS (5), /* mulsi */
386 COSTS_N_INSNS (4), /* mulsi_const */
387 COSTS_N_INSNS (3), /* mulsi_const9 */
388 COSTS_N_INSNS (5), /* muldi */
389 COSTS_N_INSNS (19), /* divsi */
390 COSTS_N_INSNS (19), /* divdi */
391 COSTS_N_INSNS (2), /* fp */
392 COSTS_N_INSNS (2), /* dmul */
393 COSTS_N_INSNS (19), /* sdiv */
394 COSTS_N_INSNS (19), /* ddiv */
395 128, /* cache line size */
401 /* Instruction costs on RIOS2 processors. */
403 struct processor_costs rios2_cost = {
404 COSTS_N_INSNS (2), /* mulsi */
405 COSTS_N_INSNS (2), /* mulsi_const */
406 COSTS_N_INSNS (2), /* mulsi_const9 */
407 COSTS_N_INSNS (2), /* muldi */
408 COSTS_N_INSNS (13), /* divsi */
409 COSTS_N_INSNS (13), /* divdi */
410 COSTS_N_INSNS (2), /* fp */
411 COSTS_N_INSNS (2), /* dmul */
412 COSTS_N_INSNS (17), /* sdiv */
413 COSTS_N_INSNS (17), /* ddiv */
414 256, /* cache line size */
420 /* Instruction costs on RS64A processors. */
422 struct processor_costs rs64a_cost = {
423 COSTS_N_INSNS (20), /* mulsi */
424 COSTS_N_INSNS (12), /* mulsi_const */
425 COSTS_N_INSNS (8), /* mulsi_const9 */
426 COSTS_N_INSNS (34), /* muldi */
427 COSTS_N_INSNS (65), /* divsi */
428 COSTS_N_INSNS (67), /* divdi */
429 COSTS_N_INSNS (4), /* fp */
430 COSTS_N_INSNS (4), /* dmul */
431 COSTS_N_INSNS (31), /* sdiv */
432 COSTS_N_INSNS (31), /* ddiv */
433 128, /* cache line size */
439 /* Instruction costs on MPCCORE processors. */
441 struct processor_costs mpccore_cost = {
442 COSTS_N_INSNS (2), /* mulsi */
443 COSTS_N_INSNS (2), /* mulsi_const */
444 COSTS_N_INSNS (2), /* mulsi_const9 */
445 COSTS_N_INSNS (2), /* muldi */
446 COSTS_N_INSNS (6), /* divsi */
447 COSTS_N_INSNS (6), /* divdi */
448 COSTS_N_INSNS (4), /* fp */
449 COSTS_N_INSNS (5), /* dmul */
450 COSTS_N_INSNS (10), /* sdiv */
451 COSTS_N_INSNS (17), /* ddiv */
452 32, /* cache line size */
458 /* Instruction costs on PPC403 processors. */
460 struct processor_costs ppc403_cost = {
461 COSTS_N_INSNS (4), /* mulsi */
462 COSTS_N_INSNS (4), /* mulsi_const */
463 COSTS_N_INSNS (4), /* mulsi_const9 */
464 COSTS_N_INSNS (4), /* muldi */
465 COSTS_N_INSNS (33), /* divsi */
466 COSTS_N_INSNS (33), /* divdi */
467 COSTS_N_INSNS (11), /* fp */
468 COSTS_N_INSNS (11), /* dmul */
469 COSTS_N_INSNS (11), /* sdiv */
470 COSTS_N_INSNS (11), /* ddiv */
471 32, /* cache line size */
477 /* Instruction costs on PPC405 processors. */
479 struct processor_costs ppc405_cost = {
480 COSTS_N_INSNS (5), /* mulsi */
481 COSTS_N_INSNS (4), /* mulsi_const */
482 COSTS_N_INSNS (3), /* mulsi_const9 */
483 COSTS_N_INSNS (5), /* muldi */
484 COSTS_N_INSNS (35), /* divsi */
485 COSTS_N_INSNS (35), /* divdi */
486 COSTS_N_INSNS (11), /* fp */
487 COSTS_N_INSNS (11), /* dmul */
488 COSTS_N_INSNS (11), /* sdiv */
489 COSTS_N_INSNS (11), /* ddiv */
490 32, /* cache line size */
496 /* Instruction costs on PPC440 processors. */
498 struct processor_costs ppc440_cost = {
499 COSTS_N_INSNS (3), /* mulsi */
500 COSTS_N_INSNS (2), /* mulsi_const */
501 COSTS_N_INSNS (2), /* mulsi_const9 */
502 COSTS_N_INSNS (3), /* muldi */
503 COSTS_N_INSNS (34), /* divsi */
504 COSTS_N_INSNS (34), /* divdi */
505 COSTS_N_INSNS (5), /* fp */
506 COSTS_N_INSNS (5), /* dmul */
507 COSTS_N_INSNS (19), /* sdiv */
508 COSTS_N_INSNS (33), /* ddiv */
509 32, /* cache line size */
515 /* Instruction costs on PPC476 processors. */
517 struct processor_costs ppc476_cost = {
518 COSTS_N_INSNS (4), /* mulsi */
519 COSTS_N_INSNS (4), /* mulsi_const */
520 COSTS_N_INSNS (4), /* mulsi_const9 */
521 COSTS_N_INSNS (4), /* muldi */
522 COSTS_N_INSNS (11), /* divsi */
523 COSTS_N_INSNS (11), /* divdi */
524 COSTS_N_INSNS (6), /* fp */
525 COSTS_N_INSNS (6), /* dmul */
526 COSTS_N_INSNS (19), /* sdiv */
527 COSTS_N_INSNS (33), /* ddiv */
528 32, /* l1 cache line size */
534 /* Instruction costs on PPC601 processors. */
536 struct processor_costs ppc601_cost = {
537 COSTS_N_INSNS (5), /* mulsi */
538 COSTS_N_INSNS (5), /* mulsi_const */
539 COSTS_N_INSNS (5), /* mulsi_const9 */
540 COSTS_N_INSNS (5), /* muldi */
541 COSTS_N_INSNS (36), /* divsi */
542 COSTS_N_INSNS (36), /* divdi */
543 COSTS_N_INSNS (4), /* fp */
544 COSTS_N_INSNS (5), /* dmul */
545 COSTS_N_INSNS (17), /* sdiv */
546 COSTS_N_INSNS (31), /* ddiv */
547 32, /* cache line size */
553 /* Instruction costs on PPC603 processors. */
555 struct processor_costs ppc603_cost = {
556 COSTS_N_INSNS (5), /* mulsi */
557 COSTS_N_INSNS (3), /* mulsi_const */
558 COSTS_N_INSNS (2), /* mulsi_const9 */
559 COSTS_N_INSNS (5), /* muldi */
560 COSTS_N_INSNS (37), /* divsi */
561 COSTS_N_INSNS (37), /* divdi */
562 COSTS_N_INSNS (3), /* fp */
563 COSTS_N_INSNS (4), /* dmul */
564 COSTS_N_INSNS (18), /* sdiv */
565 COSTS_N_INSNS (33), /* ddiv */
566 32, /* cache line size */
572 /* Instruction costs on PPC604 processors. */
574 struct processor_costs ppc604_cost = {
575 COSTS_N_INSNS (4), /* mulsi */
576 COSTS_N_INSNS (4), /* mulsi_const */
577 COSTS_N_INSNS (4), /* mulsi_const9 */
578 COSTS_N_INSNS (4), /* muldi */
579 COSTS_N_INSNS (20), /* divsi */
580 COSTS_N_INSNS (20), /* divdi */
581 COSTS_N_INSNS (3), /* fp */
582 COSTS_N_INSNS (3), /* dmul */
583 COSTS_N_INSNS (18), /* sdiv */
584 COSTS_N_INSNS (32), /* ddiv */
585 32, /* cache line size */
591 /* Instruction costs on PPC604e processors. */
593 struct processor_costs ppc604e_cost = {
594 COSTS_N_INSNS (2), /* mulsi */
595 COSTS_N_INSNS (2), /* mulsi_const */
596 COSTS_N_INSNS (2), /* mulsi_const9 */
597 COSTS_N_INSNS (2), /* muldi */
598 COSTS_N_INSNS (20), /* divsi */
599 COSTS_N_INSNS (20), /* divdi */
600 COSTS_N_INSNS (3), /* fp */
601 COSTS_N_INSNS (3), /* dmul */
602 COSTS_N_INSNS (18), /* sdiv */
603 COSTS_N_INSNS (32), /* ddiv */
604 32, /* cache line size */
610 /* Instruction costs on PPC620 processors. */
612 struct processor_costs ppc620_cost = {
613 COSTS_N_INSNS (5), /* mulsi */
614 COSTS_N_INSNS (4), /* mulsi_const */
615 COSTS_N_INSNS (3), /* mulsi_const9 */
616 COSTS_N_INSNS (7), /* muldi */
617 COSTS_N_INSNS (21), /* divsi */
618 COSTS_N_INSNS (37), /* divdi */
619 COSTS_N_INSNS (3), /* fp */
620 COSTS_N_INSNS (3), /* dmul */
621 COSTS_N_INSNS (18), /* sdiv */
622 COSTS_N_INSNS (32), /* ddiv */
623 128, /* cache line size */
629 /* Instruction costs on PPC630 processors. */
631 struct processor_costs ppc630_cost = {
632 COSTS_N_INSNS (5), /* mulsi */
633 COSTS_N_INSNS (4), /* mulsi_const */
634 COSTS_N_INSNS (3), /* mulsi_const9 */
635 COSTS_N_INSNS (7), /* muldi */
636 COSTS_N_INSNS (21), /* divsi */
637 COSTS_N_INSNS (37), /* divdi */
638 COSTS_N_INSNS (3), /* fp */
639 COSTS_N_INSNS (3), /* dmul */
640 COSTS_N_INSNS (17), /* sdiv */
641 COSTS_N_INSNS (21), /* ddiv */
642 128, /* cache line size */
648 /* Instruction costs on Cell processor. */
649 /* COSTS_N_INSNS (1) ~ one add. */
651 struct processor_costs ppccell_cost = {
652 COSTS_N_INSNS (9/2)+2, /* mulsi */
653 COSTS_N_INSNS (6/2), /* mulsi_const */
654 COSTS_N_INSNS (6/2), /* mulsi_const9 */
655 COSTS_N_INSNS (15/2)+2, /* muldi */
656 COSTS_N_INSNS (38/2), /* divsi */
657 COSTS_N_INSNS (70/2), /* divdi */
658 COSTS_N_INSNS (10/2), /* fp */
659 COSTS_N_INSNS (10/2), /* dmul */
660 COSTS_N_INSNS (74/2), /* sdiv */
661 COSTS_N_INSNS (74/2), /* ddiv */
662 128, /* cache line size */
668 /* Instruction costs on PPC750 and PPC7400 processors. */
670 struct processor_costs ppc750_cost = {
671 COSTS_N_INSNS (5), /* mulsi */
672 COSTS_N_INSNS (3), /* mulsi_const */
673 COSTS_N_INSNS (2), /* mulsi_const9 */
674 COSTS_N_INSNS (5), /* muldi */
675 COSTS_N_INSNS (17), /* divsi */
676 COSTS_N_INSNS (17), /* divdi */
677 COSTS_N_INSNS (3), /* fp */
678 COSTS_N_INSNS (3), /* dmul */
679 COSTS_N_INSNS (17), /* sdiv */
680 COSTS_N_INSNS (31), /* ddiv */
681 32, /* cache line size */
687 /* Instruction costs on PPC7450 processors. */
689 struct processor_costs ppc7450_cost = {
690 COSTS_N_INSNS (4), /* mulsi */
691 COSTS_N_INSNS (3), /* mulsi_const */
692 COSTS_N_INSNS (3), /* mulsi_const9 */
693 COSTS_N_INSNS (4), /* muldi */
694 COSTS_N_INSNS (23), /* divsi */
695 COSTS_N_INSNS (23), /* divdi */
696 COSTS_N_INSNS (5), /* fp */
697 COSTS_N_INSNS (5), /* dmul */
698 COSTS_N_INSNS (21), /* sdiv */
699 COSTS_N_INSNS (35), /* ddiv */
700 32, /* cache line size */
706 /* Instruction costs on PPC8540 processors. */
708 struct processor_costs ppc8540_cost = {
709 COSTS_N_INSNS (4), /* mulsi */
710 COSTS_N_INSNS (4), /* mulsi_const */
711 COSTS_N_INSNS (4), /* mulsi_const9 */
712 COSTS_N_INSNS (4), /* muldi */
713 COSTS_N_INSNS (19), /* divsi */
714 COSTS_N_INSNS (19), /* divdi */
715 COSTS_N_INSNS (4), /* fp */
716 COSTS_N_INSNS (4), /* dmul */
717 COSTS_N_INSNS (29), /* sdiv */
718 COSTS_N_INSNS (29), /* ddiv */
719 32, /* cache line size */
722 1, /* prefetch streams /*/
725 /* Instruction costs on E300C2 and E300C3 cores. */
727 struct processor_costs ppce300c2c3_cost = {
728 COSTS_N_INSNS (4), /* mulsi */
729 COSTS_N_INSNS (4), /* mulsi_const */
730 COSTS_N_INSNS (4), /* mulsi_const9 */
731 COSTS_N_INSNS (4), /* muldi */
732 COSTS_N_INSNS (19), /* divsi */
733 COSTS_N_INSNS (19), /* divdi */
734 COSTS_N_INSNS (3), /* fp */
735 COSTS_N_INSNS (4), /* dmul */
736 COSTS_N_INSNS (18), /* sdiv */
737 COSTS_N_INSNS (33), /* ddiv */
741 1, /* prefetch streams /*/
744 /* Instruction costs on PPCE500MC processors. */
746 struct processor_costs ppce500mc_cost = {
747 COSTS_N_INSNS (4), /* mulsi */
748 COSTS_N_INSNS (4), /* mulsi_const */
749 COSTS_N_INSNS (4), /* mulsi_const9 */
750 COSTS_N_INSNS (4), /* muldi */
751 COSTS_N_INSNS (14), /* divsi */
752 COSTS_N_INSNS (14), /* divdi */
753 COSTS_N_INSNS (8), /* fp */
754 COSTS_N_INSNS (10), /* dmul */
755 COSTS_N_INSNS (36), /* sdiv */
756 COSTS_N_INSNS (66), /* ddiv */
757 64, /* cache line size */
760 1, /* prefetch streams /*/
763 /* Instruction costs on PPCE500MC64 processors. */
765 struct processor_costs ppce500mc64_cost = {
766 COSTS_N_INSNS (4), /* mulsi */
767 COSTS_N_INSNS (4), /* mulsi_const */
768 COSTS_N_INSNS (4), /* mulsi_const9 */
769 COSTS_N_INSNS (4), /* muldi */
770 COSTS_N_INSNS (14), /* divsi */
771 COSTS_N_INSNS (14), /* divdi */
772 COSTS_N_INSNS (4), /* fp */
773 COSTS_N_INSNS (10), /* dmul */
774 COSTS_N_INSNS (36), /* sdiv */
775 COSTS_N_INSNS (66), /* ddiv */
776 64, /* cache line size */
779 1, /* prefetch streams /*/
782 /* Instruction costs on AppliedMicro Titan processors. */
784 struct processor_costs titan_cost = {
785 COSTS_N_INSNS (5), /* mulsi */
786 COSTS_N_INSNS (5), /* mulsi_const */
787 COSTS_N_INSNS (5), /* mulsi_const9 */
788 COSTS_N_INSNS (5), /* muldi */
789 COSTS_N_INSNS (18), /* divsi */
790 COSTS_N_INSNS (18), /* divdi */
791 COSTS_N_INSNS (10), /* fp */
792 COSTS_N_INSNS (10), /* dmul */
793 COSTS_N_INSNS (46), /* sdiv */
794 COSTS_N_INSNS (72), /* ddiv */
795 32, /* cache line size */
798 1, /* prefetch streams /*/
801 /* Instruction costs on POWER4 and POWER5 processors. */
803 struct processor_costs power4_cost = {
804 COSTS_N_INSNS (3), /* mulsi */
805 COSTS_N_INSNS (2), /* mulsi_const */
806 COSTS_N_INSNS (2), /* mulsi_const9 */
807 COSTS_N_INSNS (4), /* muldi */
808 COSTS_N_INSNS (18), /* divsi */
809 COSTS_N_INSNS (34), /* divdi */
810 COSTS_N_INSNS (3), /* fp */
811 COSTS_N_INSNS (3), /* dmul */
812 COSTS_N_INSNS (17), /* sdiv */
813 COSTS_N_INSNS (17), /* ddiv */
814 128, /* cache line size */
817 8, /* prefetch streams /*/
820 /* Instruction costs on POWER6 processors. */
822 struct processor_costs power6_cost = {
823 COSTS_N_INSNS (8), /* mulsi */
824 COSTS_N_INSNS (8), /* mulsi_const */
825 COSTS_N_INSNS (8), /* mulsi_const9 */
826 COSTS_N_INSNS (8), /* muldi */
827 COSTS_N_INSNS (22), /* divsi */
828 COSTS_N_INSNS (28), /* divdi */
829 COSTS_N_INSNS (3), /* fp */
830 COSTS_N_INSNS (3), /* dmul */
831 COSTS_N_INSNS (13), /* sdiv */
832 COSTS_N_INSNS (16), /* ddiv */
833 128, /* cache line size */
836 16, /* prefetch streams */
839 /* Instruction costs on POWER7 processors. */
841 struct processor_costs power7_cost = {
842 COSTS_N_INSNS (2), /* mulsi */
843 COSTS_N_INSNS (2), /* mulsi_const */
844 COSTS_N_INSNS (2), /* mulsi_const9 */
845 COSTS_N_INSNS (2), /* muldi */
846 COSTS_N_INSNS (18), /* divsi */
847 COSTS_N_INSNS (34), /* divdi */
848 COSTS_N_INSNS (3), /* fp */
849 COSTS_N_INSNS (3), /* dmul */
850 COSTS_N_INSNS (13), /* sdiv */
851 COSTS_N_INSNS (16), /* ddiv */
852 128, /* cache line size */
855 12, /* prefetch streams */
858 /* Instruction costs on POWER A2 processors. */
860 struct processor_costs ppca2_cost = {
861 COSTS_N_INSNS (16), /* mulsi */
862 COSTS_N_INSNS (16), /* mulsi_const */
863 COSTS_N_INSNS (16), /* mulsi_const9 */
864 COSTS_N_INSNS (16), /* muldi */
865 COSTS_N_INSNS (22), /* divsi */
866 COSTS_N_INSNS (28), /* divdi */
867 COSTS_N_INSNS (3), /* fp */
868 COSTS_N_INSNS (3), /* dmul */
869 COSTS_N_INSNS (59), /* sdiv */
870 COSTS_N_INSNS (72), /* ddiv */
874 16, /* prefetch streams */
878 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
879 #undef RS6000_BUILTIN
880 #undef RS6000_BUILTIN_EQUATE
881 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
882 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
884 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
886 #include "rs6000-builtin.def"
889 #undef RS6000_BUILTIN
890 #undef RS6000_BUILTIN_EQUATE
892 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
893 static tree (*rs6000_veclib_handler) (tree, tree, tree);
896 static bool rs6000_function_ok_for_sibcall (tree, tree);
897 static const char *rs6000_invalid_within_doloop (const_rtx);
898 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
899 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
900 static rtx rs6000_generate_compare (rtx, enum machine_mode);
901 static void rs6000_emit_stack_tie (void);
902 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
903 static bool spe_func_has_64bit_regs_p (void);
904 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
906 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
907 static unsigned rs6000_hash_constant (rtx);
908 static unsigned toc_hash_function (const void *);
909 static int toc_hash_eq (const void *, const void *);
910 static bool reg_offset_addressing_ok_p (enum machine_mode);
911 static bool virtual_stack_registers_memory_p (rtx);
912 static bool constant_pool_expr_p (rtx);
913 static bool legitimate_small_data_p (enum machine_mode, rtx);
914 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
915 static struct machine_function * rs6000_init_machine_status (void);
916 static bool rs6000_assemble_integer (rtx, unsigned int, int);
917 static bool no_global_regs_above (int, bool);
918 #ifdef HAVE_GAS_HIDDEN
919 static void rs6000_assemble_visibility (tree, int);
921 static int rs6000_ra_ever_killed (void);
922 static bool rs6000_attribute_takes_identifier_p (const_tree);
923 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
924 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
925 static bool rs6000_ms_bitfield_layout_p (const_tree);
926 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
927 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
928 static const char *rs6000_mangle_type (const_tree);
929 static void rs6000_set_default_type_attributes (tree);
930 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
931 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
932 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
933 enum machine_mode, bool, bool, bool);
934 static bool rs6000_reg_live_or_pic_offset_p (int);
935 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
936 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
937 static void rs6000_restore_saved_cr (rtx, int);
938 static bool rs6000_output_addr_const_extra (FILE *, rtx);
939 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
940 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
941 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
943 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
944 static bool rs6000_return_in_memory (const_tree, const_tree);
945 static rtx rs6000_function_value (const_tree, const_tree, bool);
946 static void rs6000_file_start (void);
948 static int rs6000_elf_reloc_rw_mask (void);
949 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
950 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
951 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
952 static void rs6000_elf_asm_init_sections (void);
953 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
954 unsigned HOST_WIDE_INT);
955 static void rs6000_elf_encode_section_info (tree, rtx, int)
958 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
959 static void rs6000_alloc_sdmode_stack_slot (void);
960 static void rs6000_instantiate_decls (void);
962 static void rs6000_xcoff_asm_output_anchor (rtx);
963 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
964 static void rs6000_xcoff_asm_init_sections (void);
965 static int rs6000_xcoff_reloc_rw_mask (void);
966 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
967 static section *rs6000_xcoff_select_section (tree, int,
968 unsigned HOST_WIDE_INT);
969 static void rs6000_xcoff_unique_section (tree, int);
970 static section *rs6000_xcoff_select_rtx_section
971 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
972 static const char * rs6000_xcoff_strip_name_encoding (const char *);
973 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
974 static void rs6000_xcoff_file_start (void);
975 static void rs6000_xcoff_file_end (void);
977 static int rs6000_variable_issue (FILE *, int, rtx, int);
978 static int rs6000_register_move_cost (enum machine_mode,
979 reg_class_t, reg_class_t);
980 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
981 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
982 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
983 static int rs6000_debug_address_cost (rtx, bool);
984 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
985 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
986 static void rs6000_sched_init (FILE *, int, int);
987 static bool is_microcoded_insn (rtx);
988 static bool is_nonpipeline_insn (rtx);
989 static bool is_cracked_insn (rtx);
990 static bool is_branch_slot_insn (rtx);
991 static bool is_load_insn (rtx);
992 static rtx get_store_dest (rtx pat);
993 static bool is_store_insn (rtx);
994 static bool set_to_load_agen (rtx,rtx);
995 static bool adjacent_mem_locations (rtx,rtx);
996 static int rs6000_adjust_priority (rtx, int);
997 static int rs6000_issue_rate (void);
998 static bool rs6000_is_costly_dependence (dep_t, int, int);
999 static rtx get_next_active_insn (rtx, rtx);
1000 static bool insn_terminates_group_p (rtx , enum group_termination);
1001 static bool insn_must_be_first_in_group (rtx);
1002 static bool insn_must_be_last_in_group (rtx);
1003 static bool is_costly_group (rtx *, rtx);
1004 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1005 static int redefine_groups (FILE *, int, rtx, rtx);
1006 static int pad_groups (FILE *, int, rtx, rtx);
1007 static void rs6000_sched_finish (FILE *, int);
1008 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1009 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1010 static int rs6000_use_sched_lookahead (void);
1011 static int rs6000_use_sched_lookahead_guard (rtx);
1012 static void * rs6000_alloc_sched_context (void);
1013 static void rs6000_init_sched_context (void *, bool);
1014 static void rs6000_set_sched_context (void *);
1015 static void rs6000_free_sched_context (void *);
1016 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1017 static tree rs6000_builtin_mask_for_load (void);
1018 static tree rs6000_builtin_mul_widen_even (tree);
1019 static tree rs6000_builtin_mul_widen_odd (tree);
1020 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1021 static tree rs6000_builtin_vec_perm (tree, tree *);
1022 static bool rs6000_builtin_support_vector_misalignment (enum
1026 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1028 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1030 static void def_builtin (int, const char *, tree, int);
1031 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1032 static void rs6000_init_builtins (void);
1033 static tree rs6000_builtin_decl (unsigned, bool);
1035 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1036 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1037 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1038 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1039 static void altivec_init_builtins (void);
1040 static unsigned builtin_hash_function (const void *);
1041 static int builtin_hash_eq (const void *, const void *);
1042 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1043 enum machine_mode, enum machine_mode,
1044 enum rs6000_builtins, const char *name);
1045 static void rs6000_common_init_builtins (void);
1046 static void rs6000_init_libfuncs (void);
1048 static void paired_init_builtins (void);
1049 static rtx paired_expand_builtin (tree, rtx, bool *);
1050 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1051 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1052 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1054 static void enable_mask_for_builtins (struct builtin_description *, int,
1055 enum rs6000_builtins,
1056 enum rs6000_builtins);
1057 static void spe_init_builtins (void);
1058 static rtx spe_expand_builtin (tree, rtx, bool *);
1059 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1060 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1061 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1062 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1063 static rs6000_stack_t *rs6000_stack_info (void);
1064 static void debug_stack_info (rs6000_stack_t *);
1066 static rtx altivec_expand_builtin (tree, rtx, bool *);
1067 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1068 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1069 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1070 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1071 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1072 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1073 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1074 static rtx altivec_expand_vec_set_builtin (tree);
1075 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1076 static int get_element_number (tree, tree);
1077 static void rs6000_option_override (void);
1078 static void rs6000_option_init_struct (struct gcc_options *);
1079 static void rs6000_option_default_params (void);
1080 static bool rs6000_handle_option (size_t, const char *, int);
1081 static int rs6000_loop_align_max_skip (rtx);
1082 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1083 static int first_altivec_reg_to_save (void);
1084 static unsigned int compute_vrsave_mask (void);
1085 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1086 static void is_altivec_return_reg (rtx, void *);
1087 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1088 int easy_vector_constant (rtx, enum machine_mode);
1089 static rtx rs6000_dwarf_register_span (rtx);
1090 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1091 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1092 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1093 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1094 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1095 static rtx rs6000_delegitimize_address (rtx);
1096 static rtx rs6000_tls_get_addr (void);
1097 static rtx rs6000_got_sym (void);
1098 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1099 static const char *rs6000_get_some_local_dynamic_name (void);
1100 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1101 static rtx rs6000_complex_function_value (enum machine_mode);
1102 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1103 enum machine_mode, const_tree);
1104 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1105 HOST_WIDE_INT, int);
1106 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1109 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1112 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1113 const_tree, HOST_WIDE_INT,
1115 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1116 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1117 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1119 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1121 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1123 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1124 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1125 enum machine_mode, tree,
1127 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1129 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1131 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1133 static void macho_branch_islands (void);
1134 static int no_previous_def (tree function_name);
1135 static tree get_prev_label (tree function_name);
1136 static void rs6000_darwin_file_start (void);
1139 static tree rs6000_build_builtin_va_list (void);
1140 static void rs6000_va_start (tree, rtx);
1141 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1142 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1143 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1144 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1145 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1146 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1148 static tree rs6000_stack_protect_fail (void);
1150 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1153 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1156 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1158 = rs6000_legitimize_reload_address;
1160 static bool rs6000_mode_dependent_address_p (const_rtx);
1161 static bool rs6000_mode_dependent_address (const_rtx);
1162 static bool rs6000_debug_mode_dependent_address (const_rtx);
1163 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1164 = rs6000_mode_dependent_address;
1166 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1167 enum machine_mode, rtx);
1168 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1171 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1172 enum machine_mode, rtx)
1173 = rs6000_secondary_reload_class;
1175 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1176 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1178 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1179 = rs6000_preferred_reload_class;
1181 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1184 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1188 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1190 = rs6000_secondary_memory_needed;
1192 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1195 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1199 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1202 = rs6000_cannot_change_mode_class;
1204 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1206 struct secondary_reload_info *);
1208 static const reg_class_t *rs6000_ira_cover_classes (void);
1210 const int INSN_NOT_AVAILABLE = -1;
1211 static enum machine_mode rs6000_eh_return_filter_mode (void);
1212 static bool rs6000_can_eliminate (const int, const int);
1213 static void rs6000_conditional_register_usage (void);
1214 static void rs6000_trampoline_init (rtx, tree, rtx);
1216 /* Hash table stuff for keeping track of TOC entries. */
1218 struct GTY(()) toc_hash_struct
1220 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1221 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1223 enum machine_mode key_mode;
1227 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1229 /* Hash table to keep track of the argument types for builtin functions. */
1231 struct GTY(()) builtin_hash_struct
1234 enum machine_mode mode[4]; /* return value + 3 arguments. */
1235 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1238 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1240 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1241 static void rs6000_function_specific_save (struct cl_target_option *);
1242 static void rs6000_function_specific_restore (struct cl_target_option *);
1243 static void rs6000_function_specific_print (FILE *, int,
1244 struct cl_target_option *);
1245 static bool rs6000_can_inline_p (tree, tree);
1246 static void rs6000_set_current_function (tree);
1249 /* Default register names. */
1250 char rs6000_reg_names[][8] =
1252 "0", "1", "2", "3", "4", "5", "6", "7",
1253 "8", "9", "10", "11", "12", "13", "14", "15",
1254 "16", "17", "18", "19", "20", "21", "22", "23",
1255 "24", "25", "26", "27", "28", "29", "30", "31",
1256 "0", "1", "2", "3", "4", "5", "6", "7",
1257 "8", "9", "10", "11", "12", "13", "14", "15",
1258 "16", "17", "18", "19", "20", "21", "22", "23",
1259 "24", "25", "26", "27", "28", "29", "30", "31",
1260 "mq", "lr", "ctr","ap",
1261 "0", "1", "2", "3", "4", "5", "6", "7",
1263 /* AltiVec registers. */
1264 "0", "1", "2", "3", "4", "5", "6", "7",
1265 "8", "9", "10", "11", "12", "13", "14", "15",
1266 "16", "17", "18", "19", "20", "21", "22", "23",
1267 "24", "25", "26", "27", "28", "29", "30", "31",
1269 /* SPE registers. */
1270 "spe_acc", "spefscr",
1271 /* Soft frame pointer. */
1275 #ifdef TARGET_REGNAMES
1276 static const char alt_reg_names[][8] =
1278 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1279 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1280 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1281 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1282 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1283 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1284 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1285 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1286 "mq", "lr", "ctr", "ap",
1287 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1289 /* AltiVec registers. */
1290 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1291 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1292 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1293 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1295 /* SPE registers. */
1296 "spe_acc", "spefscr",
1297 /* Soft frame pointer. */
1302 /* Table of valid machine attributes. */
1304 static const struct attribute_spec rs6000_attribute_table[] =
1306 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1307 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1308 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1309 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1310 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1311 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1312 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1313 SUBTARGET_ATTRIBUTE_TABLE,
1315 { NULL, 0, 0, false, false, false, NULL }
1318 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1319 static const struct default_options rs6000_option_optimization_table[] =
1321 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1322 { OPT_LEVELS_NONE, 0, NULL, 0 }
1325 #ifndef MASK_STRICT_ALIGN
1326 #define MASK_STRICT_ALIGN 0
1328 #ifndef TARGET_PROFILE_KERNEL
1329 #define TARGET_PROFILE_KERNEL 0
1332 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1333 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1335 /* Initialize the GCC target structure. */
1336 #undef TARGET_ATTRIBUTE_TABLE
1337 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1338 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1339 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1340 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1341 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1343 #undef TARGET_ASM_ALIGNED_DI_OP
1344 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1346 /* Default unaligned ops are only provided for ELF. Find the ops needed
1347 for non-ELF systems. */
1348 #ifndef OBJECT_FORMAT_ELF
1350 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1352 #undef TARGET_ASM_UNALIGNED_HI_OP
1353 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1354 #undef TARGET_ASM_UNALIGNED_SI_OP
1355 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1356 #undef TARGET_ASM_UNALIGNED_DI_OP
1357 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1360 #undef TARGET_ASM_UNALIGNED_HI_OP
1361 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1362 #undef TARGET_ASM_UNALIGNED_SI_OP
1363 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1364 #undef TARGET_ASM_UNALIGNED_DI_OP
1365 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1366 #undef TARGET_ASM_ALIGNED_DI_OP
1367 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1371 /* This hook deals with fixups for relocatable code and DI-mode objects
1373 #undef TARGET_ASM_INTEGER
1374 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1376 #ifdef HAVE_GAS_HIDDEN
1377 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1378 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1381 #undef TARGET_HAVE_TLS
1382 #define TARGET_HAVE_TLS HAVE_AS_TLS
1384 #undef TARGET_CANNOT_FORCE_CONST_MEM
1385 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1387 #undef TARGET_DELEGITIMIZE_ADDRESS
1388 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1390 #undef TARGET_ASM_FUNCTION_PROLOGUE
1391 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1392 #undef TARGET_ASM_FUNCTION_EPILOGUE
1393 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1395 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1396 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1398 #undef TARGET_LEGITIMIZE_ADDRESS
1399 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1401 #undef TARGET_SCHED_VARIABLE_ISSUE
1402 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1404 #undef TARGET_SCHED_ISSUE_RATE
1405 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1406 #undef TARGET_SCHED_ADJUST_COST
1407 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1408 #undef TARGET_SCHED_ADJUST_PRIORITY
1409 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1410 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1411 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1412 #undef TARGET_SCHED_INIT
1413 #define TARGET_SCHED_INIT rs6000_sched_init
1414 #undef TARGET_SCHED_FINISH
1415 #define TARGET_SCHED_FINISH rs6000_sched_finish
1416 #undef TARGET_SCHED_REORDER
1417 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1418 #undef TARGET_SCHED_REORDER2
1419 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1421 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1422 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1424 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1425 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1427 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1428 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1429 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1430 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1431 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1432 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1433 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1434 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1436 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1437 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1438 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1439 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1440 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1441 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1442 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1443 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1444 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1445 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1446 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1447 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1448 rs6000_builtin_support_vector_misalignment
1449 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1450 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1451 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1452 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1453 rs6000_builtin_vectorization_cost
1454 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1455 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1456 rs6000_preferred_simd_mode
1458 #undef TARGET_INIT_BUILTINS
1459 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1460 #undef TARGET_BUILTIN_DECL
1461 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1463 #undef TARGET_EXPAND_BUILTIN
1464 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1466 #undef TARGET_MANGLE_TYPE
1467 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1469 #undef TARGET_INIT_LIBFUNCS
1470 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1473 #undef TARGET_BINDS_LOCAL_P
1474 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1477 #undef TARGET_MS_BITFIELD_LAYOUT_P
1478 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1480 #undef TARGET_ASM_OUTPUT_MI_THUNK
1481 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1483 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1484 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1486 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1487 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1489 #undef TARGET_INVALID_WITHIN_DOLOOP
1490 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1492 #undef TARGET_REGISTER_MOVE_COST
1493 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1494 #undef TARGET_MEMORY_MOVE_COST
1495 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1496 #undef TARGET_RTX_COSTS
1497 #define TARGET_RTX_COSTS rs6000_rtx_costs
1498 #undef TARGET_ADDRESS_COST
1499 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1501 #undef TARGET_DWARF_REGISTER_SPAN
1502 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1504 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1505 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1507 /* On rs6000, function arguments are promoted, as are function return
1509 #undef TARGET_PROMOTE_FUNCTION_MODE
1510 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1512 #undef TARGET_RETURN_IN_MEMORY
1513 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1515 #undef TARGET_SETUP_INCOMING_VARARGS
1516 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1518 /* Always strict argument naming on rs6000. */
1519 #undef TARGET_STRICT_ARGUMENT_NAMING
1520 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1521 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1522 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1523 #undef TARGET_SPLIT_COMPLEX_ARG
1524 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1525 #undef TARGET_MUST_PASS_IN_STACK
1526 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1527 #undef TARGET_PASS_BY_REFERENCE
1528 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1529 #undef TARGET_ARG_PARTIAL_BYTES
1530 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1531 #undef TARGET_FUNCTION_ARG_ADVANCE
1532 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1533 #undef TARGET_FUNCTION_ARG
1534 #define TARGET_FUNCTION_ARG rs6000_function_arg
1535 #undef TARGET_FUNCTION_ARG_BOUNDARY
1536 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1538 #undef TARGET_BUILD_BUILTIN_VA_LIST
1539 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1541 #undef TARGET_EXPAND_BUILTIN_VA_START
1542 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1544 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1545 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1547 #undef TARGET_EH_RETURN_FILTER_MODE
1548 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1550 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1551 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1553 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1554 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1556 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1557 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1559 #undef TARGET_HANDLE_OPTION
1560 #define TARGET_HANDLE_OPTION rs6000_handle_option
1562 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1563 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1565 #undef TARGET_OPTION_OVERRIDE
1566 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1568 #undef TARGET_OPTION_INIT_STRUCT
1569 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1571 #undef TARGET_OPTION_DEFAULT_PARAMS
1572 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1574 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1575 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1577 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1578 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1579 rs6000_builtin_vectorized_function
1581 #undef TARGET_DEFAULT_TARGET_FLAGS
1582 #define TARGET_DEFAULT_TARGET_FLAGS \
1585 #undef TARGET_STACK_PROTECT_FAIL
1586 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1588 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1589 The PowerPC architecture requires only weak consistency among
1590 processors--that is, memory accesses between processors need not be
1591 sequentially consistent and memory accesses among processors can occur
1592 in any order. The ability to order memory accesses weakly provides
1593 opportunities for more efficient use of the system bus. Unless a
1594 dependency exists, the 604e allows read operations to precede store
1596 #undef TARGET_RELAXED_ORDERING
1597 #define TARGET_RELAXED_ORDERING true
1600 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1601 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1604 /* Use a 32-bit anchor range. This leads to sequences like:
1606 addis tmp,anchor,high
1609 where tmp itself acts as an anchor, and can be shared between
1610 accesses to the same 64k page. */
1611 #undef TARGET_MIN_ANCHOR_OFFSET
1612 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1613 #undef TARGET_MAX_ANCHOR_OFFSET
1614 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1615 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1616 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1618 #undef TARGET_BUILTIN_RECIPROCAL
1619 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1621 #undef TARGET_EXPAND_TO_RTL_HOOK
1622 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1624 #undef TARGET_INSTANTIATE_DECLS
1625 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1627 #undef TARGET_SECONDARY_RELOAD
1628 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1630 #undef TARGET_IRA_COVER_CLASSES
1631 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1633 #undef TARGET_LEGITIMATE_ADDRESS_P
1634 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1636 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1637 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1639 #undef TARGET_CAN_ELIMINATE
1640 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1642 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1643 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1645 #undef TARGET_TRAMPOLINE_INIT
1646 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1648 #undef TARGET_FUNCTION_VALUE
1649 #define TARGET_FUNCTION_VALUE rs6000_function_value
1651 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1652 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1654 #undef TARGET_OPTION_SAVE
1655 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1657 #undef TARGET_OPTION_RESTORE
1658 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1660 #undef TARGET_OPTION_PRINT
1661 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1663 #undef TARGET_CAN_INLINE_P
1664 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1666 #undef TARGET_SET_CURRENT_FUNCTION
1667 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1669 struct gcc_target targetm = TARGET_INITIALIZER;
1672 /* Simplifications for entries below. */
1675 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1676 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1679 /* Some OSs don't support saving the high part of 64-bit registers on context
1680 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1681 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1682 either, the user must explicitly specify them and we won't interfere with
1683 the user's specification. */
1686 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1687 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1688 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1689 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1690 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1691 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1692 | MASK_RECIP_PRECISION)
1695 /* Masks for instructions set at various powerpc ISAs. */
1697 ISA_2_1_MASKS = MASK_MFCRF,
1698 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1699 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1701 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1702 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1703 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1704 server and embedded. */
1705 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1706 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1707 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1709 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1710 altivec is a win so enable it. */
1711 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1712 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1716 /* This table occasionally claims that a processor does not support a
1717 particular feature even though it does, but the feature is slower than the
1718 alternative. Thus, it shouldn't be relied on as a complete description of
1719 the processor's support.
1721 Please keep this list in order, and don't forget to update the documentation
1722 in invoke.texi when adding a new processor or flag. */
1726 const char *const name; /* Canonical processor name. */
1727 const enum processor_type processor; /* Processor type enum value. */
1728 const int target_enable; /* Target flags to enable. */
1731 static struct rs6000_ptt const processor_target_table[] =
1733 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1734 {"403", PROCESSOR_PPC403,
1735 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1736 {"405", PROCESSOR_PPC405,
1737 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1738 {"405fp", PROCESSOR_PPC405,
1739 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1740 {"440", PROCESSOR_PPC440,
1741 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1742 {"440fp", PROCESSOR_PPC440,
1743 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1744 {"464", PROCESSOR_PPC440,
1745 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1746 {"464fp", PROCESSOR_PPC440,
1747 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1748 {"476", PROCESSOR_PPC476,
1749 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1750 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1751 {"476fp", PROCESSOR_PPC476,
1752 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1753 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1754 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1755 {"601", PROCESSOR_PPC601,
1756 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1757 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1758 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1759 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1760 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1761 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"620", PROCESSOR_PPC620,
1763 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1764 {"630", PROCESSOR_PPC630,
1765 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1766 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1767 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1768 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1769 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1770 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1771 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1772 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1773 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1775 /* 8548 has a dummy entry for now. */
1776 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1778 {"a2", PROCESSOR_PPCA2,
1779 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1780 | MASK_CMPB | MASK_NO_UPDATE },
1781 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1782 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1783 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1785 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1786 | MASK_PPC_GFXOPT | MASK_ISEL},
1787 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1788 {"970", PROCESSOR_POWER4,
1789 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1790 {"cell", PROCESSOR_CELL,
1791 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1792 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1793 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1794 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1795 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1796 {"G5", PROCESSOR_POWER4,
1797 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1798 {"titan", PROCESSOR_TITAN,
1799 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1800 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1801 {"power2", PROCESSOR_POWER,
1802 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1803 {"power3", PROCESSOR_PPC630,
1804 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1805 {"power4", PROCESSOR_POWER4,
1806 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1808 {"power5", PROCESSOR_POWER5,
1809 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1810 | MASK_MFCRF | MASK_POPCNTB},
1811 {"power5+", PROCESSOR_POWER5,
1812 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1813 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1814 {"power6", PROCESSOR_POWER6,
1815 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1816 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1817 | MASK_RECIP_PRECISION},
1818 {"power6x", PROCESSOR_POWER6,
1819 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1820 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1821 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1822 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1823 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1824 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1825 | MASK_VSX | MASK_RECIP_PRECISION},
1826 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1827 {"powerpc64", PROCESSOR_POWERPC64,
1828 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1829 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1830 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1831 {"rios2", PROCESSOR_RIOS2,
1832 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1833 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1834 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1835 {"rs64", PROCESSOR_RS64A,
1836 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1839 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1843 rs6000_cpu_name_lookup (const char *name)
1849 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1850 if (! strcmp (name, processor_target_table[i].name))
1858 /* Return number of consecutive hard regs needed starting at reg REGNO
1859 to hold something of mode MODE.
1860 This is ordinarily the length in words of a value of mode MODE
1861 but can be less for certain modes in special long registers.
1863 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1864 scalar instructions. The upper 32 bits are only available to the
1867 POWER and PowerPC GPRs hold 32 bits worth;
1868 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1871 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1873 unsigned HOST_WIDE_INT reg_size;
1875 if (FP_REGNO_P (regno))
1876 reg_size = (VECTOR_MEM_VSX_P (mode)
1877 ? UNITS_PER_VSX_WORD
1878 : UNITS_PER_FP_WORD);
1880 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1881 reg_size = UNITS_PER_SPE_WORD;
1883 else if (ALTIVEC_REGNO_P (regno))
1884 reg_size = UNITS_PER_ALTIVEC_WORD;
1886 /* The value returned for SCmode in the E500 double case is 2 for
1887 ABI compatibility; storing an SCmode value in a single register
1888 would require function_arg and rs6000_spe_function_arg to handle
1889 SCmode so as to pass the value correctly in a pair of
1891 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1892 && !DECIMAL_FLOAT_MODE_P (mode))
1893 reg_size = UNITS_PER_FP_WORD;
1896 reg_size = UNITS_PER_WORD;
1898 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1901 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1904 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1906 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1908 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1909 implementations. Don't allow an item to be split between a FP register
1910 and an Altivec register. */
1911 if (VECTOR_MEM_VSX_P (mode))
1913 if (FP_REGNO_P (regno))
1914 return FP_REGNO_P (last_regno);
1916 if (ALTIVEC_REGNO_P (regno))
1917 return ALTIVEC_REGNO_P (last_regno);
1920 /* The GPRs can hold any mode, but values bigger than one register
1921 cannot go past R31. */
1922 if (INT_REGNO_P (regno))
1923 return INT_REGNO_P (last_regno);
1925 /* The float registers (except for VSX vector modes) can only hold floating
1926 modes and DImode. This excludes the 32-bit decimal float mode for
1928 if (FP_REGNO_P (regno))
1930 if (SCALAR_FLOAT_MODE_P (mode)
1931 && (mode != TDmode || (regno % 2) == 0)
1932 && FP_REGNO_P (last_regno))
1935 if (GET_MODE_CLASS (mode) == MODE_INT
1936 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1939 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1940 && PAIRED_VECTOR_MODE (mode))
1946 /* The CR register can only hold CC modes. */
1947 if (CR_REGNO_P (regno))
1948 return GET_MODE_CLASS (mode) == MODE_CC;
1950 if (CA_REGNO_P (regno))
1951 return mode == BImode;
1953 /* AltiVec only in AldyVec registers. */
1954 if (ALTIVEC_REGNO_P (regno))
1955 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1957 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1958 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1961 /* We cannot put TImode anywhere except general register and it must be able
1962 to fit within the register set. In the future, allow TImode in the
1963 Altivec or VSX registers. */
1965 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1968 /* Print interesting facts about registers. */
1970 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1974 for (r = first_regno; r <= last_regno; ++r)
1976 const char *comma = "";
1979 if (first_regno == last_regno)
1980 fprintf (stderr, "%s:\t", reg_name);
1982 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1985 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1986 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1990 fprintf (stderr, ",\n\t");
1995 if (rs6000_hard_regno_nregs[m][r] > 1)
1996 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1997 rs6000_hard_regno_nregs[m][r]);
1999 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2004 if (call_used_regs[r])
2008 fprintf (stderr, ",\n\t");
2013 len += fprintf (stderr, "%s%s", comma, "call-used");
2021 fprintf (stderr, ",\n\t");
2026 len += fprintf (stderr, "%s%s", comma, "fixed");
2032 fprintf (stderr, ",\n\t");
2036 fprintf (stderr, "%sregno = %d\n", comma, r);
2040 #define DEBUG_FMT_D "%-32s= %d\n"
2041 #define DEBUG_FMT_S "%-32s= %s\n"
2043 /* Print various interesting information with -mdebug=reg. */
2045 rs6000_debug_reg_global (void)
2047 static const char *const tf[2] = { "false", "true" };
2048 const char *nl = (const char *)0;
2050 char costly_num[20];
2052 const char *costly_str;
2053 const char *nop_str;
2054 const char *trace_str;
2055 const char *abi_str;
2056 const char *cmodel_str;
2058 /* Map enum rs6000_vector to string. */
2059 static const char *rs6000_debug_vector_unit[] = {
2068 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2069 LAST_VIRTUAL_REGISTER);
2070 rs6000_debug_reg_print (0, 31, "gr");
2071 rs6000_debug_reg_print (32, 63, "fp");
2072 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2075 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2076 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2077 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2078 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2079 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2080 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2081 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2082 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2083 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2087 "d reg_class = %s\n"
2088 "f reg_class = %s\n"
2089 "v reg_class = %s\n"
2090 "wa reg_class = %s\n"
2091 "wd reg_class = %s\n"
2092 "wf reg_class = %s\n"
2093 "ws reg_class = %s\n\n",
2094 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2095 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2096 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2097 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2098 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2099 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2102 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2103 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2106 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2108 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2109 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2115 if (rs6000_recip_control)
2117 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2119 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2120 if (rs6000_recip_bits[m])
2123 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2125 (RS6000_RECIP_AUTO_RE_P (m)
2127 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2128 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2130 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2133 fputs ("\n", stderr);
2136 if (rs6000_cpu_index >= 0)
2137 fprintf (stderr, DEBUG_FMT_S, "cpu",
2138 processor_target_table[rs6000_cpu_index].name);
2140 if (rs6000_tune_index >= 0)
2141 fprintf (stderr, DEBUG_FMT_S, "tune",
2142 processor_target_table[rs6000_tune_index].name);
2144 switch (rs6000_sched_costly_dep)
2146 case max_dep_latency:
2147 costly_str = "max_dep_latency";
2151 costly_str = "no_dep_costly";
2154 case all_deps_costly:
2155 costly_str = "all_deps_costly";
2158 case true_store_to_load_dep_costly:
2159 costly_str = "true_store_to_load_dep_costly";
2162 case store_to_load_dep_costly:
2163 costly_str = "store_to_load_dep_costly";
2167 costly_str = costly_num;
2168 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2172 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2174 switch (rs6000_sched_insert_nops)
2176 case sched_finish_regroup_exact:
2177 nop_str = "sched_finish_regroup_exact";
2180 case sched_finish_pad_groups:
2181 nop_str = "sched_finish_pad_groups";
2184 case sched_finish_none:
2185 nop_str = "sched_finish_none";
2190 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2194 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2196 switch (rs6000_sdata)
2203 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2207 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2211 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2216 switch (rs6000_traceback)
2218 case traceback_default: trace_str = "default"; break;
2219 case traceback_none: trace_str = "none"; break;
2220 case traceback_part: trace_str = "part"; break;
2221 case traceback_full: trace_str = "full"; break;
2222 default: trace_str = "unknown"; break;
2225 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2227 switch (rs6000_current_cmodel)
2229 case CMODEL_SMALL: cmodel_str = "small"; break;
2230 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2231 case CMODEL_LARGE: cmodel_str = "large"; break;
2232 default: cmodel_str = "unknown"; break;
2235 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2237 switch (rs6000_current_abi)
2239 case ABI_NONE: abi_str = "none"; break;
2240 case ABI_AIX: abi_str = "aix"; break;
2241 case ABI_V4: abi_str = "V4"; break;
2242 case ABI_DARWIN: abi_str = "darwin"; break;
2243 default: abi_str = "unknown"; break;
2246 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2248 if (rs6000_altivec_abi)
2249 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2252 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2254 if (rs6000_darwin64_abi)
2255 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2257 if (rs6000_float_gprs)
2258 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2260 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2261 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2262 tf[!!rs6000_align_branch_targets]);
2263 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2264 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2265 rs6000_long_double_type_size);
2266 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2267 (int)rs6000_sched_restricted_insns_priority);
2270 /* Initialize the various global tables that are based on register size. */
2272 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2278 /* Precalculate REGNO_REG_CLASS. */
2279 rs6000_regno_regclass[0] = GENERAL_REGS;
2280 for (r = 1; r < 32; ++r)
2281 rs6000_regno_regclass[r] = BASE_REGS;
2283 for (r = 32; r < 64; ++r)
2284 rs6000_regno_regclass[r] = FLOAT_REGS;
2286 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2287 rs6000_regno_regclass[r] = NO_REGS;
2289 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2290 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2292 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2293 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2294 rs6000_regno_regclass[r] = CR_REGS;
2296 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2297 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2298 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2299 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2300 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2301 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2302 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2303 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2304 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2305 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2307 /* Precalculate vector information, this must be set up before the
2308 rs6000_hard_regno_nregs_internal below. */
2309 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2311 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2312 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2313 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2316 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2317 rs6000_constraints[c] = NO_REGS;
2319 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2320 believes it can use native alignment or still uses 128-bit alignment. */
2321 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2332 /* V2DF mode, VSX only. */
2335 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2336 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2337 rs6000_vector_align[V2DFmode] = align64;
2340 /* V4SF mode, either VSX or Altivec. */
2343 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2344 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2345 rs6000_vector_align[V4SFmode] = align32;
2347 else if (TARGET_ALTIVEC)
2349 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2350 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2351 rs6000_vector_align[V4SFmode] = align32;
2354 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2358 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2359 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2360 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2361 rs6000_vector_align[V4SImode] = align32;
2362 rs6000_vector_align[V8HImode] = align32;
2363 rs6000_vector_align[V16QImode] = align32;
2367 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2368 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2369 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2373 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2374 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2375 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2379 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2380 Altivec doesn't have 64-bit support. */
2383 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2384 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2385 rs6000_vector_align[V2DImode] = align64;
2388 /* DFmode, see if we want to use the VSX unit. */
2389 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2391 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2392 rs6000_vector_mem[DFmode]
2393 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2394 rs6000_vector_align[DFmode] = align64;
2397 /* TODO add SPE and paired floating point vector support. */
2399 /* Register class constaints for the constraints that depend on compile
2401 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2402 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2404 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2405 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2409 /* At present, we just use VSX_REGS, but we have different constraints
2410 based on the use, in case we want to fine tune the default register
2411 class used. wa = any VSX register, wf = register class to use for
2412 V4SF, wd = register class to use for V2DF, and ws = register classs to
2413 use for DF scalars. */
2414 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2415 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2416 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2417 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2423 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2425 /* Set up the reload helper functions. */
2426 if (TARGET_VSX || TARGET_ALTIVEC)
2430 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2431 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2432 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2433 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2434 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2435 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2436 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2437 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2438 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2439 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2440 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2441 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2445 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2446 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2447 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2448 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2449 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2450 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2451 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2452 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2453 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2454 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2455 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2456 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2460 /* Precalculate HARD_REGNO_NREGS. */
2461 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2462 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2463 rs6000_hard_regno_nregs[m][r]
2464 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2466 /* Precalculate HARD_REGNO_MODE_OK. */
2467 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2468 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2469 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2470 rs6000_hard_regno_mode_ok_p[m][r] = true;
2472 /* Precalculate CLASS_MAX_NREGS sizes. */
2473 for (c = 0; c < LIM_REG_CLASSES; ++c)
2477 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2478 reg_size = UNITS_PER_VSX_WORD;
2480 else if (c == ALTIVEC_REGS)
2481 reg_size = UNITS_PER_ALTIVEC_WORD;
2483 else if (c == FLOAT_REGS)
2484 reg_size = UNITS_PER_FP_WORD;
2487 reg_size = UNITS_PER_WORD;
2489 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2490 rs6000_class_max_nregs[m][c]
2491 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2494 if (TARGET_E500_DOUBLE)
2495 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2497 /* Calculate which modes to automatically generate code to use a the
2498 reciprocal divide and square root instructions. In the future, possibly
2499 automatically generate the instructions even if the user did not specify
2500 -mrecip. The older machines double precision reciprocal sqrt estimate is
2501 not accurate enough. */
2502 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2504 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2506 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2507 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2508 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2509 if (VECTOR_UNIT_VSX_P (V2DFmode))
2510 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2512 if (TARGET_FRSQRTES)
2513 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2515 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2516 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2517 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2518 if (VECTOR_UNIT_VSX_P (V2DFmode))
2519 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2521 if (rs6000_recip_control)
2523 if (!flag_finite_math_only)
2524 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2525 if (flag_trapping_math)
2526 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2527 if (!flag_reciprocal_math)
2528 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2529 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2531 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2532 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2533 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2535 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2536 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2537 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2539 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2540 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2541 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2543 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2544 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2545 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2547 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2548 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2549 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2551 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2552 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2553 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2555 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2556 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2557 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2559 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2560 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2561 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2565 if (global_init_p || TARGET_DEBUG_TARGET)
2567 if (TARGET_DEBUG_REG)
2568 rs6000_debug_reg_global ();
2570 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2572 "SImode variable mult cost = %d\n"
2573 "SImode constant mult cost = %d\n"
2574 "SImode short constant mult cost = %d\n"
2575 "DImode multipliciation cost = %d\n"
2576 "SImode division cost = %d\n"
2577 "DImode division cost = %d\n"
2578 "Simple fp operation cost = %d\n"
2579 "DFmode multiplication cost = %d\n"
2580 "SFmode division cost = %d\n"
2581 "DFmode division cost = %d\n"
2582 "cache line size = %d\n"
2583 "l1 cache size = %d\n"
2584 "l2 cache size = %d\n"
2585 "simultaneous prefetches = %d\n"
2588 rs6000_cost->mulsi_const,
2589 rs6000_cost->mulsi_const9,
2597 rs6000_cost->cache_line_size,
2598 rs6000_cost->l1_cache_size,
2599 rs6000_cost->l2_cache_size,
2600 rs6000_cost->simultaneous_prefetches);
2605 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2608 darwin_rs6000_override_options (void)
2610 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2612 rs6000_altivec_abi = 1;
2613 TARGET_ALTIVEC_VRSAVE = 1;
2615 if (DEFAULT_ABI == ABI_DARWIN
2617 darwin_one_byte_bool = 1;
2619 if (TARGET_64BIT && ! TARGET_POWERPC64)
2621 target_flags |= MASK_POWERPC64;
2622 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2626 rs6000_default_long_calls = 1;
2627 target_flags |= MASK_SOFT_FLOAT;
2630 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2632 if (!flag_mkernel && !flag_apple_kext
2634 && ! (target_flags_explicit & MASK_ALTIVEC))
2635 target_flags |= MASK_ALTIVEC;
2637 /* Unless the user (not the configurer) has explicitly overridden
2638 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2639 G4 unless targetting the kernel. */
2642 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2643 && ! (target_flags_explicit & MASK_ALTIVEC)
2644 && ! rs6000_select[1].string)
2646 target_flags |= MASK_ALTIVEC;
2651 /* If not otherwise specified by a target, make 'long double' equivalent to
2654 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2655 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2658 /* Override command line options. Mostly we process the processor type and
2659 sometimes adjust other TARGET_ options. */
2662 rs6000_option_override_internal (bool global_init_p)
2665 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2669 struct cl_target_option *main_target_opt
2670 = ((global_init_p || target_option_default_node == NULL)
2671 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2673 /* Numerous experiment shows that IRA based loop pressure
2674 calculation works better for RTL loop invariant motion on targets
2675 with enough (>= 32) registers. It is an expensive optimization.
2676 So it is on only for peak performance. */
2677 if (optimize >= 3 && global_init_p)
2678 flag_ira_loop_pressure = 1;
2680 /* Set the pointer size. */
2683 rs6000_pmode = (int)DImode;
2684 rs6000_pointer_size = 64;
2688 rs6000_pmode = (int)SImode;
2689 rs6000_pointer_size = 32;
2692 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2693 #ifdef OS_MISSING_POWERPC64
2694 if (OS_MISSING_POWERPC64)
2695 set_masks &= ~MASK_POWERPC64;
2697 #ifdef OS_MISSING_ALTIVEC
2698 if (OS_MISSING_ALTIVEC)
2699 set_masks &= ~MASK_ALTIVEC;
2702 /* Don't override by the processor default if given explicitly. */
2703 set_masks &= ~target_flags_explicit;
2705 /* Identify the processor type. */
2708 if (TARGET_POWERPC64)
2709 default_cpu = "powerpc64";
2710 else if (TARGET_POWERPC)
2711 default_cpu = "powerpc";
2714 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2715 the cpu in a target attribute or pragma, but did not specify a tuning
2716 option, use the cpu for the tuning option rather than the option specified
2717 with -mtune on the command line. */
2718 if (rs6000_cpu_index > 0)
2719 cpu_index = rs6000_cpu_index;
2720 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2721 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2723 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2725 if (rs6000_tune_index > 0)
2726 tune_index = rs6000_tune_index;
2728 rs6000_tune_index = tune_index = cpu_index;
2732 target_flags &= ~set_masks;
2733 target_flags |= (processor_target_table[cpu_index].target_enable
2737 rs6000_cpu = ((tune_index >= 0)
2738 ? processor_target_table[tune_index].processor
2740 ? PROCESSOR_DEFAULT64
2741 : PROCESSOR_DEFAULT));
2743 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2744 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2747 error ("AltiVec not supported in this target");
2749 error ("SPE not supported in this target");
2752 /* Disable Cell microcode if we are optimizing for the Cell
2753 and not optimizing for size. */
2754 if (rs6000_gen_cell_microcode == -1)
2755 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2758 /* If we are optimizing big endian systems for space and it's OK to
2759 use instructions that would be microcoded on the Cell, use the
2760 load/store multiple and string instructions. */
2761 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2762 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2764 /* Don't allow -mmultiple or -mstring on little endian systems
2765 unless the cpu is a 750, because the hardware doesn't support the
2766 instructions used in little endian mode, and causes an alignment
2767 trap. The 750 does not cause an alignment trap (except when the
2768 target is unaligned). */
2770 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2772 if (TARGET_MULTIPLE)
2774 target_flags &= ~MASK_MULTIPLE;
2775 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2776 warning (0, "-mmultiple is not supported on little endian systems");
2781 target_flags &= ~MASK_STRING;
2782 if ((target_flags_explicit & MASK_STRING) != 0)
2783 warning (0, "-mstring is not supported on little endian systems");
2787 /* Add some warnings for VSX. */
2790 const char *msg = NULL;
2791 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2792 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2794 if (target_flags_explicit & MASK_VSX)
2795 msg = N_("-mvsx requires hardware floating point");
2797 target_flags &= ~ MASK_VSX;
2799 else if (TARGET_PAIRED_FLOAT)
2800 msg = N_("-mvsx and -mpaired are incompatible");
2801 /* The hardware will allow VSX and little endian, but until we make sure
2802 things like vector select, etc. work don't allow VSX on little endian
2803 systems at this point. */
2804 else if (!BYTES_BIG_ENDIAN)
2805 msg = N_("-mvsx used with little endian code");
2806 else if (TARGET_AVOID_XFORM > 0)
2807 msg = N_("-mvsx needs indexed addressing");
2808 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2810 if (target_flags_explicit & MASK_VSX)
2811 msg = N_("-mvsx and -mno-altivec are incompatible");
2813 msg = N_("-mno-altivec disables vsx");
2819 target_flags &= ~ MASK_VSX;
2820 target_flags_explicit |= MASK_VSX;
2824 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2825 unless the user explicitly used the -mno-<option> to disable the code. */
2827 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2828 else if (TARGET_POPCNTD)
2829 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2830 else if (TARGET_DFP)
2831 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2832 else if (TARGET_CMPB)
2833 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2834 else if (TARGET_FPRND)
2835 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2836 else if (TARGET_POPCNTB)
2837 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2838 else if (TARGET_ALTIVEC)
2839 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2841 /* E500mc does "better" if we inline more aggressively. Respect the
2842 user's opinion, though. */
2843 if (rs6000_block_move_inline_limit == 0
2844 && (rs6000_cpu == PROCESSOR_PPCE500MC
2845 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2846 rs6000_block_move_inline_limit = 128;
2848 /* store_one_arg depends on expand_block_move to handle at least the
2849 size of reg_parm_stack_space. */
2850 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2851 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2855 /* If the appropriate debug option is enabled, replace the target hooks
2856 with debug versions that call the real version and then prints
2857 debugging information. */
2858 if (TARGET_DEBUG_COST)
2860 targetm.rtx_costs = rs6000_debug_rtx_costs;
2861 targetm.address_cost = rs6000_debug_address_cost;
2862 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2865 if (TARGET_DEBUG_ADDR)
2867 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2868 targetm.legitimize_address = rs6000_debug_legitimize_address;
2869 rs6000_secondary_reload_class_ptr
2870 = rs6000_debug_secondary_reload_class;
2871 rs6000_secondary_memory_needed_ptr
2872 = rs6000_debug_secondary_memory_needed;
2873 rs6000_cannot_change_mode_class_ptr
2874 = rs6000_debug_cannot_change_mode_class;
2875 rs6000_preferred_reload_class_ptr
2876 = rs6000_debug_preferred_reload_class;
2877 rs6000_legitimize_reload_address_ptr
2878 = rs6000_debug_legitimize_reload_address;
2879 rs6000_mode_dependent_address_ptr
2880 = rs6000_debug_mode_dependent_address;
2883 if (rs6000_veclibabi_name)
2885 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2886 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2889 error ("unknown vectorization library ABI type (%s) for "
2890 "-mveclibabi= switch", rs6000_veclibabi_name);
2896 if (!rs6000_explicit_options.long_double)
2898 if (main_target_opt != NULL
2899 && (main_target_opt->x_rs6000_long_double_type_size
2900 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2901 error ("target attribute or pragma changes long double size");
2903 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2906 #ifndef POWERPC_LINUX
2907 if (!rs6000_explicit_options.ieee)
2908 rs6000_ieeequad = 1;
2911 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2912 target attribute or pragma which automatically enables both options,
2913 unless the altivec ABI was set. This is set by default for 64-bit, but
2915 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2916 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2918 /* Enable Altivec ABI for AIX -maltivec. */
2919 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2921 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2922 error ("target attribute or pragma changes AltiVec ABI");
2924 rs6000_altivec_abi = 1;
2927 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2928 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2929 be explicitly overridden in either case. */
2932 if (!rs6000_explicit_options.altivec_abi
2933 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2935 if (main_target_opt != NULL &&
2936 !main_target_opt->x_rs6000_altivec_abi)
2937 error ("target attribute or pragma changes AltiVec ABI");
2939 rs6000_altivec_abi = 1;
2942 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2943 if (!rs6000_explicit_options.vrsave)
2944 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2947 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2948 So far, the only darwin64 targets are also MACH-O. */
2950 && DEFAULT_ABI == ABI_DARWIN
2953 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2954 error ("target attribute or pragma changes darwin64 ABI");
2957 rs6000_darwin64_abi = 1;
2958 /* Default to natural alignment, for better performance. */
2959 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2963 /* Place FP constants in the constant pool instead of TOC
2964 if section anchors enabled. */
2965 if (flag_section_anchors)
2966 TARGET_NO_FP_IN_TOC = 1;
2968 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2969 SUBTARGET_OVERRIDE_OPTIONS;
2971 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2972 SUBSUBTARGET_OVERRIDE_OPTIONS;
2974 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2975 SUB3TARGET_OVERRIDE_OPTIONS;
2978 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2979 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2981 /* The e500 and e500mc do not have string instructions, and we set
2982 MASK_STRING above when optimizing for size. */
2983 if ((target_flags & MASK_STRING) != 0)
2984 target_flags = target_flags & ~MASK_STRING;
2986 else if (rs6000_select[1].string != NULL)
2988 /* For the powerpc-eabispe configuration, we set all these by
2989 default, so let's unset them if we manually set another
2990 CPU that is not the E500. */
2991 if (main_target_opt != NULL
2992 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2993 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2994 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2995 error ("target attribute or pragma changes SPE ABI");
2998 if (!rs6000_explicit_options.spe_abi)
3000 if (!rs6000_explicit_options.spe)
3002 if (!rs6000_explicit_options.float_gprs)
3003 rs6000_float_gprs = 0;
3005 if (!(target_flags_explicit & MASK_ISEL))
3006 target_flags &= ~MASK_ISEL;
3009 /* Detect invalid option combinations with E500. */
3012 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3013 && rs6000_cpu != PROCESSOR_POWER5
3014 && rs6000_cpu != PROCESSOR_POWER6
3015 && rs6000_cpu != PROCESSOR_POWER7
3016 && rs6000_cpu != PROCESSOR_PPCA2
3017 && rs6000_cpu != PROCESSOR_CELL);
3018 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3019 || rs6000_cpu == PROCESSOR_POWER5
3020 || rs6000_cpu == PROCESSOR_POWER7);
3021 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3022 || rs6000_cpu == PROCESSOR_POWER5
3023 || rs6000_cpu == PROCESSOR_POWER6
3024 || rs6000_cpu == PROCESSOR_POWER7
3025 || rs6000_cpu == PROCESSOR_PPCE500MC
3026 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3028 /* Allow debug switches to override the above settings. These are set to -1
3029 in rs6000.opt to indicate the user hasn't directly set the switch. */
3030 if (TARGET_ALWAYS_HINT >= 0)
3031 rs6000_always_hint = TARGET_ALWAYS_HINT;
3033 if (TARGET_SCHED_GROUPS >= 0)
3034 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3036 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3037 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3039 rs6000_sched_restricted_insns_priority
3040 = (rs6000_sched_groups ? 1 : 0);
3042 /* Handle -msched-costly-dep option. */
3043 rs6000_sched_costly_dep
3044 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3046 if (rs6000_sched_costly_dep_str)
3048 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3049 rs6000_sched_costly_dep = no_dep_costly;
3050 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3051 rs6000_sched_costly_dep = all_deps_costly;
3052 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3053 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3054 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3055 rs6000_sched_costly_dep = store_to_load_dep_costly;
3057 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3058 atoi (rs6000_sched_costly_dep_str));
3061 /* Handle -minsert-sched-nops option. */
3062 rs6000_sched_insert_nops
3063 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3065 if (rs6000_sched_insert_nops_str)
3067 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3068 rs6000_sched_insert_nops = sched_finish_none;
3069 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3070 rs6000_sched_insert_nops = sched_finish_pad_groups;
3071 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3072 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3074 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3075 atoi (rs6000_sched_insert_nops_str));
3080 #ifdef TARGET_REGNAMES
3081 /* If the user desires alternate register names, copy in the
3082 alternate names now. */
3083 if (TARGET_REGNAMES)
3084 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3087 /* Set aix_struct_return last, after the ABI is determined.
3088 If -maix-struct-return or -msvr4-struct-return was explicitly
3089 used, don't override with the ABI default. */
3090 if (!rs6000_explicit_options.aix_struct_ret)
3091 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3094 /* IBM XL compiler defaults to unsigned bitfields. */
3095 if (TARGET_XL_COMPAT)
3096 flag_signed_bitfields = 0;
3099 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3100 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3103 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3105 /* We can only guarantee the availability of DI pseudo-ops when
3106 assembling for 64-bit targets. */
3109 targetm.asm_out.aligned_op.di = NULL;
3110 targetm.asm_out.unaligned_op.di = NULL;
3114 /* Set branch target alignment, if not optimizing for size. */
3117 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3118 aligned 8byte to avoid misprediction by the branch predictor. */
3119 if (rs6000_cpu == PROCESSOR_TITAN
3120 || rs6000_cpu == PROCESSOR_CELL)
3122 if (align_functions <= 0)
3123 align_functions = 8;
3124 if (align_jumps <= 0)
3126 if (align_loops <= 0)
3129 if (rs6000_align_branch_targets)
3131 if (align_functions <= 0)
3132 align_functions = 16;
3133 if (align_jumps <= 0)
3135 if (align_loops <= 0)
3137 can_override_loop_align = 1;
3141 if (align_jumps_max_skip <= 0)
3142 align_jumps_max_skip = 15;
3143 if (align_loops_max_skip <= 0)
3144 align_loops_max_skip = 15;
3147 /* Arrange to save and restore machine status around nested functions. */
3148 init_machine_status = rs6000_init_machine_status;
3150 /* We should always be splitting complex arguments, but we can't break
3151 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3152 if (DEFAULT_ABI != ABI_AIX)
3153 targetm.calls.split_complex_arg = NULL;
3156 /* Initialize rs6000_cost with the appropriate target costs. */
3158 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3162 case PROCESSOR_RIOS1:
3163 rs6000_cost = &rios1_cost;
3166 case PROCESSOR_RIOS2:
3167 rs6000_cost = &rios2_cost;
3170 case PROCESSOR_RS64A:
3171 rs6000_cost = &rs64a_cost;
3174 case PROCESSOR_MPCCORE:
3175 rs6000_cost = &mpccore_cost;
3178 case PROCESSOR_PPC403:
3179 rs6000_cost = &ppc403_cost;
3182 case PROCESSOR_PPC405:
3183 rs6000_cost = &ppc405_cost;
3186 case PROCESSOR_PPC440:
3187 rs6000_cost = &ppc440_cost;
3190 case PROCESSOR_PPC476:
3191 rs6000_cost = &ppc476_cost;
3194 case PROCESSOR_PPC601:
3195 rs6000_cost = &ppc601_cost;
3198 case PROCESSOR_PPC603:
3199 rs6000_cost = &ppc603_cost;
3202 case PROCESSOR_PPC604:
3203 rs6000_cost = &ppc604_cost;
3206 case PROCESSOR_PPC604e:
3207 rs6000_cost = &ppc604e_cost;
3210 case PROCESSOR_PPC620:
3211 rs6000_cost = &ppc620_cost;
3214 case PROCESSOR_PPC630:
3215 rs6000_cost = &ppc630_cost;
3218 case PROCESSOR_CELL:
3219 rs6000_cost = &ppccell_cost;
3222 case PROCESSOR_PPC750:
3223 case PROCESSOR_PPC7400:
3224 rs6000_cost = &ppc750_cost;
3227 case PROCESSOR_PPC7450:
3228 rs6000_cost = &ppc7450_cost;
3231 case PROCESSOR_PPC8540:
3232 rs6000_cost = &ppc8540_cost;
3235 case PROCESSOR_PPCE300C2:
3236 case PROCESSOR_PPCE300C3:
3237 rs6000_cost = &ppce300c2c3_cost;
3240 case PROCESSOR_PPCE500MC:
3241 rs6000_cost = &ppce500mc_cost;
3244 case PROCESSOR_PPCE500MC64:
3245 rs6000_cost = &ppce500mc64_cost;
3248 case PROCESSOR_TITAN:
3249 rs6000_cost = &titan_cost;
3252 case PROCESSOR_POWER4:
3253 case PROCESSOR_POWER5:
3254 rs6000_cost = &power4_cost;
3257 case PROCESSOR_POWER6:
3258 rs6000_cost = &power6_cost;
3261 case PROCESSOR_POWER7:
3262 rs6000_cost = &power7_cost;
3265 case PROCESSOR_PPCA2:
3266 rs6000_cost = &ppca2_cost;
3275 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3276 rs6000_cost->simultaneous_prefetches,
3277 global_options.x_param_values,
3278 global_options_set.x_param_values);
3279 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3280 global_options.x_param_values,
3281 global_options_set.x_param_values);
3282 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3283 rs6000_cost->cache_line_size,
3284 global_options.x_param_values,
3285 global_options_set.x_param_values);
3286 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3287 global_options.x_param_values,
3288 global_options_set.x_param_values);
3290 /* If using typedef char *va_list, signal that
3291 __builtin_va_start (&ap, 0) can be optimized to
3292 ap = __builtin_next_arg (0). */
3293 if (DEFAULT_ABI != ABI_V4)
3294 targetm.expand_builtin_va_start = NULL;
3297 /* Set up single/double float flags.
3298 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3299 then set both flags. */
3300 if (TARGET_HARD_FLOAT && TARGET_FPRS
3301 && rs6000_single_float == 0 && rs6000_double_float == 0)
3302 rs6000_single_float = rs6000_double_float = 1;
3304 /* Reset single and double FP flags if target is E500. */
3307 rs6000_single_float = rs6000_double_float = 0;
3308 if (TARGET_E500_SINGLE)
3309 rs6000_single_float = 1;
3310 if (TARGET_E500_DOUBLE)
3311 rs6000_single_float = rs6000_double_float = 1;
3314 if (main_target_opt)
3316 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3317 error ("target attribute or pragma changes single precision floating "
3319 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3320 error ("target attribute or pragma changes double precision floating "
3324 /* If not explicitly specified via option, decide whether to generate indexed
3325 load/store instructions. */
3326 if (TARGET_AVOID_XFORM == -1)
3327 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3328 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3329 need indexed accesses and the type used is the scalar type of the element
3330 being loaded or stored. */
3331 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3332 && !TARGET_ALTIVEC);
3334 /* Set the -mrecip options. */
3335 if (rs6000_recip_name)
3337 char *p = ASTRDUP (rs6000_recip_name);
3339 unsigned int mask, i;
3342 while ((q = strtok (p, ",")) != NULL)
3353 if (!strcmp (q, "default"))
3354 mask = ((TARGET_RECIP_PRECISION)
3355 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3358 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3359 if (!strcmp (q, recip_options[i].string))
3361 mask = recip_options[i].mask;
3365 if (i == ARRAY_SIZE (recip_options))
3367 error ("unknown option for -mrecip=%s", q);
3375 rs6000_recip_control &= ~mask;
3377 rs6000_recip_control |= mask;
3381 rs6000_init_hard_regno_mode_ok (global_init_p);
3383 /* Save the initial options in case the user does function specific options */
3385 target_option_default_node = target_option_current_node
3386 = build_target_option_node ();
3391 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3392 define the target cpu type. */
3395 rs6000_option_override (void)
3397 (void) rs6000_option_override_internal (true);
3401 /* Implement targetm.vectorize.builtin_mask_for_load. */
3403 rs6000_builtin_mask_for_load (void)
3405 if (TARGET_ALTIVEC || TARGET_VSX)
3406 return altivec_builtin_mask_for_load;
3411 /* Implement LOOP_ALIGN. */
3413 rs6000_loop_align (rtx label)
3418 /* Don't override loop alignment if -falign-loops was specified. */
3419 if (!can_override_loop_align)
3420 return align_loops_log;
3422 bb = BLOCK_FOR_INSN (label);
3423 ninsns = num_loop_insns(bb->loop_father);
3425 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3426 if (ninsns > 4 && ninsns <= 8
3427 && (rs6000_cpu == PROCESSOR_POWER4
3428 || rs6000_cpu == PROCESSOR_POWER5
3429 || rs6000_cpu == PROCESSOR_POWER6
3430 || rs6000_cpu == PROCESSOR_POWER7))
3433 return align_loops_log;
3436 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3438 rs6000_loop_align_max_skip (rtx label)
3440 return (1 << rs6000_loop_align (label)) - 1;
3443 /* Implement targetm.vectorize.builtin_conversion.
3444 Returns a decl of a function that implements conversion of an integer vector
3445 into a floating-point vector, or vice-versa. DEST_TYPE is the
3446 destination type and SRC_TYPE the source type of the conversion.
3447 Return NULL_TREE if it is not available. */
3449 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3451 enum tree_code code = (enum tree_code) tcode;
3455 case FIX_TRUNC_EXPR:
3456 switch (TYPE_MODE (dest_type))
3459 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3462 return TYPE_UNSIGNED (dest_type)
3463 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3464 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3467 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3470 return TYPE_UNSIGNED (dest_type)
3471 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3472 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3479 switch (TYPE_MODE (src_type))
3482 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3485 return TYPE_UNSIGNED (src_type)
3486 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3487 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3490 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3493 return TYPE_UNSIGNED (src_type)
3494 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3495 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3506 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3508 rs6000_builtin_mul_widen_even (tree type)
3510 if (!TARGET_ALTIVEC)
3513 switch (TYPE_MODE (type))
3516 return TYPE_UNSIGNED (type)
3517 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3518 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3521 return TYPE_UNSIGNED (type)
3522 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3523 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3529 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3531 rs6000_builtin_mul_widen_odd (tree type)
3533 if (!TARGET_ALTIVEC)
3536 switch (TYPE_MODE (type))
3539 return TYPE_UNSIGNED (type)
3540 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3541 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3544 return TYPE_UNSIGNED (type)
3545 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3546 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3553 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3554 after applying N number of iterations. This routine does not determine
3555 how may iterations are required to reach desired alignment. */
3558 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3565 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3568 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3578 /* Assuming that all other types are naturally aligned. CHECKME! */
3583 /* Return true if the vector misalignment factor is supported by the
3586 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3593 /* Return if movmisalign pattern is not supported for this mode. */
3594 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3597 if (misalignment == -1)
3599 /* Misalignment factor is unknown at compile time but we know
3600 it's word aligned. */
3601 if (rs6000_vector_alignment_reachable (type, is_packed))
3603 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3605 if (element_size == 64 || element_size == 32)
3612 /* VSX supports word-aligned vector. */
3613 if (misalignment % 4 == 0)
3619 /* Implement targetm.vectorize.builtin_vec_perm. */
3621 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3623 tree inner_type = TREE_TYPE (type);
3624 bool uns_p = TYPE_UNSIGNED (inner_type);
3627 *mask_element_type = unsigned_char_type_node;
3629 switch (TYPE_MODE (type))
3633 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3634 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3639 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3640 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3645 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3646 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3650 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3654 if (!TARGET_ALLOW_DF_PERMUTE)
3657 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3661 if (!TARGET_ALLOW_DF_PERMUTE)
3665 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3666 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3678 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3680 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3681 tree vectype, int misalign)
3685 switch (type_of_cost)
3695 case cond_branch_not_taken:
3699 case cond_branch_taken:
3702 case unaligned_load:
3703 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3705 elements = TYPE_VECTOR_SUBPARTS (vectype);
3707 /* Double word aligned. */
3715 /* Double word aligned. */
3719 /* Unknown misalignment. */
3732 /* Misaligned loads are not supported. */
3737 case unaligned_store:
3738 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3740 elements = TYPE_VECTOR_SUBPARTS (vectype);
3742 /* Double word aligned. */
3750 /* Double word aligned. */
3754 /* Unknown misalignment. */
3767 /* Misaligned stores are not supported. */
3777 /* Implement targetm.vectorize.preferred_simd_mode. */
3779 static enum machine_mode
3780 rs6000_preferred_simd_mode (enum machine_mode mode)
3789 if (TARGET_ALTIVEC || TARGET_VSX)
3813 if (TARGET_PAIRED_FLOAT
3819 /* Handle generic options of the form -mfoo=yes/no.
3820 NAME is the option name.
3821 VALUE is the option value.
3822 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3823 whether the option value is 'yes' or 'no' respectively. */
3825 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3829 else if (!strcmp (value, "yes"))
3831 else if (!strcmp (value, "no"))
3834 error ("unknown -m%s= option specified: '%s'", name, value);
3837 /* Implement TARGET_OPTION_INIT_STRUCT. */
3840 rs6000_option_init_struct (struct gcc_options *opts)
3842 if (DEFAULT_ABI == ABI_DARWIN)
3843 /* The Darwin libraries never set errno, so we might as well
3844 avoid calling them when that's the only reason we would. */
3845 opts->x_flag_errno_math = 0;
3847 /* Enable section anchors by default. */
3849 opts->x_flag_section_anchors = 1;
3852 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3855 rs6000_option_default_params (void)
3857 /* Double growth factor to counter reduced min jump length. */
3858 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3861 static enum fpu_type_t
3862 rs6000_parse_fpu_option (const char *option)
3864 if (!strcmp("none", option)) return FPU_NONE;
3865 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3866 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3867 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3868 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3869 error("unknown value %s for -mfpu", option);
3874 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3875 library with vectorized intrinsics. */
3878 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3881 const char *suffix = NULL;
3882 tree fntype, new_fndecl, bdecl = NULL_TREE;
3885 enum machine_mode el_mode, in_mode;
3888 /* Libmass is suitable for unsafe math only as it does not correctly support
3889 parts of IEEE with the required precision such as denormals. Only support
3890 it if we have VSX to use the simd d2 or f4 functions.
3891 XXX: Add variable length support. */
3892 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3895 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3896 n = TYPE_VECTOR_SUBPARTS (type_out);
3897 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3898 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3899 if (el_mode != in_mode
3903 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3905 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3908 case BUILT_IN_ATAN2:
3909 case BUILT_IN_HYPOT:
3915 case BUILT_IN_ACOSH:
3917 case BUILT_IN_ASINH:
3919 case BUILT_IN_ATANH:
3927 case BUILT_IN_EXPM1:
3928 case BUILT_IN_LGAMMA:
3929 case BUILT_IN_LOG10:
3930 case BUILT_IN_LOG1P:
3938 bdecl = implicit_built_in_decls[fn];
3939 suffix = "d2"; /* pow -> powd2 */
3940 if (el_mode != DFmode
3945 case BUILT_IN_ATAN2F:
3946 case BUILT_IN_HYPOTF:
3951 case BUILT_IN_ACOSF:
3952 case BUILT_IN_ACOSHF:
3953 case BUILT_IN_ASINF:
3954 case BUILT_IN_ASINHF:
3955 case BUILT_IN_ATANF:
3956 case BUILT_IN_ATANHF:
3957 case BUILT_IN_CBRTF:
3959 case BUILT_IN_COSHF:
3961 case BUILT_IN_ERFCF:
3962 case BUILT_IN_EXP2F:
3964 case BUILT_IN_EXPM1F:
3965 case BUILT_IN_LGAMMAF:
3966 case BUILT_IN_LOG10F:
3967 case BUILT_IN_LOG1PF:
3968 case BUILT_IN_LOG2F:
3971 case BUILT_IN_SINHF:
3972 case BUILT_IN_SQRTF:
3974 case BUILT_IN_TANHF:
3975 bdecl = implicit_built_in_decls[fn];
3976 suffix = "4"; /* powf -> powf4 */
3977 if (el_mode != SFmode
3989 gcc_assert (suffix != NULL);
3990 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3991 strcpy (name, bname + sizeof ("__builtin_") - 1);
3992 strcat (name, suffix);
3995 fntype = build_function_type_list (type_out, type_in, NULL);
3996 else if (n_args == 2)
3997 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
4001 /* Build a function declaration for the vectorized function. */
4002 new_fndecl = build_decl (BUILTINS_LOCATION,
4003 FUNCTION_DECL, get_identifier (name), fntype);
4004 TREE_PUBLIC (new_fndecl) = 1;
4005 DECL_EXTERNAL (new_fndecl) = 1;
4006 DECL_IS_NOVOPS (new_fndecl) = 1;
4007 TREE_READONLY (new_fndecl) = 1;
4012 /* Returns a function decl for a vectorized version of the builtin function
4013 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4014 if it is not available. */
4017 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4020 enum machine_mode in_mode, out_mode;
4023 if (TREE_CODE (type_out) != VECTOR_TYPE
4024 || TREE_CODE (type_in) != VECTOR_TYPE
4025 || !TARGET_VECTORIZE_BUILTINS)
4028 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4029 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4030 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4031 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4033 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4035 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4038 case BUILT_IN_COPYSIGN:
4039 if (VECTOR_UNIT_VSX_P (V2DFmode)
4040 && out_mode == DFmode && out_n == 2
4041 && in_mode == DFmode && in_n == 2)
4042 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4044 case BUILT_IN_COPYSIGNF:
4045 if (out_mode != SFmode || out_n != 4
4046 || in_mode != SFmode || in_n != 4)
4048 if (VECTOR_UNIT_VSX_P (V4SFmode))
4049 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4050 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4051 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4054 if (VECTOR_UNIT_VSX_P (V2DFmode)
4055 && out_mode == DFmode && out_n == 2
4056 && in_mode == DFmode && in_n == 2)
4057 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4059 case BUILT_IN_SQRTF:
4060 if (VECTOR_UNIT_VSX_P (V4SFmode)
4061 && out_mode == SFmode && out_n == 4
4062 && in_mode == SFmode && in_n == 4)
4063 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4066 if (VECTOR_UNIT_VSX_P (V2DFmode)
4067 && out_mode == DFmode && out_n == 2
4068 && in_mode == DFmode && in_n == 2)
4069 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4071 case BUILT_IN_CEILF:
4072 if (out_mode != SFmode || out_n != 4
4073 || in_mode != SFmode || in_n != 4)
4075 if (VECTOR_UNIT_VSX_P (V4SFmode))
4076 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4077 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4078 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4080 case BUILT_IN_FLOOR:
4081 if (VECTOR_UNIT_VSX_P (V2DFmode)
4082 && out_mode == DFmode && out_n == 2
4083 && in_mode == DFmode && in_n == 2)
4084 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4086 case BUILT_IN_FLOORF:
4087 if (out_mode != SFmode || out_n != 4
4088 || in_mode != SFmode || in_n != 4)
4090 if (VECTOR_UNIT_VSX_P (V4SFmode))
4091 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4092 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4093 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4096 if (VECTOR_UNIT_VSX_P (V2DFmode)
4097 && out_mode == DFmode && out_n == 2
4098 && in_mode == DFmode && in_n == 2)
4099 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4102 if (VECTOR_UNIT_VSX_P (V4SFmode)
4103 && out_mode == SFmode && out_n == 4
4104 && in_mode == SFmode && in_n == 4)
4105 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4106 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4107 && out_mode == SFmode && out_n == 4
4108 && in_mode == SFmode && in_n == 4)
4109 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4111 case BUILT_IN_TRUNC:
4112 if (VECTOR_UNIT_VSX_P (V2DFmode)
4113 && out_mode == DFmode && out_n == 2
4114 && in_mode == DFmode && in_n == 2)
4115 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4117 case BUILT_IN_TRUNCF:
4118 if (out_mode != SFmode || out_n != 4
4119 || in_mode != SFmode || in_n != 4)
4121 if (VECTOR_UNIT_VSX_P (V4SFmode))
4122 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4123 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4124 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4126 case BUILT_IN_NEARBYINT:
4127 if (VECTOR_UNIT_VSX_P (V2DFmode)
4128 && flag_unsafe_math_optimizations
4129 && out_mode == DFmode && out_n == 2
4130 && in_mode == DFmode && in_n == 2)
4131 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4133 case BUILT_IN_NEARBYINTF:
4134 if (VECTOR_UNIT_VSX_P (V4SFmode)
4135 && flag_unsafe_math_optimizations
4136 && out_mode == SFmode && out_n == 4
4137 && in_mode == SFmode && in_n == 4)
4138 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4141 if (VECTOR_UNIT_VSX_P (V2DFmode)
4142 && !flag_trapping_math
4143 && out_mode == DFmode && out_n == 2
4144 && in_mode == DFmode && in_n == 2)
4145 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4147 case BUILT_IN_RINTF:
4148 if (VECTOR_UNIT_VSX_P (V4SFmode)
4149 && !flag_trapping_math
4150 && out_mode == SFmode && out_n == 4
4151 && in_mode == SFmode && in_n == 4)
4152 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4159 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4161 enum rs6000_builtins fn
4162 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4165 case RS6000_BUILTIN_RSQRTF:
4166 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4167 && out_mode == SFmode && out_n == 4
4168 && in_mode == SFmode && in_n == 4)
4169 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4171 case RS6000_BUILTIN_RSQRT:
4172 if (VECTOR_UNIT_VSX_P (V2DFmode)
4173 && out_mode == DFmode && out_n == 2
4174 && in_mode == DFmode && in_n == 2)
4175 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4177 case RS6000_BUILTIN_RECIPF:
4178 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4179 && out_mode == SFmode && out_n == 4
4180 && in_mode == SFmode && in_n == 4)
4181 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4183 case RS6000_BUILTIN_RECIP:
4184 if (VECTOR_UNIT_VSX_P (V2DFmode)
4185 && out_mode == DFmode && out_n == 2
4186 && in_mode == DFmode && in_n == 2)
4187 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4194 /* Generate calls to libmass if appropriate. */
4195 if (rs6000_veclib_handler)
4196 return rs6000_veclib_handler (fndecl, type_out, type_in);
4202 /* Implement TARGET_HANDLE_OPTION. */
4205 rs6000_handle_option (size_t code, const char *arg, int value)
4207 enum fpu_type_t fpu_type = FPU_NONE;
4214 target_flags &= ~(MASK_POWER | MASK_POWER2
4215 | MASK_MULTIPLE | MASK_STRING);
4216 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4217 | MASK_MULTIPLE | MASK_STRING);
4219 case OPT_mno_powerpc:
4220 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4221 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4222 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4223 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4226 target_flags &= ~MASK_MINIMAL_TOC;
4227 TARGET_NO_FP_IN_TOC = 0;
4228 TARGET_NO_SUM_IN_TOC = 0;
4229 target_flags_explicit |= MASK_MINIMAL_TOC;
4230 #ifdef TARGET_USES_SYSV4_OPT
4231 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4232 just the same as -mminimal-toc. */
4233 target_flags |= MASK_MINIMAL_TOC;
4234 target_flags_explicit |= MASK_MINIMAL_TOC;
4238 #ifdef TARGET_USES_SYSV4_OPT
4240 /* Make -mtoc behave like -mminimal-toc. */
4241 target_flags |= MASK_MINIMAL_TOC;
4242 target_flags_explicit |= MASK_MINIMAL_TOC;
4246 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4248 if (strcmp (arg, "small") == 0)
4249 rs6000_current_cmodel = CMODEL_SMALL;
4250 else if (strcmp (arg, "medium") == 0)
4251 rs6000_current_cmodel = CMODEL_MEDIUM;
4252 else if (strcmp (arg, "large") == 0)
4253 rs6000_current_cmodel = CMODEL_LARGE;
4256 error ("invalid option for -mcmodel: '%s'", arg);
4259 rs6000_explicit_options.cmodel = true;
4262 #ifdef TARGET_USES_AIX64_OPT
4267 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4268 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4269 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4272 #ifdef TARGET_USES_AIX64_OPT
4277 target_flags &= ~MASK_POWERPC64;
4278 target_flags_explicit |= MASK_POWERPC64;
4281 case OPT_minsert_sched_nops_:
4282 rs6000_sched_insert_nops_str = arg;
4285 case OPT_mminimal_toc:
4288 TARGET_NO_FP_IN_TOC = 0;
4289 TARGET_NO_SUM_IN_TOC = 0;
4296 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4297 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4304 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4305 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4309 case OPT_mpowerpc_gpopt:
4310 case OPT_mpowerpc_gfxopt:
4313 target_flags |= MASK_POWERPC;
4314 target_flags_explicit |= MASK_POWERPC;
4318 case OPT_maix_struct_return:
4319 case OPT_msvr4_struct_return:
4320 rs6000_explicit_options.aix_struct_ret = true;
4324 rs6000_explicit_options.vrsave = true;
4325 TARGET_ALTIVEC_VRSAVE = value;
4329 rs6000_explicit_options.vrsave = true;
4330 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4334 target_flags_explicit |= MASK_ISEL;
4336 rs6000_parse_yes_no_option ("isel", arg, &isel);
4338 target_flags |= MASK_ISEL;
4340 target_flags &= ~MASK_ISEL;
4344 rs6000_explicit_options.spe = true;
4349 rs6000_explicit_options.spe = true;
4350 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4357 while ((q = strtok (p, ",")) != NULL)
4371 if (! strcmp (q, "all"))
4372 mask = MASK_DEBUG_ALL;
4373 else if (! strcmp (q, "stack"))
4374 mask = MASK_DEBUG_STACK;
4375 else if (! strcmp (q, "arg"))
4376 mask = MASK_DEBUG_ARG;
4377 else if (! strcmp (q, "reg"))
4378 mask = MASK_DEBUG_REG;
4379 else if (! strcmp (q, "addr"))
4380 mask = MASK_DEBUG_ADDR;
4381 else if (! strcmp (q, "cost"))
4382 mask = MASK_DEBUG_COST;
4383 else if (! strcmp (q, "target"))
4384 mask = MASK_DEBUG_TARGET;
4386 error ("unknown -mdebug-%s switch", q);
4389 rs6000_debug &= ~mask;
4391 rs6000_debug |= mask;
4395 #ifdef TARGET_USES_SYSV4_OPT
4397 rs6000_abi_name = arg;
4401 rs6000_sdata_name = arg;
4404 case OPT_mtls_size_:
4405 if (strcmp (arg, "16") == 0)
4406 rs6000_tls_size = 16;
4407 else if (strcmp (arg, "32") == 0)
4408 rs6000_tls_size = 32;
4409 else if (strcmp (arg, "64") == 0)
4410 rs6000_tls_size = 64;
4412 error ("bad value %qs for -mtls-size switch", arg);
4415 case OPT_mrelocatable:
4418 target_flags |= MASK_MINIMAL_TOC;
4419 target_flags_explicit |= MASK_MINIMAL_TOC;
4420 TARGET_NO_FP_IN_TOC = 1;
4424 case OPT_mrelocatable_lib:
4427 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4428 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4429 TARGET_NO_FP_IN_TOC = 1;
4433 target_flags &= ~MASK_RELOCATABLE;
4434 target_flags_explicit |= MASK_RELOCATABLE;
4440 if (!strcmp (arg, "altivec"))
4442 rs6000_explicit_options.altivec_abi = true;
4443 rs6000_altivec_abi = 1;
4445 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4448 else if (! strcmp (arg, "no-altivec"))
4450 rs6000_explicit_options.altivec_abi = true;
4451 rs6000_altivec_abi = 0;
4453 else if (! strcmp (arg, "spe"))
4455 rs6000_explicit_options.spe_abi = true;
4457 rs6000_altivec_abi = 0;
4458 if (!TARGET_SPE_ABI)
4459 error ("not configured for ABI: '%s'", arg);
4461 else if (! strcmp (arg, "no-spe"))
4463 rs6000_explicit_options.spe_abi = true;
4467 /* These are here for testing during development only, do not
4468 document in the manual please. */
4469 else if (! strcmp (arg, "d64"))
4471 rs6000_darwin64_abi = 1;
4472 warning (0, "using darwin64 ABI");
4474 else if (! strcmp (arg, "d32"))
4476 rs6000_darwin64_abi = 0;
4477 warning (0, "using old darwin ABI");
4480 else if (! strcmp (arg, "ibmlongdouble"))
4482 rs6000_explicit_options.ieee = true;
4483 rs6000_ieeequad = 0;
4484 warning (0, "using IBM extended precision long double");
4486 else if (! strcmp (arg, "ieeelongdouble"))
4488 rs6000_explicit_options.ieee = true;
4489 rs6000_ieeequad = 1;
4490 warning (0, "using IEEE extended precision long double");
4495 error ("unknown ABI specified: '%s'", arg);
4501 rs6000_select[1].string = arg;
4502 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4503 if (rs6000_cpu_index < 0)
4504 error ("bad value (%s) for -mcpu", arg);
4508 rs6000_select[2].string = arg;
4509 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4510 if (rs6000_tune_index < 0)
4511 error ("bad value (%s) for -mtune", arg);
4514 case OPT_mtraceback_:
4515 if (! strncmp (arg, "full", 4))
4516 rs6000_traceback = traceback_full;
4517 else if (! strncmp (arg, "part", 4))
4518 rs6000_traceback = traceback_part;
4519 else if (! strncmp (arg, "no", 2))
4520 rs6000_traceback = traceback_none;
4522 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4523 "%<partial%> or %<none%>", arg);
4526 case OPT_mfloat_gprs_:
4527 rs6000_explicit_options.float_gprs = true;
4528 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4529 rs6000_float_gprs = 1;
4530 else if (! strcmp (arg, "double"))
4531 rs6000_float_gprs = 2;
4532 else if (! strcmp (arg, "no"))
4533 rs6000_float_gprs = 0;
4536 error ("invalid option for -mfloat-gprs: '%s'", arg);
4541 case OPT_mlong_double_:
4542 rs6000_explicit_options.long_double = true;
4543 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4544 if (value != 64 && value != 128)
4546 error ("unknown switch -mlong-double-%s", arg);
4547 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4551 rs6000_long_double_type_size = value;
4554 case OPT_msched_costly_dep_:
4555 rs6000_sched_costly_dep_str = arg;
4559 rs6000_explicit_options.alignment = true;
4560 if (! strcmp (arg, "power"))
4562 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4563 some C library functions, so warn about it. The flag may be
4564 useful for performance studies from time to time though, so
4565 don't disable it entirely. */
4566 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4567 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4568 " it is incompatible with the installed C and C++ libraries");
4569 rs6000_alignment_flags = MASK_ALIGN_POWER;
4571 else if (! strcmp (arg, "natural"))
4572 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4575 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4580 case OPT_msingle_float:
4581 if (!TARGET_SINGLE_FPU)
4582 warning (0, "-msingle-float option equivalent to -mhard-float");
4583 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4584 rs6000_double_float = 0;
4585 target_flags &= ~MASK_SOFT_FLOAT;
4586 target_flags_explicit |= MASK_SOFT_FLOAT;
4589 case OPT_mdouble_float:
4590 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4591 rs6000_single_float = 1;
4592 target_flags &= ~MASK_SOFT_FLOAT;
4593 target_flags_explicit |= MASK_SOFT_FLOAT;
4596 case OPT_msimple_fpu:
4597 if (!TARGET_SINGLE_FPU)
4598 warning (0, "-msimple-fpu option ignored");
4601 case OPT_mhard_float:
4602 /* -mhard_float implies -msingle-float and -mdouble-float. */
4603 rs6000_single_float = rs6000_double_float = 1;
4606 case OPT_msoft_float:
4607 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4608 rs6000_single_float = rs6000_double_float = 0;
4612 fpu_type = rs6000_parse_fpu_option(arg);
4613 if (fpu_type != FPU_NONE)
4614 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4616 target_flags &= ~MASK_SOFT_FLOAT;
4617 target_flags_explicit |= MASK_SOFT_FLOAT;
4618 rs6000_xilinx_fpu = 1;
4619 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4620 rs6000_single_float = 1;
4621 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4622 rs6000_single_float = rs6000_double_float = 1;
4623 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4624 rs6000_simple_fpu = 1;
4628 /* -mfpu=none is equivalent to -msoft-float */
4629 target_flags |= MASK_SOFT_FLOAT;
4630 target_flags_explicit |= MASK_SOFT_FLOAT;
4631 rs6000_single_float = rs6000_double_float = 0;
4635 rs6000_recip_name = (value) ? "default" : "none";
4639 rs6000_recip_name = arg;
4645 /* Do anything needed at the start of the asm file. */
4648 rs6000_file_start (void)
4652 const char *start = buffer;
4653 struct rs6000_cpu_select *ptr;
4654 const char *default_cpu = TARGET_CPU_DEFAULT;
4655 FILE *file = asm_out_file;
4657 default_file_start ();
4659 #ifdef TARGET_BI_ARCH
4660 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4664 if (flag_verbose_asm)
4666 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4667 rs6000_select[0].string = default_cpu;
4669 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4671 ptr = &rs6000_select[i];
4672 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4674 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4679 if (PPC405_ERRATUM77)
4681 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4685 #ifdef USING_ELFOS_H
4686 switch (rs6000_sdata)
4688 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4689 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4690 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4691 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4694 if (rs6000_sdata && g_switch_value)
4696 fprintf (file, "%s -G %d", start,
4706 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4708 switch_to_section (toc_section);
4709 switch_to_section (text_section);
4714 /* Return nonzero if this function is known to have a null epilogue. */
4717 direct_return (void)
4719 if (reload_completed)
4721 rs6000_stack_t *info = rs6000_stack_info ();
4723 if (info->first_gp_reg_save == 32
4724 && info->first_fp_reg_save == 64
4725 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4726 && ! info->lr_save_p
4727 && ! info->cr_save_p
4728 && info->vrsave_mask == 0
4736 /* Return the number of instructions it takes to form a constant in an
4737 integer register. */
4740 num_insns_constant_wide (HOST_WIDE_INT value)
4742 /* signed constant loadable with {cal|addi} */
4743 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4746 /* constant loadable with {cau|addis} */
4747 else if ((value & 0xffff) == 0
4748 && (value >> 31 == -1 || value >> 31 == 0))
4751 #if HOST_BITS_PER_WIDE_INT == 64
4752 else if (TARGET_POWERPC64)
4754 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4755 HOST_WIDE_INT high = value >> 31;
4757 if (high == 0 || high == -1)
4763 return num_insns_constant_wide (high) + 1;
4765 return num_insns_constant_wide (low) + 1;
4767 return (num_insns_constant_wide (high)
4768 + num_insns_constant_wide (low) + 1);
4777 num_insns_constant (rtx op, enum machine_mode mode)
4779 HOST_WIDE_INT low, high;
4781 switch (GET_CODE (op))
4784 #if HOST_BITS_PER_WIDE_INT == 64
4785 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4786 && mask64_operand (op, mode))
4790 return num_insns_constant_wide (INTVAL (op));
4793 if (mode == SFmode || mode == SDmode)
4798 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4799 if (DECIMAL_FLOAT_MODE_P (mode))
4800 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4802 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4803 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4806 if (mode == VOIDmode || mode == DImode)
4808 high = CONST_DOUBLE_HIGH (op);
4809 low = CONST_DOUBLE_LOW (op);
4816 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4817 if (DECIMAL_FLOAT_MODE_P (mode))
4818 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4820 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4821 high = l[WORDS_BIG_ENDIAN == 0];
4822 low = l[WORDS_BIG_ENDIAN != 0];
4826 return (num_insns_constant_wide (low)
4827 + num_insns_constant_wide (high));
4830 if ((high == 0 && low >= 0)
4831 || (high == -1 && low < 0))
4832 return num_insns_constant_wide (low);
4834 else if (mask64_operand (op, mode))
4838 return num_insns_constant_wide (high) + 1;
4841 return (num_insns_constant_wide (high)
4842 + num_insns_constant_wide (low) + 1);
4850 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4851 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4852 corresponding element of the vector, but for V4SFmode and V2SFmode,
4853 the corresponding "float" is interpreted as an SImode integer. */
4856 const_vector_elt_as_int (rtx op, unsigned int elt)
4860 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4861 gcc_assert (GET_MODE (op) != V2DImode
4862 && GET_MODE (op) != V2DFmode);
4864 tmp = CONST_VECTOR_ELT (op, elt);
4865 if (GET_MODE (op) == V4SFmode
4866 || GET_MODE (op) == V2SFmode)
4867 tmp = gen_lowpart (SImode, tmp);
4868 return INTVAL (tmp);
4871 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4872 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4873 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4874 all items are set to the same value and contain COPIES replicas of the
4875 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4876 operand and the others are set to the value of the operand's msb. */
4879 vspltis_constant (rtx op, unsigned step, unsigned copies)
4881 enum machine_mode mode = GET_MODE (op);
4882 enum machine_mode inner = GET_MODE_INNER (mode);
4890 HOST_WIDE_INT splat_val;
4891 HOST_WIDE_INT msb_val;
4893 if (mode == V2DImode || mode == V2DFmode)
4896 nunits = GET_MODE_NUNITS (mode);
4897 bitsize = GET_MODE_BITSIZE (inner);
4898 mask = GET_MODE_MASK (inner);
4900 val = const_vector_elt_as_int (op, nunits - 1);
4902 msb_val = val > 0 ? 0 : -1;
4904 /* Construct the value to be splatted, if possible. If not, return 0. */
4905 for (i = 2; i <= copies; i *= 2)
4907 HOST_WIDE_INT small_val;
4909 small_val = splat_val >> bitsize;
4911 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4913 splat_val = small_val;
4916 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4917 if (EASY_VECTOR_15 (splat_val))
4920 /* Also check if we can splat, and then add the result to itself. Do so if
4921 the value is positive, of if the splat instruction is using OP's mode;
4922 for splat_val < 0, the splat and the add should use the same mode. */
4923 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4924 && (splat_val >= 0 || (step == 1 && copies == 1)))
4927 /* Also check if are loading up the most significant bit which can be done by
4928 loading up -1 and shifting the value left by -1. */
4929 else if (EASY_VECTOR_MSB (splat_val, inner))
4935 /* Check if VAL is present in every STEP-th element, and the
4936 other elements are filled with its most significant bit. */
4937 for (i = 0; i < nunits - 1; ++i)
4939 HOST_WIDE_INT desired_val;
4940 if (((i + 1) & (step - 1)) == 0)
4943 desired_val = msb_val;
4945 if (desired_val != const_vector_elt_as_int (op, i))
4953 /* Return true if OP is of the given MODE and can be synthesized
4954 with a vspltisb, vspltish or vspltisw. */
4957 easy_altivec_constant (rtx op, enum machine_mode mode)
4959 unsigned step, copies;
4961 if (mode == VOIDmode)
4962 mode = GET_MODE (op);
4963 else if (mode != GET_MODE (op))
4966 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4968 if (mode == V2DFmode)
4969 return zero_constant (op, mode);
4971 if (mode == V2DImode)
4973 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4975 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4976 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4979 if (zero_constant (op, mode))
4982 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4983 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4989 /* Start with a vspltisw. */
4990 step = GET_MODE_NUNITS (mode) / 4;
4993 if (vspltis_constant (op, step, copies))
4996 /* Then try with a vspltish. */
5002 if (vspltis_constant (op, step, copies))
5005 /* And finally a vspltisb. */
5011 if (vspltis_constant (op, step, copies))
5017 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
5018 result is OP. Abort if it is not possible. */
5021 gen_easy_altivec_constant (rtx op)
5023 enum machine_mode mode = GET_MODE (op);
5024 int nunits = GET_MODE_NUNITS (mode);
5025 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
5026 unsigned step = nunits / 4;
5027 unsigned copies = 1;
5029 /* Start with a vspltisw. */
5030 if (vspltis_constant (op, step, copies))
5031 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5033 /* Then try with a vspltish. */
5039 if (vspltis_constant (op, step, copies))
5040 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5042 /* And finally a vspltisb. */
5048 if (vspltis_constant (op, step, copies))
5049 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5055 output_vec_const_move (rtx *operands)
5058 enum machine_mode mode;
5063 mode = GET_MODE (dest);
5067 if (zero_constant (vec, mode))
5068 return "xxlxor %x0,%x0,%x0";
5070 if (mode == V2DImode
5071 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5072 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5073 return "vspltisw %0,-1";
5079 if (zero_constant (vec, mode))
5080 return "vxor %0,%0,%0";
5082 splat_vec = gen_easy_altivec_constant (vec);
5083 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5084 operands[1] = XEXP (splat_vec, 0);
5085 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5088 switch (GET_MODE (splat_vec))
5091 return "vspltisw %0,%1";
5094 return "vspltish %0,%1";
5097 return "vspltisb %0,%1";
5104 gcc_assert (TARGET_SPE);
5106 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5107 pattern of V1DI, V4HI, and V2SF.
5109 FIXME: We should probably return # and add post reload
5110 splitters for these, but this way is so easy ;-). */
5111 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5112 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5113 operands[1] = CONST_VECTOR_ELT (vec, 0);
5114 operands[2] = CONST_VECTOR_ELT (vec, 1);
5116 return "li %0,%1\n\tevmergelo %0,%0,%0";
5118 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5121 /* Initialize TARGET of vector PAIRED to VALS. */
5124 paired_expand_vector_init (rtx target, rtx vals)
5126 enum machine_mode mode = GET_MODE (target);
5127 int n_elts = GET_MODE_NUNITS (mode);
5129 rtx x, new_rtx, tmp, constant_op, op1, op2;
5132 for (i = 0; i < n_elts; ++i)
5134 x = XVECEXP (vals, 0, i);
5135 if (!CONSTANT_P (x))
5140 /* Load from constant pool. */
5141 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5147 /* The vector is initialized only with non-constants. */
5148 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5149 XVECEXP (vals, 0, 1));
5151 emit_move_insn (target, new_rtx);
5155 /* One field is non-constant and the other one is a constant. Load the
5156 constant from the constant pool and use ps_merge instruction to
5157 construct the whole vector. */
5158 op1 = XVECEXP (vals, 0, 0);
5159 op2 = XVECEXP (vals, 0, 1);
5161 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5163 tmp = gen_reg_rtx (GET_MODE (constant_op));
5164 emit_move_insn (tmp, constant_op);
5166 if (CONSTANT_P (op1))
5167 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5169 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5171 emit_move_insn (target, new_rtx);
5175 paired_expand_vector_move (rtx operands[])
5177 rtx op0 = operands[0], op1 = operands[1];
5179 emit_move_insn (op0, op1);
5182 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5183 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5184 operands for the relation operation COND. This is a recursive
5188 paired_emit_vector_compare (enum rtx_code rcode,
5189 rtx dest, rtx op0, rtx op1,
5190 rtx cc_op0, rtx cc_op1)
5192 rtx tmp = gen_reg_rtx (V2SFmode);
5195 gcc_assert (TARGET_PAIRED_FLOAT);
5196 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5202 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5206 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5207 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5211 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5214 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5217 tmp1 = gen_reg_rtx (V2SFmode);
5218 max = gen_reg_rtx (V2SFmode);
5219 min = gen_reg_rtx (V2SFmode);
5220 gen_reg_rtx (V2SFmode);
5222 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5223 emit_insn (gen_selv2sf4
5224 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5225 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5226 emit_insn (gen_selv2sf4
5227 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5228 emit_insn (gen_subv2sf3 (tmp1, min, max));
5229 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5232 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5235 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5238 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5241 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5244 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5253 /* Emit vector conditional expression.
5254 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5255 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5258 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5259 rtx cond, rtx cc_op0, rtx cc_op1)
5261 enum rtx_code rcode = GET_CODE (cond);
5263 if (!TARGET_PAIRED_FLOAT)
5266 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5271 /* Initialize vector TARGET to VALS. */
5274 rs6000_expand_vector_init (rtx target, rtx vals)
5276 enum machine_mode mode = GET_MODE (target);
5277 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5278 int n_elts = GET_MODE_NUNITS (mode);
5279 int n_var = 0, one_var = -1;
5280 bool all_same = true, all_const_zero = true;
5284 for (i = 0; i < n_elts; ++i)
5286 x = XVECEXP (vals, 0, i);
5287 if (!CONSTANT_P (x))
5288 ++n_var, one_var = i;
5289 else if (x != CONST0_RTX (inner_mode))
5290 all_const_zero = false;
5292 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5298 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5299 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5300 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5302 /* Zero register. */
5303 emit_insn (gen_rtx_SET (VOIDmode, target,
5304 gen_rtx_XOR (mode, target, target)));
5307 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5309 /* Splat immediate. */
5310 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5315 /* Load from constant pool. */
5316 emit_move_insn (target, const_vec);
5321 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5322 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5326 rtx element = XVECEXP (vals, 0, 0);
5327 if (mode == V2DFmode)
5328 emit_insn (gen_vsx_splat_v2df (target, element));
5330 emit_insn (gen_vsx_splat_v2di (target, element));
5334 if (mode == V2DFmode)
5336 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5337 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5338 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5342 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5343 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5344 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5350 /* With single precision floating point on VSX, know that internally single
5351 precision is actually represented as a double, and either make 2 V2DF
5352 vectors, and convert these vectors to single precision, or do one
5353 conversion, and splat the result to the other elements. */
5354 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5358 rtx freg = gen_reg_rtx (V4SFmode);
5359 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5361 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5362 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5366 rtx dbl_even = gen_reg_rtx (V2DFmode);
5367 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5368 rtx flt_even = gen_reg_rtx (V4SFmode);
5369 rtx flt_odd = gen_reg_rtx (V4SFmode);
5371 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5372 copy_to_reg (XVECEXP (vals, 0, 0)),
5373 copy_to_reg (XVECEXP (vals, 0, 1))));
5374 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5375 copy_to_reg (XVECEXP (vals, 0, 2)),
5376 copy_to_reg (XVECEXP (vals, 0, 3))));
5377 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5378 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5379 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5384 /* Store value to stack temp. Load vector element. Splat. However, splat
5385 of 64-bit items is not supported on Altivec. */
5386 if (all_same && GET_MODE_SIZE (mode) <= 4)
5388 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5389 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5390 XVECEXP (vals, 0, 0));
5391 x = gen_rtx_UNSPEC (VOIDmode,
5392 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5393 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5395 gen_rtx_SET (VOIDmode,
5398 x = gen_rtx_VEC_SELECT (inner_mode, target,
5399 gen_rtx_PARALLEL (VOIDmode,
5400 gen_rtvec (1, const0_rtx)));
5401 emit_insn (gen_rtx_SET (VOIDmode, target,
5402 gen_rtx_VEC_DUPLICATE (mode, x)));
5406 /* One field is non-constant. Load constant then overwrite
5410 rtx copy = copy_rtx (vals);
5412 /* Load constant part of vector, substitute neighboring value for
5414 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5415 rs6000_expand_vector_init (target, copy);
5417 /* Insert variable. */
5418 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5422 /* Construct the vector in memory one field at a time
5423 and load the whole vector. */
5424 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5425 for (i = 0; i < n_elts; i++)
5426 emit_move_insn (adjust_address_nv (mem, inner_mode,
5427 i * GET_MODE_SIZE (inner_mode)),
5428 XVECEXP (vals, 0, i));
5429 emit_move_insn (target, mem);
5432 /* Set field ELT of TARGET to VAL. */
5435 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5437 enum machine_mode mode = GET_MODE (target);
5438 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5439 rtx reg = gen_reg_rtx (mode);
5441 int width = GET_MODE_SIZE (inner_mode);
5444 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5446 rtx (*set_func) (rtx, rtx, rtx, rtx)
5447 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5448 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5452 /* Load single variable value. */
5453 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5454 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5455 x = gen_rtx_UNSPEC (VOIDmode,
5456 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5457 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5459 gen_rtx_SET (VOIDmode,
5463 /* Linear sequence. */
5464 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5465 for (i = 0; i < 16; ++i)
5466 XVECEXP (mask, 0, i) = GEN_INT (i);
5468 /* Set permute mask to insert element into target. */
5469 for (i = 0; i < width; ++i)
5470 XVECEXP (mask, 0, elt*width + i)
5471 = GEN_INT (i + 0x10);
5472 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5473 x = gen_rtx_UNSPEC (mode,
5474 gen_rtvec (3, target, reg,
5475 force_reg (V16QImode, x)),
5477 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5480 /* Extract field ELT from VEC into TARGET. */
5483 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5485 enum machine_mode mode = GET_MODE (vec);
5486 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5489 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5491 rtx (*extract_func) (rtx, rtx, rtx)
5492 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5493 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5497 /* Allocate mode-sized buffer. */
5498 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5500 emit_move_insn (mem, vec);
5502 /* Add offset to field within buffer matching vector element. */
5503 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5505 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5508 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5509 implement ANDing by the mask IN. */
5511 build_mask64_2_operands (rtx in, rtx *out)
5513 #if HOST_BITS_PER_WIDE_INT >= 64
5514 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5517 gcc_assert (GET_CODE (in) == CONST_INT);
5522 /* Assume c initially something like 0x00fff000000fffff. The idea
5523 is to rotate the word so that the middle ^^^^^^ group of zeros
5524 is at the MS end and can be cleared with an rldicl mask. We then
5525 rotate back and clear off the MS ^^ group of zeros with a
5527 c = ~c; /* c == 0xff000ffffff00000 */
5528 lsb = c & -c; /* lsb == 0x0000000000100000 */
5529 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5530 c = ~c; /* c == 0x00fff000000fffff */
5531 c &= -lsb; /* c == 0x00fff00000000000 */
5532 lsb = c & -c; /* lsb == 0x0000100000000000 */
5533 c = ~c; /* c == 0xff000fffffffffff */
5534 c &= -lsb; /* c == 0xff00000000000000 */
5536 while ((lsb >>= 1) != 0)
5537 shift++; /* shift == 44 on exit from loop */
5538 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5539 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5540 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5544 /* Assume c initially something like 0xff000f0000000000. The idea
5545 is to rotate the word so that the ^^^ middle group of zeros
5546 is at the LS end and can be cleared with an rldicr mask. We then
5547 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5549 lsb = c & -c; /* lsb == 0x0000010000000000 */
5550 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5551 c = ~c; /* c == 0x00fff0ffffffffff */
5552 c &= -lsb; /* c == 0x00fff00000000000 */
5553 lsb = c & -c; /* lsb == 0x0000100000000000 */
5554 c = ~c; /* c == 0xff000fffffffffff */
5555 c &= -lsb; /* c == 0xff00000000000000 */
5557 while ((lsb >>= 1) != 0)
5558 shift++; /* shift == 44 on exit from loop */
5559 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5560 m1 >>= shift; /* m1 == 0x0000000000000fff */
5561 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5564 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5565 masks will be all 1's. We are guaranteed more than one transition. */
5566 out[0] = GEN_INT (64 - shift);
5567 out[1] = GEN_INT (m1);
5568 out[2] = GEN_INT (shift);
5569 out[3] = GEN_INT (m2);
5577 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5580 invalid_e500_subreg (rtx op, enum machine_mode mode)
5582 if (TARGET_E500_DOUBLE)
5584 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5585 subreg:TI and reg:TF. Decimal float modes are like integer
5586 modes (only low part of each register used) for this
5588 if (GET_CODE (op) == SUBREG
5589 && (mode == SImode || mode == DImode || mode == TImode
5590 || mode == DDmode || mode == TDmode)
5591 && REG_P (SUBREG_REG (op))
5592 && (GET_MODE (SUBREG_REG (op)) == DFmode
5593 || GET_MODE (SUBREG_REG (op)) == TFmode))
5596 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5598 if (GET_CODE (op) == SUBREG
5599 && (mode == DFmode || mode == TFmode)
5600 && REG_P (SUBREG_REG (op))
5601 && (GET_MODE (SUBREG_REG (op)) == DImode
5602 || GET_MODE (SUBREG_REG (op)) == TImode
5603 || GET_MODE (SUBREG_REG (op)) == DDmode
5604 || GET_MODE (SUBREG_REG (op)) == TDmode))
5609 && GET_CODE (op) == SUBREG
5611 && REG_P (SUBREG_REG (op))
5612 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5618 /* AIX increases natural record alignment to doubleword if the first
5619 field is an FP double while the FP fields remain word aligned. */
5622 rs6000_special_round_type_align (tree type, unsigned int computed,
5623 unsigned int specified)
5625 unsigned int align = MAX (computed, specified);
5626 tree field = TYPE_FIELDS (type);
5628 /* Skip all non field decls */
5629 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5630 field = DECL_CHAIN (field);
5632 if (field != NULL && field != type)
5634 type = TREE_TYPE (field);
5635 while (TREE_CODE (type) == ARRAY_TYPE)
5636 type = TREE_TYPE (type);
5638 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5639 align = MAX (align, 64);
5645 /* Darwin increases record alignment to the natural alignment of
5649 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5650 unsigned int specified)
5652 unsigned int align = MAX (computed, specified);
5654 if (TYPE_PACKED (type))
5657 /* Find the first field, looking down into aggregates. */
5659 tree field = TYPE_FIELDS (type);
5660 /* Skip all non field decls */
5661 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5662 field = DECL_CHAIN (field);
5665 /* A packed field does not contribute any extra alignment. */
5666 if (DECL_PACKED (field))
5668 type = TREE_TYPE (field);
5669 while (TREE_CODE (type) == ARRAY_TYPE)
5670 type = TREE_TYPE (type);
5671 } while (AGGREGATE_TYPE_P (type));
5673 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5674 align = MAX (align, TYPE_ALIGN (type));
5679 /* Return 1 for an operand in small memory on V.4/eabi. */
5682 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5683 enum machine_mode mode ATTRIBUTE_UNUSED)
5688 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5691 if (DEFAULT_ABI != ABI_V4)
5694 /* Vector and float memory instructions have a limited offset on the
5695 SPE, so using a vector or float variable directly as an operand is
5698 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5701 if (GET_CODE (op) == SYMBOL_REF)
5704 else if (GET_CODE (op) != CONST
5705 || GET_CODE (XEXP (op, 0)) != PLUS
5706 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5707 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5712 rtx sum = XEXP (op, 0);
5713 HOST_WIDE_INT summand;
5715 /* We have to be careful here, because it is the referenced address
5716 that must be 32k from _SDA_BASE_, not just the symbol. */
5717 summand = INTVAL (XEXP (sum, 1));
5718 if (summand < 0 || summand > g_switch_value)
5721 sym_ref = XEXP (sum, 0);
5724 return SYMBOL_REF_SMALL_P (sym_ref);
5730 /* Return true if either operand is a general purpose register. */
5733 gpr_or_gpr_p (rtx op0, rtx op1)
5735 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5736 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5740 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5743 reg_offset_addressing_ok_p (enum machine_mode mode)
5753 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5754 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5762 /* Paired vector modes. Only reg+reg addressing is valid. */
5763 if (TARGET_PAIRED_FLOAT)
5775 virtual_stack_registers_memory_p (rtx op)
5779 if (GET_CODE (op) == REG)
5780 regnum = REGNO (op);
5782 else if (GET_CODE (op) == PLUS
5783 && GET_CODE (XEXP (op, 0)) == REG
5784 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5785 regnum = REGNO (XEXP (op, 0));
5790 return (regnum >= FIRST_VIRTUAL_REGISTER
5791 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5794 /* Return true if memory accesses to OP are known to never straddle
5798 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5799 enum machine_mode mode)
5802 unsigned HOST_WIDE_INT dsize, dalign;
5804 if (GET_CODE (op) != SYMBOL_REF)
5807 decl = SYMBOL_REF_DECL (op);
5810 if (GET_MODE_SIZE (mode) == 0)
5813 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5814 replacing memory addresses with an anchor plus offset. We
5815 could find the decl by rummaging around in the block->objects
5816 VEC for the given offset but that seems like too much work. */
5818 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5819 && SYMBOL_REF_ANCHOR_P (op)
5820 && SYMBOL_REF_BLOCK (op) != NULL)
5822 struct object_block *block = SYMBOL_REF_BLOCK (op);
5823 HOST_WIDE_INT lsb, mask;
5825 /* Given the alignment of the block.. */
5826 dalign = block->alignment;
5827 mask = dalign / BITS_PER_UNIT - 1;
5829 /* ..and the combined offset of the anchor and any offset
5830 to this block object.. */
5831 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5832 lsb = offset & -offset;
5834 /* ..find how many bits of the alignment we know for the
5839 return dalign >= GET_MODE_SIZE (mode);
5844 if (TREE_CODE (decl) == FUNCTION_DECL)
5847 if (!DECL_SIZE_UNIT (decl))
5850 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5853 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5857 dalign = DECL_ALIGN_UNIT (decl);
5858 return dalign >= dsize;
5861 type = TREE_TYPE (decl);
5863 if (TREE_CODE (decl) == STRING_CST)
5864 dsize = TREE_STRING_LENGTH (decl);
5865 else if (TYPE_SIZE_UNIT (type)
5866 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5867 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5873 dalign = TYPE_ALIGN (type);
5874 if (CONSTANT_CLASS_P (decl))
5875 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5877 dalign = DATA_ALIGNMENT (decl, dalign);
5878 dalign /= BITS_PER_UNIT;
5879 return dalign >= dsize;
5883 constant_pool_expr_p (rtx op)
5887 split_const (op, &base, &offset);
5888 return (GET_CODE (base) == SYMBOL_REF
5889 && CONSTANT_POOL_ADDRESS_P (base)
5890 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5893 static rtx tocrel_base, tocrel_offset;
5896 toc_relative_expr_p (rtx op)
5898 if (GET_CODE (op) != CONST)
5901 split_const (op, &tocrel_base, &tocrel_offset);
5902 return (GET_CODE (tocrel_base) == UNSPEC
5903 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5906 /* Return true if X is a constant pool address, and also for cmodel=medium
5907 if X is a toc-relative address known to be offsettable within MODE. */
5910 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5914 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5915 && GET_CODE (XEXP (x, 0)) == REG
5916 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5917 || ((TARGET_MINIMAL_TOC
5918 || TARGET_CMODEL != CMODEL_SMALL)
5919 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5920 && toc_relative_expr_p (XEXP (x, 1))
5921 && (TARGET_CMODEL != CMODEL_MEDIUM
5922 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5924 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5925 INTVAL (tocrel_offset), mode)));
5929 legitimate_small_data_p (enum machine_mode mode, rtx x)
5931 return (DEFAULT_ABI == ABI_V4
5932 && !flag_pic && !TARGET_TOC
5933 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5934 && small_data_operand (x, mode));
5937 /* SPE offset addressing is limited to 5-bits worth of double words. */
5938 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5941 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5943 unsigned HOST_WIDE_INT offset, extra;
5945 if (GET_CODE (x) != PLUS)
5947 if (GET_CODE (XEXP (x, 0)) != REG)
5949 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5951 if (!reg_offset_addressing_ok_p (mode))
5952 return virtual_stack_registers_memory_p (x);
5953 if (legitimate_constant_pool_address_p (x, mode, strict))
5955 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5958 offset = INTVAL (XEXP (x, 1));
5966 /* SPE vector modes. */
5967 return SPE_CONST_OFFSET_OK (offset);
5970 if (TARGET_E500_DOUBLE)
5971 return SPE_CONST_OFFSET_OK (offset);
5973 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5975 if (VECTOR_MEM_VSX_P (DFmode))
5980 /* On e500v2, we may have:
5982 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5984 Which gets addressed with evldd instructions. */
5985 if (TARGET_E500_DOUBLE)
5986 return SPE_CONST_OFFSET_OK (offset);
5988 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5990 else if (offset & 3)
5995 if (TARGET_E500_DOUBLE)
5996 return (SPE_CONST_OFFSET_OK (offset)
5997 && SPE_CONST_OFFSET_OK (offset + 8));
6001 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
6003 else if (offset & 3)
6014 return (offset < 0x10000) && (offset + extra < 0x10000);
6018 legitimate_indexed_address_p (rtx x, int strict)
6022 if (GET_CODE (x) != PLUS)
6028 /* Recognize the rtl generated by reload which we know will later be
6029 replaced with proper base and index regs. */
6031 && reload_in_progress
6032 && (REG_P (op0) || GET_CODE (op0) == PLUS)
6036 return (REG_P (op0) && REG_P (op1)
6037 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
6038 && INT_REG_OK_FOR_INDEX_P (op1, strict))
6039 || (INT_REG_OK_FOR_BASE_P (op1, strict)
6040 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
6044 avoiding_indexed_address_p (enum machine_mode mode)
6046 /* Avoid indexed addressing for modes that have non-indexed
6047 load/store instruction forms. */
6048 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
6052 legitimate_indirect_address_p (rtx x, int strict)
6054 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
6058 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
6060 if (!TARGET_MACHO || !flag_pic
6061 || mode != SImode || GET_CODE (x) != MEM)
6065 if (GET_CODE (x) != LO_SUM)
6067 if (GET_CODE (XEXP (x, 0)) != REG)
6069 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
6073 return CONSTANT_P (x);
6077 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
6079 if (GET_CODE (x) != LO_SUM)
6081 if (GET_CODE (XEXP (x, 0)) != REG)
6083 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
6085 /* Restrict addressing for DI because of our SUBREG hackery. */
6086 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6087 || mode == DDmode || mode == TDmode
6092 if (TARGET_ELF || TARGET_MACHO)
6094 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
6098 if (GET_MODE_NUNITS (mode) != 1)
6100 if (GET_MODE_BITSIZE (mode) > 64
6101 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6102 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6103 && (mode == DFmode || mode == DDmode))))
6106 return CONSTANT_P (x);
6113 /* Try machine-dependent ways of modifying an illegitimate address
6114 to be legitimate. If we find one, return the new, valid address.
6115 This is used from only one place: `memory_address' in explow.c.
6117 OLDX is the address as it was before break_out_memory_refs was
6118 called. In some cases it is useful to look at this to decide what
6121 It is always safe for this function to do nothing. It exists to
6122 recognize opportunities to optimize the output.
6124 On RS/6000, first check for the sum of a register with a constant
6125 integer that is out of range. If so, generate code to add the
6126 constant with the low-order 16 bits masked to the register and force
6127 this result into another register (this can be done with `cau').
6128 Then generate an address of REG+(CONST&0xffff), allowing for the
6129 possibility of bit 16 being a one.
6131 Then check for the sum of a register and something not constant, try to
6132 load the other things into a register and return the sum. */
6135 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6136 enum machine_mode mode)
6138 unsigned int extra = 0;
6140 if (!reg_offset_addressing_ok_p (mode))
6142 if (virtual_stack_registers_memory_p (x))
6145 /* In theory we should not be seeing addresses of the form reg+0,
6146 but just in case it is generated, optimize it away. */
6147 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6148 return force_reg (Pmode, XEXP (x, 0));
6150 /* Make sure both operands are registers. */
6151 else if (GET_CODE (x) == PLUS)
6152 return gen_rtx_PLUS (Pmode,
6153 force_reg (Pmode, XEXP (x, 0)),
6154 force_reg (Pmode, XEXP (x, 1)));
6156 return force_reg (Pmode, x);
6158 if (GET_CODE (x) == SYMBOL_REF)
6160 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6162 return rs6000_legitimize_tls_address (x, model);
6172 if (!TARGET_POWERPC64)
6180 extra = TARGET_POWERPC64 ? 8 : 12;
6186 if (GET_CODE (x) == PLUS
6187 && GET_CODE (XEXP (x, 0)) == REG
6188 && GET_CODE (XEXP (x, 1)) == CONST_INT
6189 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6191 && !((TARGET_POWERPC64
6192 && (mode == DImode || mode == TImode)
6193 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6194 || SPE_VECTOR_MODE (mode)
6195 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6196 || mode == DImode || mode == DDmode
6197 || mode == TDmode))))
6199 HOST_WIDE_INT high_int, low_int;
6201 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6202 if (low_int >= 0x8000 - extra)
6204 high_int = INTVAL (XEXP (x, 1)) - low_int;
6205 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6206 GEN_INT (high_int)), 0);
6207 return plus_constant (sum, low_int);
6209 else if (GET_CODE (x) == PLUS
6210 && GET_CODE (XEXP (x, 0)) == REG
6211 && GET_CODE (XEXP (x, 1)) != CONST_INT
6212 && GET_MODE_NUNITS (mode) == 1
6213 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6215 || ((mode != DImode && mode != DFmode && mode != DDmode)
6216 || (TARGET_E500_DOUBLE && mode != DDmode)))
6217 && (TARGET_POWERPC64 || mode != DImode)
6218 && !avoiding_indexed_address_p (mode)
6223 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6224 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6226 else if (SPE_VECTOR_MODE (mode)
6227 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6228 || mode == DDmode || mode == TDmode
6229 || mode == DImode)))
6233 /* We accept [reg + reg] and [reg + OFFSET]. */
6235 if (GET_CODE (x) == PLUS)
6237 rtx op1 = XEXP (x, 0);
6238 rtx op2 = XEXP (x, 1);
6241 op1 = force_reg (Pmode, op1);
6243 if (GET_CODE (op2) != REG
6244 && (GET_CODE (op2) != CONST_INT
6245 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6246 || (GET_MODE_SIZE (mode) > 8
6247 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6248 op2 = force_reg (Pmode, op2);
6250 /* We can't always do [reg + reg] for these, because [reg +
6251 reg + offset] is not a legitimate addressing mode. */
6252 y = gen_rtx_PLUS (Pmode, op1, op2);
6254 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6255 return force_reg (Pmode, y);
6260 return force_reg (Pmode, x);
6266 && GET_CODE (x) != CONST_INT
6267 && GET_CODE (x) != CONST_DOUBLE
6269 && GET_MODE_NUNITS (mode) == 1
6270 && (GET_MODE_BITSIZE (mode) <= 32
6271 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6272 && (mode == DFmode || mode == DDmode))))
6274 rtx reg = gen_reg_rtx (Pmode);
6275 emit_insn (gen_elf_high (reg, x));
6276 return gen_rtx_LO_SUM (Pmode, reg, x);
6278 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6281 && ! MACHO_DYNAMIC_NO_PIC_P
6283 && GET_CODE (x) != CONST_INT
6284 && GET_CODE (x) != CONST_DOUBLE
6286 && GET_MODE_NUNITS (mode) == 1
6287 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6288 || (mode != DFmode && mode != DDmode))
6292 rtx reg = gen_reg_rtx (Pmode);
6293 emit_insn (gen_macho_high (reg, x));
6294 return gen_rtx_LO_SUM (Pmode, reg, x);
6297 && GET_CODE (x) == SYMBOL_REF
6298 && constant_pool_expr_p (x)
6299 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6301 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6302 return create_TOC_reference (x, reg);
6308 /* Debug version of rs6000_legitimize_address. */
6310 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6316 ret = rs6000_legitimize_address (x, oldx, mode);
6317 insns = get_insns ();
6323 "\nrs6000_legitimize_address: mode %s, old code %s, "
6324 "new code %s, modified\n",
6325 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6326 GET_RTX_NAME (GET_CODE (ret)));
6328 fprintf (stderr, "Original address:\n");
6331 fprintf (stderr, "oldx:\n");
6334 fprintf (stderr, "New address:\n");
6339 fprintf (stderr, "Insns added:\n");
6340 debug_rtx_list (insns, 20);
6346 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6347 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6358 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6359 We need to emit DTP-relative relocations. */
6362 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6367 fputs ("\t.long\t", file);
6370 fputs (DOUBLE_INT_ASM_OP, file);
6375 output_addr_const (file, x);
6376 fputs ("@dtprel+0x8000", file);
6379 /* In the name of slightly smaller debug output, and to cater to
6380 general assembler lossage, recognize various UNSPEC sequences
6381 and turn them back into a direct symbol reference. */
6384 rs6000_delegitimize_address (rtx orig_x)
6388 orig_x = delegitimize_mem_from_attrs (orig_x);
6393 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6394 && GET_CODE (XEXP (x, 1)) == CONST)
6396 y = XEXP (XEXP (x, 1), 0);
6397 if (GET_CODE (y) == UNSPEC
6398 && XINT (y, 1) == UNSPEC_TOCREL
6399 && ((GET_CODE (XEXP (x, 0)) == REG
6400 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6401 || TARGET_MINIMAL_TOC
6402 || TARGET_CMODEL != CMODEL_SMALL))
6403 || (TARGET_CMODEL != CMODEL_SMALL
6404 && GET_CODE (XEXP (x, 0)) == PLUS
6405 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6406 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6407 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6408 && rtx_equal_p (XEXP (x, 1),
6409 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6411 y = XVECEXP (y, 0, 0);
6412 if (!MEM_P (orig_x))
6415 return replace_equiv_address_nv (orig_x, y);
6420 && GET_CODE (orig_x) == LO_SUM
6421 && GET_CODE (XEXP (x, 1)) == CONST)
6423 y = XEXP (XEXP (x, 1), 0);
6424 if (GET_CODE (y) == UNSPEC
6425 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6426 return XVECEXP (y, 0, 0);
6432 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6434 static GTY(()) rtx rs6000_tls_symbol;
6436 rs6000_tls_get_addr (void)
6438 if (!rs6000_tls_symbol)
6439 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6441 return rs6000_tls_symbol;
6444 /* Construct the SYMBOL_REF for TLS GOT references. */
6446 static GTY(()) rtx rs6000_got_symbol;
6448 rs6000_got_sym (void)
6450 if (!rs6000_got_symbol)
6452 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6453 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6454 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6457 return rs6000_got_symbol;
6460 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6461 this (thread-local) address. */
6464 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6468 dest = gen_reg_rtx (Pmode);
6469 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6475 tlsreg = gen_rtx_REG (Pmode, 13);
6476 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6480 tlsreg = gen_rtx_REG (Pmode, 2);
6481 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6485 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6489 tmp = gen_reg_rtx (Pmode);
6492 tlsreg = gen_rtx_REG (Pmode, 13);
6493 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6497 tlsreg = gen_rtx_REG (Pmode, 2);
6498 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6502 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6504 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6509 rtx r3, got, tga, tmp1, tmp2, call_insn;
6511 /* We currently use relocations like @got@tlsgd for tls, which
6512 means the linker will handle allocation of tls entries, placing
6513 them in the .got section. So use a pointer to the .got section,
6514 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6515 or to secondary GOT sections used by 32-bit -fPIC. */
6517 got = gen_rtx_REG (Pmode, 2);
6521 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6524 rtx gsym = rs6000_got_sym ();
6525 got = gen_reg_rtx (Pmode);
6527 rs6000_emit_move (got, gsym, Pmode);
6532 tmp1 = gen_reg_rtx (Pmode);
6533 tmp2 = gen_reg_rtx (Pmode);
6534 mem = gen_const_mem (Pmode, tmp1);
6535 lab = gen_label_rtx ();
6536 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6537 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6538 emit_move_insn (tmp2, mem);
6539 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6540 set_unique_reg_note (last, REG_EQUAL, gsym);
6545 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6547 r3 = gen_rtx_REG (Pmode, 3);
6548 tga = rs6000_tls_get_addr ();
6549 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6551 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6552 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6553 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6554 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6555 else if (DEFAULT_ABI == ABI_V4)
6556 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6559 call_insn = last_call_insn ();
6560 PATTERN (call_insn) = insn;
6561 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6562 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6563 pic_offset_table_rtx);
6565 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6567 r3 = gen_rtx_REG (Pmode, 3);
6568 tga = rs6000_tls_get_addr ();
6569 tmp1 = gen_reg_rtx (Pmode);
6570 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6572 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6573 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6574 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6575 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6576 else if (DEFAULT_ABI == ABI_V4)
6577 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6580 call_insn = last_call_insn ();
6581 PATTERN (call_insn) = insn;
6582 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6583 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6584 pic_offset_table_rtx);
6586 if (rs6000_tls_size == 16)
6589 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6591 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6593 else if (rs6000_tls_size == 32)
6595 tmp2 = gen_reg_rtx (Pmode);
6597 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6599 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6602 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6604 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6608 tmp2 = gen_reg_rtx (Pmode);
6610 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6612 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6614 insn = gen_rtx_SET (Pmode, dest,
6615 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6621 /* IE, or 64-bit offset LE. */
6622 tmp2 = gen_reg_rtx (Pmode);
6624 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6626 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6629 insn = gen_tls_tls_64 (dest, tmp2, addr);
6631 insn = gen_tls_tls_32 (dest, tmp2, addr);
6639 /* Return 1 if X contains a thread-local symbol. */
6642 rs6000_tls_referenced_p (rtx x)
6644 if (! TARGET_HAVE_TLS)
6647 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6650 /* Return 1 if *X is a thread-local symbol. This is the same as
6651 rs6000_tls_symbol_ref except for the type of the unused argument. */
6654 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6656 return RS6000_SYMBOL_REF_TLS_P (*x);
6659 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6660 replace the input X, or the original X if no replacement is called for.
6661 The output parameter *WIN is 1 if the calling macro should goto WIN,
6664 For RS/6000, we wish to handle large displacements off a base
6665 register by splitting the addend across an addiu/addis and the mem insn.
6666 This cuts number of extra insns needed from 3 to 1.
6668 On Darwin, we use this to generate code for floating point constants.
6669 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6670 The Darwin code is inside #if TARGET_MACHO because only then are the
6671 machopic_* functions defined. */
6673 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6674 int opnum, int type,
6675 int ind_levels ATTRIBUTE_UNUSED, int *win)
6677 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6679 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6680 DFmode/DImode MEM. */
6683 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6684 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6685 reg_offset_p = false;
6687 /* We must recognize output that we have already generated ourselves. */
6688 if (GET_CODE (x) == PLUS
6689 && GET_CODE (XEXP (x, 0)) == PLUS
6690 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6691 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6692 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6694 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6695 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6696 opnum, (enum reload_type)type);
6701 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6702 if (GET_CODE (x) == LO_SUM
6703 && GET_CODE (XEXP (x, 0)) == HIGH)
6705 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6706 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6707 opnum, (enum reload_type)type);
6713 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6714 && GET_CODE (x) == LO_SUM
6715 && GET_CODE (XEXP (x, 0)) == PLUS
6716 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6717 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6718 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6719 && machopic_operand_p (XEXP (x, 1)))
6721 /* Result of previous invocation of this function on Darwin
6722 floating point constant. */
6723 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6724 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6725 opnum, (enum reload_type)type);
6731 if (TARGET_CMODEL != CMODEL_SMALL
6732 && GET_CODE (x) == LO_SUM
6733 && GET_CODE (XEXP (x, 0)) == PLUS
6734 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6735 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6736 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6737 && GET_CODE (XEXP (x, 1)) == CONST
6738 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6739 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6740 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6742 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6743 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6744 opnum, (enum reload_type) type);
6749 /* Force ld/std non-word aligned offset into base register by wrapping
6751 if (GET_CODE (x) == PLUS
6752 && GET_CODE (XEXP (x, 0)) == REG
6753 && REGNO (XEXP (x, 0)) < 32
6754 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6755 && GET_CODE (XEXP (x, 1)) == CONST_INT
6757 && (INTVAL (XEXP (x, 1)) & 3) != 0
6758 && VECTOR_MEM_NONE_P (mode)
6759 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6760 && TARGET_POWERPC64)
6762 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6763 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6764 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6765 opnum, (enum reload_type) type);
6770 if (GET_CODE (x) == PLUS
6771 && GET_CODE (XEXP (x, 0)) == REG
6772 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6773 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6774 && GET_CODE (XEXP (x, 1)) == CONST_INT
6776 && !SPE_VECTOR_MODE (mode)
6777 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6778 || mode == DDmode || mode == TDmode
6780 && VECTOR_MEM_NONE_P (mode))
6782 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6783 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6785 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6787 /* Check for 32-bit overflow. */
6788 if (high + low != val)
6794 /* Reload the high part into a base reg; leave the low part
6795 in the mem directly. */
6797 x = gen_rtx_PLUS (GET_MODE (x),
6798 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6802 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6803 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6804 opnum, (enum reload_type)type);
6809 if (GET_CODE (x) == SYMBOL_REF
6811 && VECTOR_MEM_NONE_P (mode)
6812 && !SPE_VECTOR_MODE (mode)
6814 && DEFAULT_ABI == ABI_DARWIN
6815 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6817 && DEFAULT_ABI == ABI_V4
6820 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6821 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6825 && (mode != DImode || TARGET_POWERPC64)
6826 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6827 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6832 rtx offset = machopic_gen_offset (x);
6833 x = gen_rtx_LO_SUM (GET_MODE (x),
6834 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6835 gen_rtx_HIGH (Pmode, offset)), offset);
6839 x = gen_rtx_LO_SUM (GET_MODE (x),
6840 gen_rtx_HIGH (Pmode, x), x);
6842 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6843 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6844 opnum, (enum reload_type)type);
6849 /* Reload an offset address wrapped by an AND that represents the
6850 masking of the lower bits. Strip the outer AND and let reload
6851 convert the offset address into an indirect address. For VSX,
6852 force reload to create the address with an AND in a separate
6853 register, because we can't guarantee an altivec register will
6855 if (VECTOR_MEM_ALTIVEC_P (mode)
6856 && GET_CODE (x) == AND
6857 && GET_CODE (XEXP (x, 0)) == PLUS
6858 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6859 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6860 && GET_CODE (XEXP (x, 1)) == CONST_INT
6861 && INTVAL (XEXP (x, 1)) == -16)
6870 && GET_CODE (x) == SYMBOL_REF
6871 && constant_pool_expr_p (x)
6872 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6874 x = create_TOC_reference (x, NULL_RTX);
6875 if (TARGET_CMODEL != CMODEL_SMALL)
6876 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6877 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6878 opnum, (enum reload_type) type);
6886 /* Debug version of rs6000_legitimize_reload_address. */
6888 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6889 int opnum, int type,
6890 int ind_levels, int *win)
6892 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6895 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6896 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6897 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6901 fprintf (stderr, "Same address returned\n");
6903 fprintf (stderr, "NULL returned\n");
6906 fprintf (stderr, "New address:\n");
6913 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6914 that is a valid memory address for an instruction.
6915 The MODE argument is the machine mode for the MEM expression
6916 that wants to use this address.
6918 On the RS/6000, there are four valid address: a SYMBOL_REF that
6919 refers to a constant pool entry of an address (or the sum of it
6920 plus a constant), a short (16-bit signed) constant plus a register,
6921 the sum of two registers, or a register indirect, possibly with an
6922 auto-increment. For DFmode, DDmode and DImode with a constant plus
6923 register, we must ensure that both words are addressable or PowerPC64
6924 with offset word aligned.
6926 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6927 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6928 because adjacent memory cells are accessed by adding word-sized offsets
6929 during assembly output. */
6931 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6933 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6935 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6936 if (VECTOR_MEM_ALTIVEC_P (mode)
6937 && GET_CODE (x) == AND
6938 && GET_CODE (XEXP (x, 1)) == CONST_INT
6939 && INTVAL (XEXP (x, 1)) == -16)
6942 if (RS6000_SYMBOL_REF_TLS_P (x))
6944 if (legitimate_indirect_address_p (x, reg_ok_strict))
6946 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6947 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6948 && !SPE_VECTOR_MODE (mode)
6951 /* Restrict addressing for DI because of our SUBREG hackery. */
6952 && !(TARGET_E500_DOUBLE
6953 && (mode == DFmode || mode == DDmode || mode == DImode))
6955 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6957 if (virtual_stack_registers_memory_p (x))
6959 if (reg_offset_p && legitimate_small_data_p (mode, x))
6962 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6964 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6967 && GET_CODE (x) == PLUS
6968 && GET_CODE (XEXP (x, 0)) == REG
6969 && (XEXP (x, 0) == virtual_stack_vars_rtx
6970 || XEXP (x, 0) == arg_pointer_rtx)
6971 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6973 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6978 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6980 || (mode != DFmode && mode != DDmode)
6981 || (TARGET_E500_DOUBLE && mode != DDmode))
6982 && (TARGET_POWERPC64 || mode != DImode)
6983 && !avoiding_indexed_address_p (mode)
6984 && legitimate_indexed_address_p (x, reg_ok_strict))
6986 if (GET_CODE (x) == PRE_MODIFY
6990 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6992 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6993 && (TARGET_POWERPC64 || mode != DImode)
6994 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6995 && !SPE_VECTOR_MODE (mode)
6996 /* Restrict addressing for DI because of our SUBREG hackery. */
6997 && !(TARGET_E500_DOUBLE
6998 && (mode == DFmode || mode == DDmode || mode == DImode))
7000 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
7001 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
7002 || (!avoiding_indexed_address_p (mode)
7003 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
7004 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
7006 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
7011 /* Debug version of rs6000_legitimate_address_p. */
7013 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
7016 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
7018 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
7019 "strict = %d, code = %s\n",
7020 ret ? "true" : "false",
7021 GET_MODE_NAME (mode),
7023 GET_RTX_NAME (GET_CODE (x)));
7029 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7032 rs6000_mode_dependent_address_p (const_rtx addr)
7034 return rs6000_mode_dependent_address_ptr (addr);
7037 /* Go to LABEL if ADDR (a legitimate address expression)
7038 has an effect that depends on the machine mode it is used for.
7040 On the RS/6000 this is true of all integral offsets (since AltiVec
7041 and VSX modes don't allow them) or is a pre-increment or decrement.
7043 ??? Except that due to conceptual problems in offsettable_address_p
7044 we can't really report the problems of integral offsets. So leave
7045 this assuming that the adjustable offset must be valid for the
7046 sub-words of a TFmode operand, which is what we had before. */
7049 rs6000_mode_dependent_address (const_rtx addr)
7051 switch (GET_CODE (addr))
7054 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7055 is considered a legitimate address before reload, so there
7056 are no offset restrictions in that case. Note that this
7057 condition is safe in strict mode because any address involving
7058 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7059 been rejected as illegitimate. */
7060 if (XEXP (addr, 0) != virtual_stack_vars_rtx
7061 && XEXP (addr, 0) != arg_pointer_rtx
7062 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
7064 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
7065 return val + 12 + 0x8000 >= 0x10000;
7070 /* Anything in the constant pool is sufficiently aligned that
7071 all bytes have the same high part address. */
7072 return !legitimate_constant_pool_address_p (addr, QImode, false);
7074 /* Auto-increment cases are now treated generically in recog.c. */
7076 return TARGET_UPDATE;
7078 /* AND is only allowed in Altivec loads. */
7089 /* Debug version of rs6000_mode_dependent_address. */
7091 rs6000_debug_mode_dependent_address (const_rtx addr)
7093 bool ret = rs6000_mode_dependent_address (addr);
7095 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
7096 ret ? "true" : "false");
7102 /* Implement FIND_BASE_TERM. */
7105 rs6000_find_base_term (rtx op)
7109 split_const (op, &base, &offset);
7110 if (GET_CODE (base) == UNSPEC)
7111 switch (XINT (base, 1))
7114 case UNSPEC_MACHOPIC_OFFSET:
7115 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7116 for aliasing purposes. */
7117 return XVECEXP (base, 0, 0);
7123 /* More elaborate version of recog's offsettable_memref_p predicate
7124 that works around the ??? note of rs6000_mode_dependent_address.
7125 In particular it accepts
7127 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7129 in 32-bit mode, that the recog predicate rejects. */
7132 rs6000_offsettable_memref_p (rtx op)
7137 /* First mimic offsettable_memref_p. */
7138 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7141 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7142 the latter predicate knows nothing about the mode of the memory
7143 reference and, therefore, assumes that it is the largest supported
7144 mode (TFmode). As a consequence, legitimate offsettable memory
7145 references are rejected. rs6000_legitimate_offset_address_p contains
7146 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7147 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7150 /* Change register usage conditional on target flags. */
7152 rs6000_conditional_register_usage (void)
7156 if (TARGET_DEBUG_TARGET)
7157 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7159 /* Set MQ register fixed (already call_used) if not POWER
7160 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7165 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7167 fixed_regs[13] = call_used_regs[13]
7168 = call_really_used_regs[13] = 1;
7170 /* Conditionally disable FPRs. */
7171 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7172 for (i = 32; i < 64; i++)
7173 fixed_regs[i] = call_used_regs[i]
7174 = call_really_used_regs[i] = 1;
7176 /* The TOC register is not killed across calls in a way that is
7177 visible to the compiler. */
7178 if (DEFAULT_ABI == ABI_AIX)
7179 call_really_used_regs[2] = 0;
7181 if (DEFAULT_ABI == ABI_V4
7182 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7184 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7186 if (DEFAULT_ABI == ABI_V4
7187 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7189 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7190 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7191 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7193 if (DEFAULT_ABI == ABI_DARWIN
7194 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7195 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7196 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7197 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7199 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7200 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7201 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7205 global_regs[SPEFSCR_REGNO] = 1;
7206 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7207 registers in prologues and epilogues. We no longer use r14
7208 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7209 pool for link-compatibility with older versions of GCC. Once
7210 "old" code has died out, we can return r14 to the allocation
7213 = call_used_regs[14]
7214 = call_really_used_regs[14] = 1;
7217 if (!TARGET_ALTIVEC && !TARGET_VSX)
7219 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7220 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7221 call_really_used_regs[VRSAVE_REGNO] = 1;
7224 if (TARGET_ALTIVEC || TARGET_VSX)
7225 global_regs[VSCR_REGNO] = 1;
7227 if (TARGET_ALTIVEC_ABI)
7229 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7230 call_used_regs[i] = call_really_used_regs[i] = 1;
7232 /* AIX reserves VR20:31 in non-extended ABI mode. */
7234 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7235 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7239 /* Try to output insns to set TARGET equal to the constant C if it can
7240 be done in less than N insns. Do all computations in MODE.
7241 Returns the place where the output has been placed if it can be
7242 done and the insns have been emitted. If it would take more than N
7243 insns, zero is returned and no insns and emitted. */
7246 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7247 rtx source, int n ATTRIBUTE_UNUSED)
7249 rtx result, insn, set;
7250 HOST_WIDE_INT c0, c1;
7257 dest = gen_reg_rtx (mode);
7258 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7262 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7264 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7265 GEN_INT (INTVAL (source)
7266 & (~ (HOST_WIDE_INT) 0xffff))));
7267 emit_insn (gen_rtx_SET (VOIDmode, dest,
7268 gen_rtx_IOR (SImode, copy_rtx (result),
7269 GEN_INT (INTVAL (source) & 0xffff))));
7274 switch (GET_CODE (source))
7277 c0 = INTVAL (source);
7282 #if HOST_BITS_PER_WIDE_INT >= 64
7283 c0 = CONST_DOUBLE_LOW (source);
7286 c0 = CONST_DOUBLE_LOW (source);
7287 c1 = CONST_DOUBLE_HIGH (source);
7295 result = rs6000_emit_set_long_const (dest, c0, c1);
7302 insn = get_last_insn ();
7303 set = single_set (insn);
7304 if (! CONSTANT_P (SET_SRC (set)))
7305 set_unique_reg_note (insn, REG_EQUAL, source);
7310 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7311 fall back to a straight forward decomposition. We do this to avoid
7312 exponential run times encountered when looking for longer sequences
7313 with rs6000_emit_set_const. */
7315 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7317 if (!TARGET_POWERPC64)
7319 rtx operand1, operand2;
7321 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7323 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7325 emit_move_insn (operand1, GEN_INT (c1));
7326 emit_move_insn (operand2, GEN_INT (c2));
7330 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7333 ud2 = (c1 & 0xffff0000) >> 16;
7334 #if HOST_BITS_PER_WIDE_INT >= 64
7338 ud4 = (c2 & 0xffff0000) >> 16;
7340 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7341 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7344 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7346 emit_move_insn (dest, GEN_INT (ud1));
7349 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7350 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7353 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7356 emit_move_insn (dest, GEN_INT (ud2 << 16));
7358 emit_move_insn (copy_rtx (dest),
7359 gen_rtx_IOR (DImode, copy_rtx (dest),
7362 else if (ud3 == 0 && ud4 == 0)
7364 gcc_assert (ud2 & 0x8000);
7365 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7368 emit_move_insn (copy_rtx (dest),
7369 gen_rtx_IOR (DImode, copy_rtx (dest),
7371 emit_move_insn (copy_rtx (dest),
7372 gen_rtx_ZERO_EXTEND (DImode,
7373 gen_lowpart (SImode,
7376 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7377 || (ud4 == 0 && ! (ud3 & 0x8000)))
7380 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7383 emit_move_insn (dest, GEN_INT (ud3 << 16));
7386 emit_move_insn (copy_rtx (dest),
7387 gen_rtx_IOR (DImode, copy_rtx (dest),
7389 emit_move_insn (copy_rtx (dest),
7390 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7393 emit_move_insn (copy_rtx (dest),
7394 gen_rtx_IOR (DImode, copy_rtx (dest),
7400 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7403 emit_move_insn (dest, GEN_INT (ud4 << 16));
7406 emit_move_insn (copy_rtx (dest),
7407 gen_rtx_IOR (DImode, copy_rtx (dest),
7410 emit_move_insn (copy_rtx (dest),
7411 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7414 emit_move_insn (copy_rtx (dest),
7415 gen_rtx_IOR (DImode, copy_rtx (dest),
7416 GEN_INT (ud2 << 16)));
7418 emit_move_insn (copy_rtx (dest),
7419 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7425 /* Helper for the following. Get rid of [r+r] memory refs
7426 in cases where it won't work (TImode, TFmode, TDmode). */
7429 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7431 if (reload_in_progress)
7434 if (GET_CODE (operands[0]) == MEM
7435 && GET_CODE (XEXP (operands[0], 0)) != REG
7436 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7437 GET_MODE (operands[0]), false))
7439 = replace_equiv_address (operands[0],
7440 copy_addr_to_reg (XEXP (operands[0], 0)));
7442 if (GET_CODE (operands[1]) == MEM
7443 && GET_CODE (XEXP (operands[1], 0)) != REG
7444 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7445 GET_MODE (operands[1]), false))
7447 = replace_equiv_address (operands[1],
7448 copy_addr_to_reg (XEXP (operands[1], 0)));
7451 /* Emit a move from SOURCE to DEST in mode MODE. */
7453 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7457 operands[1] = source;
7459 if (TARGET_DEBUG_ADDR)
7462 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7463 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7464 GET_MODE_NAME (mode),
7467 can_create_pseudo_p ());
7469 fprintf (stderr, "source:\n");
7473 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7474 if (GET_CODE (operands[1]) == CONST_DOUBLE
7475 && ! FLOAT_MODE_P (mode)
7476 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7478 /* FIXME. This should never happen. */
7479 /* Since it seems that it does, do the safe thing and convert
7481 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7483 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7484 || FLOAT_MODE_P (mode)
7485 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7486 || CONST_DOUBLE_LOW (operands[1]) < 0)
7487 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7488 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7490 /* Check if GCC is setting up a block move that will end up using FP
7491 registers as temporaries. We must make sure this is acceptable. */
7492 if (GET_CODE (operands[0]) == MEM
7493 && GET_CODE (operands[1]) == MEM
7495 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7496 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7497 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7498 ? 32 : MEM_ALIGN (operands[0])))
7499 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7501 : MEM_ALIGN (operands[1]))))
7502 && ! MEM_VOLATILE_P (operands [0])
7503 && ! MEM_VOLATILE_P (operands [1]))
7505 emit_move_insn (adjust_address (operands[0], SImode, 0),
7506 adjust_address (operands[1], SImode, 0));
7507 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7508 adjust_address (copy_rtx (operands[1]), SImode, 4));
7512 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7513 && !gpc_reg_operand (operands[1], mode))
7514 operands[1] = force_reg (mode, operands[1]);
7516 if (mode == SFmode && ! TARGET_POWERPC
7517 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7518 && GET_CODE (operands[0]) == MEM)
7522 if (reload_in_progress || reload_completed)
7523 regnum = true_regnum (operands[1]);
7524 else if (GET_CODE (operands[1]) == REG)
7525 regnum = REGNO (operands[1]);
7529 /* If operands[1] is a register, on POWER it may have
7530 double-precision data in it, so truncate it to single
7532 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7535 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7536 : gen_reg_rtx (mode));
7537 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7538 operands[1] = newreg;
7542 /* Recognize the case where operand[1] is a reference to thread-local
7543 data and load its address to a register. */
7544 if (rs6000_tls_referenced_p (operands[1]))
7546 enum tls_model model;
7547 rtx tmp = operands[1];
7550 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7552 addend = XEXP (XEXP (tmp, 0), 1);
7553 tmp = XEXP (XEXP (tmp, 0), 0);
7556 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7557 model = SYMBOL_REF_TLS_MODEL (tmp);
7558 gcc_assert (model != 0);
7560 tmp = rs6000_legitimize_tls_address (tmp, model);
7563 tmp = gen_rtx_PLUS (mode, tmp, addend);
7564 tmp = force_operand (tmp, operands[0]);
7569 /* Handle the case where reload calls us with an invalid address. */
7570 if (reload_in_progress && mode == Pmode
7571 && (! general_operand (operands[1], mode)
7572 || ! nonimmediate_operand (operands[0], mode)))
7575 /* 128-bit constant floating-point values on Darwin should really be
7576 loaded as two parts. */
7577 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7578 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7580 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7581 know how to get a DFmode SUBREG of a TFmode. */
7582 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7583 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7584 simplify_gen_subreg (imode, operands[1], mode, 0),
7586 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7587 GET_MODE_SIZE (imode)),
7588 simplify_gen_subreg (imode, operands[1], mode,
7589 GET_MODE_SIZE (imode)),
7594 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7595 cfun->machine->sdmode_stack_slot =
7596 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7598 if (reload_in_progress
7600 && MEM_P (operands[0])
7601 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7602 && REG_P (operands[1]))
7604 if (FP_REGNO_P (REGNO (operands[1])))
7606 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7607 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7608 emit_insn (gen_movsd_store (mem, operands[1]));
7610 else if (INT_REGNO_P (REGNO (operands[1])))
7612 rtx mem = adjust_address_nv (operands[0], mode, 4);
7613 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7614 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7620 if (reload_in_progress
7622 && REG_P (operands[0])
7623 && MEM_P (operands[1])
7624 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7626 if (FP_REGNO_P (REGNO (operands[0])))
7628 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7629 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7630 emit_insn (gen_movsd_load (operands[0], mem));
7632 else if (INT_REGNO_P (REGNO (operands[0])))
7634 rtx mem = adjust_address_nv (operands[1], mode, 4);
7635 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7636 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7643 /* FIXME: In the long term, this switch statement should go away
7644 and be replaced by a sequence of tests based on things like
7650 if (CONSTANT_P (operands[1])
7651 && GET_CODE (operands[1]) != CONST_INT)
7652 operands[1] = force_const_mem (mode, operands[1]);
7657 rs6000_eliminate_indexed_memrefs (operands);
7664 if (CONSTANT_P (operands[1])
7665 && ! easy_fp_constant (operands[1], mode))
7666 operands[1] = force_const_mem (mode, operands[1]);
7679 if (CONSTANT_P (operands[1])
7680 && !easy_vector_constant (operands[1], mode))
7681 operands[1] = force_const_mem (mode, operands[1]);
7686 /* Use default pattern for address of ELF small data */
7689 && DEFAULT_ABI == ABI_V4
7690 && (GET_CODE (operands[1]) == SYMBOL_REF
7691 || GET_CODE (operands[1]) == CONST)
7692 && small_data_operand (operands[1], mode))
7694 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7698 if (DEFAULT_ABI == ABI_V4
7699 && mode == Pmode && mode == SImode
7700 && flag_pic == 1 && got_operand (operands[1], mode))
7702 emit_insn (gen_movsi_got (operands[0], operands[1]));
7706 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7710 && CONSTANT_P (operands[1])
7711 && GET_CODE (operands[1]) != HIGH
7712 && GET_CODE (operands[1]) != CONST_INT)
7714 rtx target = (!can_create_pseudo_p ()
7716 : gen_reg_rtx (mode));
7718 /* If this is a function address on -mcall-aixdesc,
7719 convert it to the address of the descriptor. */
7720 if (DEFAULT_ABI == ABI_AIX
7721 && GET_CODE (operands[1]) == SYMBOL_REF
7722 && XSTR (operands[1], 0)[0] == '.')
7724 const char *name = XSTR (operands[1], 0);
7726 while (*name == '.')
7728 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7729 CONSTANT_POOL_ADDRESS_P (new_ref)
7730 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7731 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7732 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7733 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7734 operands[1] = new_ref;
7737 if (DEFAULT_ABI == ABI_DARWIN)
7740 if (MACHO_DYNAMIC_NO_PIC_P)
7742 /* Take care of any required data indirection. */
7743 operands[1] = rs6000_machopic_legitimize_pic_address (
7744 operands[1], mode, operands[0]);
7745 if (operands[0] != operands[1])
7746 emit_insn (gen_rtx_SET (VOIDmode,
7747 operands[0], operands[1]));
7751 emit_insn (gen_macho_high (target, operands[1]));
7752 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7756 emit_insn (gen_elf_high (target, operands[1]));
7757 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7761 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7762 and we have put it in the TOC, we just need to make a TOC-relative
7765 && GET_CODE (operands[1]) == SYMBOL_REF
7766 && constant_pool_expr_p (operands[1])
7767 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7768 get_pool_mode (operands[1])))
7769 || (TARGET_CMODEL == CMODEL_MEDIUM
7770 && GET_CODE (operands[1]) == SYMBOL_REF
7771 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7772 && SYMBOL_REF_LOCAL_P (operands[1])))
7775 if (TARGET_CMODEL != CMODEL_SMALL)
7777 if (can_create_pseudo_p ())
7778 reg = gen_reg_rtx (Pmode);
7782 operands[1] = create_TOC_reference (operands[1], reg);
7784 else if (mode == Pmode
7785 && CONSTANT_P (operands[1])
7786 && ((GET_CODE (operands[1]) != CONST_INT
7787 && ! easy_fp_constant (operands[1], mode))
7788 || (GET_CODE (operands[1]) == CONST_INT
7789 && (num_insns_constant (operands[1], mode)
7790 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7791 || (GET_CODE (operands[0]) == REG
7792 && FP_REGNO_P (REGNO (operands[0]))))
7793 && GET_CODE (operands[1]) != HIGH
7794 && ! legitimate_constant_pool_address_p (operands[1], mode,
7796 && ! toc_relative_expr_p (operands[1])
7797 && (TARGET_CMODEL == CMODEL_SMALL
7798 || can_create_pseudo_p ()
7799 || (REG_P (operands[0])
7800 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7804 /* Darwin uses a special PIC legitimizer. */
7805 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7808 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7810 if (operands[0] != operands[1])
7811 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7816 /* If we are to limit the number of things we put in the TOC and
7817 this is a symbol plus a constant we can add in one insn,
7818 just put the symbol in the TOC and add the constant. Don't do
7819 this if reload is in progress. */
7820 if (GET_CODE (operands[1]) == CONST
7821 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7822 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7823 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7824 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7825 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7826 && ! side_effects_p (operands[0]))
7829 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7830 rtx other = XEXP (XEXP (operands[1], 0), 1);
7832 sym = force_reg (mode, sym);
7833 emit_insn (gen_add3_insn (operands[0], sym, other));
7837 operands[1] = force_const_mem (mode, operands[1]);
7840 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7841 && constant_pool_expr_p (XEXP (operands[1], 0))
7842 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7843 get_pool_constant (XEXP (operands[1], 0)),
7844 get_pool_mode (XEXP (operands[1], 0))))
7848 if (TARGET_CMODEL != CMODEL_SMALL)
7850 if (can_create_pseudo_p ())
7851 reg = gen_reg_rtx (Pmode);
7855 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7856 operands[1] = gen_const_mem (mode, tocref);
7857 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7863 rs6000_eliminate_indexed_memrefs (operands);
7867 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7869 gen_rtx_SET (VOIDmode,
7870 operands[0], operands[1]),
7871 gen_rtx_CLOBBER (VOIDmode,
7872 gen_rtx_SCRATCH (SImode)))));
7878 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7881 /* Above, we may have called force_const_mem which may have returned
7882 an invalid address. If we can, fix this up; otherwise, reload will
7883 have to deal with it. */
7884 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7885 operands[1] = validize_mem (operands[1]);
7888 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7891 /* Nonzero if we can use a floating-point register to pass this arg. */
7892 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7893 (SCALAR_FLOAT_MODE_P (MODE) \
7894 && (CUM)->fregno <= FP_ARG_MAX_REG \
7895 && TARGET_HARD_FLOAT && TARGET_FPRS)
7897 /* Nonzero if we can use an AltiVec register to pass this arg. */
7898 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7899 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7900 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7901 && TARGET_ALTIVEC_ABI \
7904 /* Return a nonzero value to say to return the function value in
7905 memory, just as large structures are always returned. TYPE will be
7906 the data type of the value, and FNTYPE will be the type of the
7907 function doing the returning, or @code{NULL} for libcalls.
7909 The AIX ABI for the RS/6000 specifies that all structures are
7910 returned in memory. The Darwin ABI does the same.
7912 For the Darwin 64 Bit ABI, a function result can be returned in
7913 registers or in memory, depending on the size of the return data
7914 type. If it is returned in registers, the value occupies the same
7915 registers as it would if it were the first and only function
7916 argument. Otherwise, the function places its result in memory at
7917 the location pointed to by GPR3.
7919 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7920 but a draft put them in memory, and GCC used to implement the draft
7921 instead of the final standard. Therefore, aix_struct_return
7922 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7923 compatibility can change DRAFT_V4_STRUCT_RET to override the
7924 default, and -m switches get the final word. See
7925 rs6000_option_override_internal for more details.
7927 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7928 long double support is enabled. These values are returned in memory.
7930 int_size_in_bytes returns -1 for variable size objects, which go in
7931 memory always. The cast to unsigned makes -1 > 8. */
7934 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7936 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7938 && rs6000_darwin64_abi
7939 && TREE_CODE (type) == RECORD_TYPE
7940 && int_size_in_bytes (type) > 0)
7942 CUMULATIVE_ARGS valcum;
7946 valcum.fregno = FP_ARG_MIN_REG;
7947 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7948 /* Do a trial code generation as if this were going to be passed
7949 as an argument; if any part goes in memory, we return NULL. */
7950 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7953 /* Otherwise fall through to more conventional ABI rules. */
7956 if (AGGREGATE_TYPE_P (type)
7957 && (aix_struct_return
7958 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7961 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7962 modes only exist for GCC vector types if -maltivec. */
7963 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7964 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7967 /* Return synthetic vectors in memory. */
7968 if (TREE_CODE (type) == VECTOR_TYPE
7969 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7971 static bool warned_for_return_big_vectors = false;
7972 if (!warned_for_return_big_vectors)
7974 warning (0, "GCC vector returned by reference: "
7975 "non-standard ABI extension with no compatibility guarantee");
7976 warned_for_return_big_vectors = true;
7981 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7987 #ifdef HAVE_AS_GNU_ATTRIBUTE
7988 /* Return TRUE if a call to function FNDECL may be one that
7989 potentially affects the function calling ABI of the object file. */
7992 call_ABI_of_interest (tree fndecl)
7994 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7996 struct cgraph_node *c_node;
7998 /* Libcalls are always interesting. */
7999 if (fndecl == NULL_TREE)
8002 /* Any call to an external function is interesting. */
8003 if (DECL_EXTERNAL (fndecl))
8006 /* Interesting functions that we are emitting in this object file. */
8007 c_node = cgraph_node (fndecl);
8008 return !cgraph_only_called_directly_p (c_node);
8014 /* Initialize a variable CUM of type CUMULATIVE_ARGS
8015 for a call to a function whose data type is FNTYPE.
8016 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
8018 For incoming args we set the number of arguments in the prototype large
8019 so we never return a PARALLEL. */
8022 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
8023 rtx libname ATTRIBUTE_UNUSED, int incoming,
8024 int libcall, int n_named_args,
8025 tree fndecl ATTRIBUTE_UNUSED,
8026 enum machine_mode return_mode ATTRIBUTE_UNUSED)
8028 static CUMULATIVE_ARGS zero_cumulative;
8030 *cum = zero_cumulative;
8032 cum->fregno = FP_ARG_MIN_REG;
8033 cum->vregno = ALTIVEC_ARG_MIN_REG;
8034 cum->prototype = (fntype && prototype_p (fntype));
8035 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
8036 ? CALL_LIBCALL : CALL_NORMAL);
8037 cum->sysv_gregno = GP_ARG_MIN_REG;
8038 cum->stdarg = stdarg_p (fntype);
8040 cum->nargs_prototype = 0;
8041 if (incoming || cum->prototype)
8042 cum->nargs_prototype = n_named_args;
8044 /* Check for a longcall attribute. */
8045 if ((!fntype && rs6000_default_long_calls)
8047 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
8048 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
8049 cum->call_cookie |= CALL_LONG;
8051 if (TARGET_DEBUG_ARG)
8053 fprintf (stderr, "\ninit_cumulative_args:");
8056 tree ret_type = TREE_TYPE (fntype);
8057 fprintf (stderr, " ret code = %s,",
8058 tree_code_name[ (int)TREE_CODE (ret_type) ]);
8061 if (cum->call_cookie & CALL_LONG)
8062 fprintf (stderr, " longcall,");
8064 fprintf (stderr, " proto = %d, nargs = %d\n",
8065 cum->prototype, cum->nargs_prototype);
8068 #ifdef HAVE_AS_GNU_ATTRIBUTE
8069 if (DEFAULT_ABI == ABI_V4)
8071 cum->escapes = call_ABI_of_interest (fndecl);
8078 return_type = TREE_TYPE (fntype);
8079 return_mode = TYPE_MODE (return_type);
8082 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8084 if (return_type != NULL)
8086 if (TREE_CODE (return_type) == RECORD_TYPE
8087 && TYPE_TRANSPARENT_AGGR (return_type))
8089 return_type = TREE_TYPE (first_field (return_type));
8090 return_mode = TYPE_MODE (return_type);
8092 if (AGGREGATE_TYPE_P (return_type)
8093 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8095 rs6000_returns_struct = true;
8097 if (SCALAR_FLOAT_MODE_P (return_mode))
8098 rs6000_passes_float = true;
8099 else if (ALTIVEC_VECTOR_MODE (return_mode)
8100 || VSX_VECTOR_MODE (return_mode)
8101 || SPE_VECTOR_MODE (return_mode))
8102 rs6000_passes_vector = true;
8109 && TARGET_ALTIVEC_ABI
8110 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8112 error ("cannot return value in vector register because"
8113 " altivec instructions are disabled, use -maltivec"
8118 /* Return true if TYPE must be passed on the stack and not in registers. */
8121 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8123 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8124 return must_pass_in_stack_var_size (mode, type);
8126 return must_pass_in_stack_var_size_or_pad (mode, type);
8129 /* If defined, a C expression which determines whether, and in which
8130 direction, to pad out an argument with extra space. The value
8131 should be of type `enum direction': either `upward' to pad above
8132 the argument, `downward' to pad below, or `none' to inhibit
8135 For the AIX ABI structs are always stored left shifted in their
8139 function_arg_padding (enum machine_mode mode, const_tree type)
8141 #ifndef AGGREGATE_PADDING_FIXED
8142 #define AGGREGATE_PADDING_FIXED 0
8144 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8145 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8148 if (!AGGREGATE_PADDING_FIXED)
8150 /* GCC used to pass structures of the same size as integer types as
8151 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8152 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8153 passed padded downward, except that -mstrict-align further
8154 muddied the water in that multi-component structures of 2 and 4
8155 bytes in size were passed padded upward.
8157 The following arranges for best compatibility with previous
8158 versions of gcc, but removes the -mstrict-align dependency. */
8159 if (BYTES_BIG_ENDIAN)
8161 HOST_WIDE_INT size = 0;
8163 if (mode == BLKmode)
8165 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8166 size = int_size_in_bytes (type);
8169 size = GET_MODE_SIZE (mode);
8171 if (size == 1 || size == 2 || size == 4)
8177 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8179 if (type != 0 && AGGREGATE_TYPE_P (type))
8183 /* Fall back to the default. */
8184 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8187 /* If defined, a C expression that gives the alignment boundary, in bits,
8188 of an argument with the specified mode and type. If it is not defined,
8189 PARM_BOUNDARY is used for all arguments.
8191 V.4 wants long longs and doubles to be double word aligned. Just
8192 testing the mode size is a boneheaded way to do this as it means
8193 that other types such as complex int are also double word aligned.
8194 However, we're stuck with this because changing the ABI might break
8195 existing library interfaces.
8197 Doubleword align SPE vectors.
8198 Quadword align Altivec vectors.
8199 Quadword align large synthetic vector types. */
8202 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8204 if (DEFAULT_ABI == ABI_V4
8205 && (GET_MODE_SIZE (mode) == 8
8206 || (TARGET_HARD_FLOAT
8208 && (mode == TFmode || mode == TDmode))))
8210 else if (SPE_VECTOR_MODE (mode)
8211 || (type && TREE_CODE (type) == VECTOR_TYPE
8212 && int_size_in_bytes (type) >= 8
8213 && int_size_in_bytes (type) < 16))
8215 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8216 || (type && TREE_CODE (type) == VECTOR_TYPE
8217 && int_size_in_bytes (type) >= 16))
8219 else if (TARGET_MACHO
8220 && rs6000_darwin64_abi
8222 && type && TYPE_ALIGN (type) > 64)
8225 return PARM_BOUNDARY;
8228 /* For a function parm of MODE and TYPE, return the starting word in
8229 the parameter area. NWORDS of the parameter area are already used. */
8232 rs6000_parm_start (enum machine_mode mode, const_tree type,
8233 unsigned int nwords)
8236 unsigned int parm_offset;
8238 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8239 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8240 return nwords + (-(parm_offset + nwords) & align);
8243 /* Compute the size (in words) of a function argument. */
8245 static unsigned long
8246 rs6000_arg_size (enum machine_mode mode, const_tree type)
8250 if (mode != BLKmode)
8251 size = GET_MODE_SIZE (mode);
8253 size = int_size_in_bytes (type);
8256 return (size + 3) >> 2;
8258 return (size + 7) >> 3;
8261 /* Use this to flush pending int fields. */
8264 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8265 HOST_WIDE_INT bitpos, int final)
8267 unsigned int startbit, endbit;
8268 int intregs, intoffset;
8269 enum machine_mode mode;
8271 /* Handle the situations where a float is taking up the first half
8272 of the GPR, and the other half is empty (typically due to
8273 alignment restrictions). We can detect this by a 8-byte-aligned
8274 int field, or by seeing that this is the final flush for this
8275 argument. Count the word and continue on. */
8276 if (cum->floats_in_gpr == 1
8277 && (cum->intoffset % 64 == 0
8278 || (cum->intoffset == -1 && final)))
8281 cum->floats_in_gpr = 0;
8284 if (cum->intoffset == -1)
8287 intoffset = cum->intoffset;
8288 cum->intoffset = -1;
8289 cum->floats_in_gpr = 0;
8291 if (intoffset % BITS_PER_WORD != 0)
8293 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8295 if (mode == BLKmode)
8297 /* We couldn't find an appropriate mode, which happens,
8298 e.g., in packed structs when there are 3 bytes to load.
8299 Back intoffset back to the beginning of the word in this
8301 intoffset = intoffset & -BITS_PER_WORD;
8305 startbit = intoffset & -BITS_PER_WORD;
8306 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8307 intregs = (endbit - startbit) / BITS_PER_WORD;
8308 cum->words += intregs;
8309 /* words should be unsigned. */
8310 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8312 int pad = (endbit/BITS_PER_WORD) - cum->words;
8317 /* The darwin64 ABI calls for us to recurse down through structs,
8318 looking for elements passed in registers. Unfortunately, we have
8319 to track int register count here also because of misalignments
8320 in powerpc alignment mode. */
8323 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8325 HOST_WIDE_INT startbitpos)
8329 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8330 if (TREE_CODE (f) == FIELD_DECL)
8332 HOST_WIDE_INT bitpos = startbitpos;
8333 tree ftype = TREE_TYPE (f);
8334 enum machine_mode mode;
8335 if (ftype == error_mark_node)
8337 mode = TYPE_MODE (ftype);
8339 if (DECL_SIZE (f) != 0
8340 && host_integerp (bit_position (f), 1))
8341 bitpos += int_bit_position (f);
8343 /* ??? FIXME: else assume zero offset. */
8345 if (TREE_CODE (ftype) == RECORD_TYPE)
8346 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8347 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8349 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8350 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8351 cum->fregno += n_fpregs;
8352 /* Single-precision floats present a special problem for
8353 us, because they are smaller than an 8-byte GPR, and so
8354 the structure-packing rules combined with the standard
8355 varargs behavior mean that we want to pack float/float
8356 and float/int combinations into a single register's
8357 space. This is complicated by the arg advance flushing,
8358 which works on arbitrarily large groups of int-type
8362 if (cum->floats_in_gpr == 1)
8364 /* Two floats in a word; count the word and reset
8367 cum->floats_in_gpr = 0;
8369 else if (bitpos % 64 == 0)
8371 /* A float at the beginning of an 8-byte word;
8372 count it and put off adjusting cum->words until
8373 we see if a arg advance flush is going to do it
8375 cum->floats_in_gpr++;
8379 /* The float is at the end of a word, preceded
8380 by integer fields, so the arg advance flush
8381 just above has already set cum->words and
8382 everything is taken care of. */
8386 cum->words += n_fpregs;
8388 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8390 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8394 else if (cum->intoffset == -1)
8395 cum->intoffset = bitpos;
8399 /* Check for an item that needs to be considered specially under the darwin 64
8400 bit ABI. These are record types where the mode is BLK or the structure is
8403 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8405 return rs6000_darwin64_abi
8406 && ((mode == BLKmode
8407 && TREE_CODE (type) == RECORD_TYPE
8408 && int_size_in_bytes (type) > 0)
8409 || (type && TREE_CODE (type) == RECORD_TYPE
8410 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8413 /* Update the data in CUM to advance over an argument
8414 of mode MODE and data type TYPE.
8415 (TYPE is null for libcalls where that information may not be available.)
8417 Note that for args passed by reference, function_arg will be called
8418 with MODE and TYPE set to that of the pointer to the arg, not the arg
8422 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8423 const_tree type, bool named, int depth)
8425 /* Only tick off an argument if we're not recursing. */
8427 cum->nargs_prototype--;
8429 #ifdef HAVE_AS_GNU_ATTRIBUTE
8430 if (DEFAULT_ABI == ABI_V4
8433 if (SCALAR_FLOAT_MODE_P (mode))
8434 rs6000_passes_float = true;
8435 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8436 rs6000_passes_vector = true;
8437 else if (SPE_VECTOR_MODE (mode)
8439 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8440 rs6000_passes_vector = true;
8444 if (TARGET_ALTIVEC_ABI
8445 && (ALTIVEC_VECTOR_MODE (mode)
8446 || VSX_VECTOR_MODE (mode)
8447 || (type && TREE_CODE (type) == VECTOR_TYPE
8448 && int_size_in_bytes (type) == 16)))
8452 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8455 if (!TARGET_ALTIVEC)
8456 error ("cannot pass argument in vector register because"
8457 " altivec instructions are disabled, use -maltivec"
8460 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8461 even if it is going to be passed in a vector register.
8462 Darwin does the same for variable-argument functions. */
8463 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8464 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8474 /* Vector parameters must be 16-byte aligned. This places
8475 them at 2 mod 4 in terms of words in 32-bit mode, since
8476 the parameter save area starts at offset 24 from the
8477 stack. In 64-bit mode, they just have to start on an
8478 even word, since the parameter save area is 16-byte
8479 aligned. Space for GPRs is reserved even if the argument
8480 will be passed in memory. */
8482 align = (2 - cum->words) & 3;
8484 align = cum->words & 1;
8485 cum->words += align + rs6000_arg_size (mode, type);
8487 if (TARGET_DEBUG_ARG)
8489 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8491 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8492 cum->nargs_prototype, cum->prototype,
8493 GET_MODE_NAME (mode));
8497 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8499 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8502 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8504 int size = int_size_in_bytes (type);
8505 /* Variable sized types have size == -1 and are
8506 treated as if consisting entirely of ints.
8507 Pad to 16 byte boundary if needed. */
8508 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8509 && (cum->words % 2) != 0)
8511 /* For varargs, we can just go up by the size of the struct. */
8513 cum->words += (size + 7) / 8;
8516 /* It is tempting to say int register count just goes up by
8517 sizeof(type)/8, but this is wrong in a case such as
8518 { int; double; int; } [powerpc alignment]. We have to
8519 grovel through the fields for these too. */
8521 cum->floats_in_gpr = 0;
8522 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8523 rs6000_darwin64_record_arg_advance_flush (cum,
8524 size * BITS_PER_UNIT, 1);
8526 if (TARGET_DEBUG_ARG)
8528 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8529 cum->words, TYPE_ALIGN (type), size);
8531 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8532 cum->nargs_prototype, cum->prototype,
8533 GET_MODE_NAME (mode));
8536 else if (DEFAULT_ABI == ABI_V4)
8538 if (TARGET_HARD_FLOAT && TARGET_FPRS
8539 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8540 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8541 || (mode == TFmode && !TARGET_IEEEQUAD)
8542 || mode == SDmode || mode == DDmode || mode == TDmode))
8544 /* _Decimal128 must use an even/odd register pair. This assumes
8545 that the register number is odd when fregno is odd. */
8546 if (mode == TDmode && (cum->fregno % 2) == 1)
8549 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8550 <= FP_ARG_V4_MAX_REG)
8551 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8554 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8555 if (mode == DFmode || mode == TFmode
8556 || mode == DDmode || mode == TDmode)
8557 cum->words += cum->words & 1;
8558 cum->words += rs6000_arg_size (mode, type);
8563 int n_words = rs6000_arg_size (mode, type);
8564 int gregno = cum->sysv_gregno;
8566 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8567 (r7,r8) or (r9,r10). As does any other 2 word item such
8568 as complex int due to a historical mistake. */
8570 gregno += (1 - gregno) & 1;
8572 /* Multi-reg args are not split between registers and stack. */
8573 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8575 /* Long long and SPE vectors are aligned on the stack.
8576 So are other 2 word items such as complex int due to
8577 a historical mistake. */
8579 cum->words += cum->words & 1;
8580 cum->words += n_words;
8583 /* Note: continuing to accumulate gregno past when we've started
8584 spilling to the stack indicates the fact that we've started
8585 spilling to the stack to expand_builtin_saveregs. */
8586 cum->sysv_gregno = gregno + n_words;
8589 if (TARGET_DEBUG_ARG)
8591 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8592 cum->words, cum->fregno);
8593 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8594 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8595 fprintf (stderr, "mode = %4s, named = %d\n",
8596 GET_MODE_NAME (mode), named);
8601 int n_words = rs6000_arg_size (mode, type);
8602 int start_words = cum->words;
8603 int align_words = rs6000_parm_start (mode, type, start_words);
8605 cum->words = align_words + n_words;
8607 if (SCALAR_FLOAT_MODE_P (mode)
8608 && TARGET_HARD_FLOAT && TARGET_FPRS)
8610 /* _Decimal128 must be passed in an even/odd float register pair.
8611 This assumes that the register number is odd when fregno is
8613 if (mode == TDmode && (cum->fregno % 2) == 1)
8615 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8618 if (TARGET_DEBUG_ARG)
8620 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8621 cum->words, cum->fregno);
8622 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8623 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8624 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8625 named, align_words - start_words, depth);
8631 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8632 const_tree type, bool named)
8634 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8638 spe_build_register_parallel (enum machine_mode mode, int gregno)
8645 r1 = gen_rtx_REG (DImode, gregno);
8646 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8647 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8651 r1 = gen_rtx_REG (DImode, gregno);
8652 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8653 r3 = gen_rtx_REG (DImode, gregno + 2);
8654 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8655 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8658 r1 = gen_rtx_REG (DImode, gregno);
8659 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8660 r3 = gen_rtx_REG (DImode, gregno + 2);
8661 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8662 r5 = gen_rtx_REG (DImode, gregno + 4);
8663 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8664 r7 = gen_rtx_REG (DImode, gregno + 6);
8665 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8666 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8673 /* Determine where to put a SIMD argument on the SPE. */
8675 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8678 int gregno = cum->sysv_gregno;
8680 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8681 are passed and returned in a pair of GPRs for ABI compatibility. */
8682 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8683 || mode == DCmode || mode == TCmode))
8685 int n_words = rs6000_arg_size (mode, type);
8687 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8689 gregno += (1 - gregno) & 1;
8691 /* Multi-reg args are not split between registers and stack. */
8692 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8695 return spe_build_register_parallel (mode, gregno);
8699 int n_words = rs6000_arg_size (mode, type);
8701 /* SPE vectors are put in odd registers. */
8702 if (n_words == 2 && (gregno & 1) == 0)
8705 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8708 enum machine_mode m = SImode;
8710 r1 = gen_rtx_REG (m, gregno);
8711 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8712 r2 = gen_rtx_REG (m, gregno + 1);
8713 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8714 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8721 if (gregno <= GP_ARG_MAX_REG)
8722 return gen_rtx_REG (mode, gregno);
8728 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8729 structure between cum->intoffset and bitpos to integer registers. */
8732 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8733 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8735 enum machine_mode mode;
8737 unsigned int startbit, endbit;
8738 int this_regno, intregs, intoffset;
8741 if (cum->intoffset == -1)
8744 intoffset = cum->intoffset;
8745 cum->intoffset = -1;
8747 /* If this is the trailing part of a word, try to only load that
8748 much into the register. Otherwise load the whole register. Note
8749 that in the latter case we may pick up unwanted bits. It's not a
8750 problem at the moment but may wish to revisit. */
8752 if (intoffset % BITS_PER_WORD != 0)
8754 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8756 if (mode == BLKmode)
8758 /* We couldn't find an appropriate mode, which happens,
8759 e.g., in packed structs when there are 3 bytes to load.
8760 Back intoffset back to the beginning of the word in this
8762 intoffset = intoffset & -BITS_PER_WORD;
8769 startbit = intoffset & -BITS_PER_WORD;
8770 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8771 intregs = (endbit - startbit) / BITS_PER_WORD;
8772 this_regno = cum->words + intoffset / BITS_PER_WORD;
8774 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8777 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8781 intoffset /= BITS_PER_UNIT;
8784 regno = GP_ARG_MIN_REG + this_regno;
8785 reg = gen_rtx_REG (mode, regno);
8787 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8790 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8794 while (intregs > 0);
8797 /* Recursive workhorse for the following. */
8800 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8801 HOST_WIDE_INT startbitpos, rtx rvec[],
8806 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8807 if (TREE_CODE (f) == FIELD_DECL)
8809 HOST_WIDE_INT bitpos = startbitpos;
8810 tree ftype = TREE_TYPE (f);
8811 enum machine_mode mode;
8812 if (ftype == error_mark_node)
8814 mode = TYPE_MODE (ftype);
8816 if (DECL_SIZE (f) != 0
8817 && host_integerp (bit_position (f), 1))
8818 bitpos += int_bit_position (f);
8820 /* ??? FIXME: else assume zero offset. */
8822 if (TREE_CODE (ftype) == RECORD_TYPE)
8823 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8824 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8826 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8830 case SCmode: mode = SFmode; break;
8831 case DCmode: mode = DFmode; break;
8832 case TCmode: mode = TFmode; break;
8836 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8837 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8839 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8840 && (mode == TFmode || mode == TDmode));
8841 /* Long double or _Decimal128 split over regs and memory. */
8842 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8846 = gen_rtx_EXPR_LIST (VOIDmode,
8847 gen_rtx_REG (mode, cum->fregno++),
8848 GEN_INT (bitpos / BITS_PER_UNIT));
8849 if (mode == TFmode || mode == TDmode)
8852 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8854 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8856 = gen_rtx_EXPR_LIST (VOIDmode,
8857 gen_rtx_REG (mode, cum->vregno++),
8858 GEN_INT (bitpos / BITS_PER_UNIT));
8860 else if (cum->intoffset == -1)
8861 cum->intoffset = bitpos;
8865 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8866 the register(s) to be used for each field and subfield of a struct
8867 being passed by value, along with the offset of where the
8868 register's value may be found in the block. FP fields go in FP
8869 register, vector fields go in vector registers, and everything
8870 else goes in int registers, packed as in memory.
8872 This code is also used for function return values. RETVAL indicates
8873 whether this is the case.
8875 Much of this is taken from the SPARC V9 port, which has a similar
8876 calling convention. */
8879 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8880 bool named, bool retval)
8882 rtx rvec[FIRST_PSEUDO_REGISTER];
8883 int k = 1, kbase = 1;
8884 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8885 /* This is a copy; modifications are not visible to our caller. */
8886 CUMULATIVE_ARGS copy_cum = *orig_cum;
8887 CUMULATIVE_ARGS *cum = ©_cum;
8889 /* Pad to 16 byte boundary if needed. */
8890 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8891 && (cum->words % 2) != 0)
8898 /* Put entries into rvec[] for individual FP and vector fields, and
8899 for the chunks of memory that go in int regs. Note we start at
8900 element 1; 0 is reserved for an indication of using memory, and
8901 may or may not be filled in below. */
8902 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8903 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8905 /* If any part of the struct went on the stack put all of it there.
8906 This hack is because the generic code for
8907 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8908 parts of the struct are not at the beginning. */
8912 return NULL_RTX; /* doesn't go in registers at all */
8914 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8916 if (k > 1 || cum->use_stack)
8917 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8922 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8925 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8930 rtx rvec[GP_ARG_NUM_REG + 1];
8932 if (align_words >= GP_ARG_NUM_REG)
8935 n_units = rs6000_arg_size (mode, type);
8937 /* Optimize the simple case where the arg fits in one gpr, except in
8938 the case of BLKmode due to assign_parms assuming that registers are
8939 BITS_PER_WORD wide. */
8941 || (n_units == 1 && mode != BLKmode))
8942 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8945 if (align_words + n_units > GP_ARG_NUM_REG)
8946 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8947 using a magic NULL_RTX component.
8948 This is not strictly correct. Only some of the arg belongs in
8949 memory, not all of it. However, the normal scheme using
8950 function_arg_partial_nregs can result in unusual subregs, eg.
8951 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8952 store the whole arg to memory is often more efficient than code
8953 to store pieces, and we know that space is available in the right
8954 place for the whole arg. */
8955 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8960 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8961 rtx off = GEN_INT (i++ * 4);
8962 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8964 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8966 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8969 /* Determine where to put an argument to a function.
8970 Value is zero to push the argument on the stack,
8971 or a hard register in which to store the argument.
8973 MODE is the argument's machine mode.
8974 TYPE is the data type of the argument (as a tree).
8975 This is null for libcalls where that information may
8977 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8978 the preceding args and about the function being called. It is
8979 not modified in this routine.
8980 NAMED is nonzero if this argument is a named parameter
8981 (otherwise it is an extra parameter matching an ellipsis).
8983 On RS/6000 the first eight words of non-FP are normally in registers
8984 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8985 Under V.4, the first 8 FP args are in registers.
8987 If this is floating-point and no prototype is specified, we use
8988 both an FP and integer register (or possibly FP reg and stack). Library
8989 functions (when CALL_LIBCALL is set) always have the proper types for args,
8990 so we can pass the FP value just in one register. emit_library_function
8991 doesn't support PARALLEL anyway.
8993 Note that for args passed by reference, function_arg will be called
8994 with MODE and TYPE set to that of the pointer to the arg, not the arg
8998 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8999 const_tree type, bool named)
9001 enum rs6000_abi abi = DEFAULT_ABI;
9003 /* Return a marker to indicate whether CR1 needs to set or clear the
9004 bit that V.4 uses to say fp args were passed in registers.
9005 Assume that we don't need the marker for software floating point,
9006 or compiler generated library calls. */
9007 if (mode == VOIDmode)
9010 && (cum->call_cookie & CALL_LIBCALL) == 0
9012 || (cum->nargs_prototype < 0
9013 && (cum->prototype || TARGET_NO_PROTOTYPE))))
9015 /* For the SPE, we need to crxor CR6 always. */
9017 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
9018 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
9019 return GEN_INT (cum->call_cookie
9020 | ((cum->fregno == FP_ARG_MIN_REG)
9021 ? CALL_V4_SET_FP_ARGS
9022 : CALL_V4_CLEAR_FP_ARGS));
9025 return GEN_INT (cum->call_cookie);
9028 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9030 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
9031 if (rslt != NULL_RTX)
9033 /* Else fall through to usual handling. */
9036 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
9037 if (TARGET_64BIT && ! cum->prototype)
9039 /* Vector parameters get passed in vector register
9040 and also in GPRs or memory, in absence of prototype. */
9043 align_words = (cum->words + 1) & ~1;
9045 if (align_words >= GP_ARG_NUM_REG)
9051 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9053 return gen_rtx_PARALLEL (mode,
9055 gen_rtx_EXPR_LIST (VOIDmode,
9057 gen_rtx_EXPR_LIST (VOIDmode,
9058 gen_rtx_REG (mode, cum->vregno),
9062 return gen_rtx_REG (mode, cum->vregno);
9063 else if (TARGET_ALTIVEC_ABI
9064 && (ALTIVEC_VECTOR_MODE (mode)
9065 || VSX_VECTOR_MODE (mode)
9066 || (type && TREE_CODE (type) == VECTOR_TYPE
9067 && int_size_in_bytes (type) == 16)))
9069 if (named || abi == ABI_V4)
9073 /* Vector parameters to varargs functions under AIX or Darwin
9074 get passed in memory and possibly also in GPRs. */
9075 int align, align_words, n_words;
9076 enum machine_mode part_mode;
9078 /* Vector parameters must be 16-byte aligned. This places them at
9079 2 mod 4 in terms of words in 32-bit mode, since the parameter
9080 save area starts at offset 24 from the stack. In 64-bit mode,
9081 they just have to start on an even word, since the parameter
9082 save area is 16-byte aligned. */
9084 align = (2 - cum->words) & 3;
9086 align = cum->words & 1;
9087 align_words = cum->words + align;
9089 /* Out of registers? Memory, then. */
9090 if (align_words >= GP_ARG_NUM_REG)
9093 if (TARGET_32BIT && TARGET_POWERPC64)
9094 return rs6000_mixed_function_arg (mode, type, align_words);
9096 /* The vector value goes in GPRs. Only the part of the
9097 value in GPRs is reported here. */
9099 n_words = rs6000_arg_size (mode, type);
9100 if (align_words + n_words > GP_ARG_NUM_REG)
9101 /* Fortunately, there are only two possibilities, the value
9102 is either wholly in GPRs or half in GPRs and half not. */
9105 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9108 else if (TARGET_SPE_ABI && TARGET_SPE
9109 && (SPE_VECTOR_MODE (mode)
9110 || (TARGET_E500_DOUBLE && (mode == DFmode
9113 || mode == TCmode))))
9114 return rs6000_spe_function_arg (cum, mode, type);
9116 else if (abi == ABI_V4)
9118 if (TARGET_HARD_FLOAT && TARGET_FPRS
9119 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9120 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9121 || (mode == TFmode && !TARGET_IEEEQUAD)
9122 || mode == SDmode || mode == DDmode || mode == TDmode))
9124 /* _Decimal128 must use an even/odd register pair. This assumes
9125 that the register number is odd when fregno is odd. */
9126 if (mode == TDmode && (cum->fregno % 2) == 1)
9129 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9130 <= FP_ARG_V4_MAX_REG)
9131 return gen_rtx_REG (mode, cum->fregno);
9137 int n_words = rs6000_arg_size (mode, type);
9138 int gregno = cum->sysv_gregno;
9140 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9141 (r7,r8) or (r9,r10). As does any other 2 word item such
9142 as complex int due to a historical mistake. */
9144 gregno += (1 - gregno) & 1;
9146 /* Multi-reg args are not split between registers and stack. */
9147 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9150 if (TARGET_32BIT && TARGET_POWERPC64)
9151 return rs6000_mixed_function_arg (mode, type,
9152 gregno - GP_ARG_MIN_REG);
9153 return gen_rtx_REG (mode, gregno);
9158 int align_words = rs6000_parm_start (mode, type, cum->words);
9160 /* _Decimal128 must be passed in an even/odd float register pair.
9161 This assumes that the register number is odd when fregno is odd. */
9162 if (mode == TDmode && (cum->fregno % 2) == 1)
9165 if (USE_FP_FOR_ARG_P (cum, mode, type))
9167 rtx rvec[GP_ARG_NUM_REG + 1];
9171 enum machine_mode fmode = mode;
9172 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9174 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9176 /* Currently, we only ever need one reg here because complex
9177 doubles are split. */
9178 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9179 && (fmode == TFmode || fmode == TDmode));
9181 /* Long double or _Decimal128 split over regs and memory. */
9182 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9185 /* Do we also need to pass this arg in the parameter save
9188 && (cum->nargs_prototype <= 0
9189 || (DEFAULT_ABI == ABI_AIX
9191 && align_words >= GP_ARG_NUM_REG)));
9193 if (!needs_psave && mode == fmode)
9194 return gen_rtx_REG (fmode, cum->fregno);
9199 /* Describe the part that goes in gprs or the stack.
9200 This piece must come first, before the fprs. */
9201 if (align_words < GP_ARG_NUM_REG)
9203 unsigned long n_words = rs6000_arg_size (mode, type);
9205 if (align_words + n_words > GP_ARG_NUM_REG
9206 || (TARGET_32BIT && TARGET_POWERPC64))
9208 /* If this is partially on the stack, then we only
9209 include the portion actually in registers here. */
9210 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9213 if (align_words + n_words > GP_ARG_NUM_REG)
9214 /* Not all of the arg fits in gprs. Say that it
9215 goes in memory too, using a magic NULL_RTX
9216 component. Also see comment in
9217 rs6000_mixed_function_arg for why the normal
9218 function_arg_partial_nregs scheme doesn't work
9220 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9224 r = gen_rtx_REG (rmode,
9225 GP_ARG_MIN_REG + align_words);
9226 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9227 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9229 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9233 /* The whole arg fits in gprs. */
9234 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9235 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9239 /* It's entirely in memory. */
9240 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9243 /* Describe where this piece goes in the fprs. */
9244 r = gen_rtx_REG (fmode, cum->fregno);
9245 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9247 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9249 else if (align_words < GP_ARG_NUM_REG)
9251 if (TARGET_32BIT && TARGET_POWERPC64)
9252 return rs6000_mixed_function_arg (mode, type, align_words);
9254 if (mode == BLKmode)
9257 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9264 /* For an arg passed partly in registers and partly in memory, this is
9265 the number of bytes passed in registers. For args passed entirely in
9266 registers or entirely in memory, zero. When an arg is described by a
9267 PARALLEL, perhaps using more than one register type, this function
9268 returns the number of bytes used by the first element of the PARALLEL. */
9271 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9272 tree type, bool named)
9277 if (DEFAULT_ABI == ABI_V4)
9280 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9281 && cum->nargs_prototype >= 0)
9284 /* In this complicated case we just disable the partial_nregs code. */
9285 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9288 align_words = rs6000_parm_start (mode, type, cum->words);
9290 if (USE_FP_FOR_ARG_P (cum, mode, type))
9292 /* If we are passing this arg in the fixed parameter save area
9293 (gprs or memory) as well as fprs, then this function should
9294 return the number of partial bytes passed in the parameter
9295 save area rather than partial bytes passed in fprs. */
9297 && (cum->nargs_prototype <= 0
9298 || (DEFAULT_ABI == ABI_AIX
9300 && align_words >= GP_ARG_NUM_REG)))
9302 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9303 > FP_ARG_MAX_REG + 1)
9304 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9305 else if (cum->nargs_prototype >= 0)
9309 if (align_words < GP_ARG_NUM_REG
9310 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9311 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9313 if (ret != 0 && TARGET_DEBUG_ARG)
9314 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9319 /* A C expression that indicates when an argument must be passed by
9320 reference. If nonzero for an argument, a copy of that argument is
9321 made in memory and a pointer to the argument is passed instead of
9322 the argument itself. The pointer is passed in whatever way is
9323 appropriate for passing a pointer to that type.
9325 Under V.4, aggregates and long double are passed by reference.
9327 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9328 reference unless the AltiVec vector extension ABI is in force.
9330 As an extension to all ABIs, variable sized types are passed by
9334 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9335 enum machine_mode mode, const_tree type,
9336 bool named ATTRIBUTE_UNUSED)
9338 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9340 if (TARGET_DEBUG_ARG)
9341 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9348 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9350 if (TARGET_DEBUG_ARG)
9351 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9355 if (int_size_in_bytes (type) < 0)
9357 if (TARGET_DEBUG_ARG)
9358 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9362 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9363 modes only exist for GCC vector types if -maltivec. */
9364 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9366 if (TARGET_DEBUG_ARG)
9367 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9371 /* Pass synthetic vectors in memory. */
9372 if (TREE_CODE (type) == VECTOR_TYPE
9373 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9375 static bool warned_for_pass_big_vectors = false;
9376 if (TARGET_DEBUG_ARG)
9377 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9378 if (!warned_for_pass_big_vectors)
9380 warning (0, "GCC vector passed by reference: "
9381 "non-standard ABI extension with no compatibility guarantee");
9382 warned_for_pass_big_vectors = true;
9391 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9394 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9399 for (i = 0; i < nregs; i++)
9401 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9402 if (reload_completed)
9404 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9407 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9408 i * GET_MODE_SIZE (reg_mode));
9411 tem = replace_equiv_address (tem, XEXP (tem, 0));
9415 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9419 /* Perform any needed actions needed for a function that is receiving a
9420 variable number of arguments.
9424 MODE and TYPE are the mode and type of the current parameter.
9426 PRETEND_SIZE is a variable that should be set to the amount of stack
9427 that must be pushed by the prolog to pretend that our caller pushed
9430 Normally, this macro will push all remaining incoming registers on the
9431 stack and set PRETEND_SIZE to the length of the registers pushed. */
9434 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9435 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9438 CUMULATIVE_ARGS next_cum;
9439 int reg_size = TARGET_32BIT ? 4 : 8;
9440 rtx save_area = NULL_RTX, mem;
9441 int first_reg_offset;
9444 /* Skip the last named argument. */
9446 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9448 if (DEFAULT_ABI == ABI_V4)
9450 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9454 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9455 HOST_WIDE_INT offset = 0;
9457 /* Try to optimize the size of the varargs save area.
9458 The ABI requires that ap.reg_save_area is doubleword
9459 aligned, but we don't need to allocate space for all
9460 the bytes, only those to which we actually will save
9462 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9463 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9464 if (TARGET_HARD_FLOAT && TARGET_FPRS
9465 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9466 && cfun->va_list_fpr_size)
9469 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9470 * UNITS_PER_FP_WORD;
9471 if (cfun->va_list_fpr_size
9472 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9473 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9475 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9476 * UNITS_PER_FP_WORD;
9480 offset = -((first_reg_offset * reg_size) & ~7);
9481 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9483 gpr_reg_num = cfun->va_list_gpr_size;
9484 if (reg_size == 4 && (first_reg_offset & 1))
9487 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9490 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9492 - (int) (GP_ARG_NUM_REG * reg_size);
9494 if (gpr_size + fpr_size)
9497 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9498 gcc_assert (GET_CODE (reg_save_area) == MEM);
9499 reg_save_area = XEXP (reg_save_area, 0);
9500 if (GET_CODE (reg_save_area) == PLUS)
9502 gcc_assert (XEXP (reg_save_area, 0)
9503 == virtual_stack_vars_rtx);
9504 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9505 offset += INTVAL (XEXP (reg_save_area, 1));
9508 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9511 cfun->machine->varargs_save_offset = offset;
9512 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9517 first_reg_offset = next_cum.words;
9518 save_area = virtual_incoming_args_rtx;
9520 if (targetm.calls.must_pass_in_stack (mode, type))
9521 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9524 set = get_varargs_alias_set ();
9525 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9526 && cfun->va_list_gpr_size)
9528 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9530 if (va_list_gpr_counter_field)
9532 /* V4 va_list_gpr_size counts number of registers needed. */
9533 if (nregs > cfun->va_list_gpr_size)
9534 nregs = cfun->va_list_gpr_size;
9538 /* char * va_list instead counts number of bytes needed. */
9539 if (nregs > cfun->va_list_gpr_size / reg_size)
9540 nregs = cfun->va_list_gpr_size / reg_size;
9543 mem = gen_rtx_MEM (BLKmode,
9544 plus_constant (save_area,
9545 first_reg_offset * reg_size));
9546 MEM_NOTRAP_P (mem) = 1;
9547 set_mem_alias_set (mem, set);
9548 set_mem_align (mem, BITS_PER_WORD);
9550 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9554 /* Save FP registers if needed. */
9555 if (DEFAULT_ABI == ABI_V4
9556 && TARGET_HARD_FLOAT && TARGET_FPRS
9558 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9559 && cfun->va_list_fpr_size)
9561 int fregno = next_cum.fregno, nregs;
9562 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9563 rtx lab = gen_label_rtx ();
9564 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9565 * UNITS_PER_FP_WORD);
9568 (gen_rtx_SET (VOIDmode,
9570 gen_rtx_IF_THEN_ELSE (VOIDmode,
9571 gen_rtx_NE (VOIDmode, cr1,
9573 gen_rtx_LABEL_REF (VOIDmode, lab),
9577 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9578 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9580 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9582 plus_constant (save_area, off));
9583 MEM_NOTRAP_P (mem) = 1;
9584 set_mem_alias_set (mem, set);
9585 set_mem_align (mem, GET_MODE_ALIGNMENT (
9586 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9587 ? DFmode : SFmode));
9588 emit_move_insn (mem, gen_rtx_REG (
9589 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9590 ? DFmode : SFmode, fregno));
9597 /* Create the va_list data type. */
9600 rs6000_build_builtin_va_list (void)
9602 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9604 /* For AIX, prefer 'char *' because that's what the system
9605 header files like. */
9606 if (DEFAULT_ABI != ABI_V4)
9607 return build_pointer_type (char_type_node);
9609 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9610 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9611 get_identifier ("__va_list_tag"), record);
9613 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9614 unsigned_char_type_node);
9615 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9616 unsigned_char_type_node);
9617 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9619 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9620 get_identifier ("reserved"), short_unsigned_type_node);
9621 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9622 get_identifier ("overflow_arg_area"),
9624 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9625 get_identifier ("reg_save_area"),
9628 va_list_gpr_counter_field = f_gpr;
9629 va_list_fpr_counter_field = f_fpr;
9631 DECL_FIELD_CONTEXT (f_gpr) = record;
9632 DECL_FIELD_CONTEXT (f_fpr) = record;
9633 DECL_FIELD_CONTEXT (f_res) = record;
9634 DECL_FIELD_CONTEXT (f_ovf) = record;
9635 DECL_FIELD_CONTEXT (f_sav) = record;
9637 TYPE_STUB_DECL (record) = type_decl;
9638 TYPE_NAME (record) = type_decl;
9639 TYPE_FIELDS (record) = f_gpr;
9640 DECL_CHAIN (f_gpr) = f_fpr;
9641 DECL_CHAIN (f_fpr) = f_res;
9642 DECL_CHAIN (f_res) = f_ovf;
9643 DECL_CHAIN (f_ovf) = f_sav;
9645 layout_type (record);
9647 /* The correct type is an array type of one element. */
9648 return build_array_type (record, build_index_type (size_zero_node));
9651 /* Implement va_start. */
9654 rs6000_va_start (tree valist, rtx nextarg)
9656 HOST_WIDE_INT words, n_gpr, n_fpr;
9657 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9658 tree gpr, fpr, ovf, sav, t;
9660 /* Only SVR4 needs something special. */
9661 if (DEFAULT_ABI != ABI_V4)
9663 std_expand_builtin_va_start (valist, nextarg);
9667 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9668 f_fpr = DECL_CHAIN (f_gpr);
9669 f_res = DECL_CHAIN (f_fpr);
9670 f_ovf = DECL_CHAIN (f_res);
9671 f_sav = DECL_CHAIN (f_ovf);
9673 valist = build_simple_mem_ref (valist);
9674 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9675 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9677 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9679 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9682 /* Count number of gp and fp argument registers used. */
9683 words = crtl->args.info.words;
9684 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9686 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9689 if (TARGET_DEBUG_ARG)
9690 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9691 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9692 words, n_gpr, n_fpr);
9694 if (cfun->va_list_gpr_size)
9696 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9697 build_int_cst (NULL_TREE, n_gpr));
9698 TREE_SIDE_EFFECTS (t) = 1;
9699 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9702 if (cfun->va_list_fpr_size)
9704 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9705 build_int_cst (NULL_TREE, n_fpr));
9706 TREE_SIDE_EFFECTS (t) = 1;
9707 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9709 #ifdef HAVE_AS_GNU_ATTRIBUTE
9710 if (call_ABI_of_interest (cfun->decl))
9711 rs6000_passes_float = true;
9715 /* Find the overflow area. */
9716 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9718 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9719 size_int (words * UNITS_PER_WORD));
9720 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9721 TREE_SIDE_EFFECTS (t) = 1;
9722 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9724 /* If there were no va_arg invocations, don't set up the register
9726 if (!cfun->va_list_gpr_size
9727 && !cfun->va_list_fpr_size
9728 && n_gpr < GP_ARG_NUM_REG
9729 && n_fpr < FP_ARG_V4_MAX_REG)
9732 /* Find the register save area. */
9733 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9734 if (cfun->machine->varargs_save_offset)
9735 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9736 size_int (cfun->machine->varargs_save_offset));
9737 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9738 TREE_SIDE_EFFECTS (t) = 1;
9739 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9742 /* Implement va_arg. */
9745 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9748 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9749 tree gpr, fpr, ovf, sav, reg, t, u;
9750 int size, rsize, n_reg, sav_ofs, sav_scale;
9751 tree lab_false, lab_over, addr;
9753 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9757 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9759 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9760 return build_va_arg_indirect_ref (t);
9763 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9764 earlier version of gcc, with the property that it always applied alignment
9765 adjustments to the va-args (even for zero-sized types). The cheapest way
9766 to deal with this is to replicate the effect of the part of
9767 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9769 We don't need to check for pass-by-reference because of the test above.
9770 We can return a simplifed answer, since we know there's no offset to add. */
9773 && rs6000_darwin64_abi
9774 && integer_zerop (TYPE_SIZE (type)))
9776 unsigned HOST_WIDE_INT align, boundary;
9777 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9778 align = PARM_BOUNDARY / BITS_PER_UNIT;
9779 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9780 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9781 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9782 boundary /= BITS_PER_UNIT;
9783 if (boundary > align)
9786 /* This updates arg ptr by the amount that would be necessary
9787 to align the zero-sized (but not zero-alignment) item. */
9788 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9789 fold_build2 (POINTER_PLUS_EXPR,
9791 valist_tmp, size_int (boundary - 1)));
9792 gimplify_and_add (t, pre_p);
9794 t = fold_convert (sizetype, valist_tmp);
9795 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9796 fold_convert (TREE_TYPE (valist),
9797 fold_build2 (BIT_AND_EXPR, sizetype, t,
9798 size_int (-boundary))));
9799 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9800 gimplify_and_add (t, pre_p);
9802 /* Since it is zero-sized there's no increment for the item itself. */
9803 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9804 return build_va_arg_indirect_ref (valist_tmp);
9807 if (DEFAULT_ABI != ABI_V4)
9809 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9811 tree elem_type = TREE_TYPE (type);
9812 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9813 int elem_size = GET_MODE_SIZE (elem_mode);
9815 if (elem_size < UNITS_PER_WORD)
9817 tree real_part, imag_part;
9818 gimple_seq post = NULL;
9820 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9822 /* Copy the value into a temporary, lest the formal temporary
9823 be reused out from under us. */
9824 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9825 gimple_seq_add_seq (pre_p, post);
9827 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9830 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9834 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9837 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9838 f_fpr = DECL_CHAIN (f_gpr);
9839 f_res = DECL_CHAIN (f_fpr);
9840 f_ovf = DECL_CHAIN (f_res);
9841 f_sav = DECL_CHAIN (f_ovf);
9843 valist = build_va_arg_indirect_ref (valist);
9844 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9845 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9847 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9849 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9852 size = int_size_in_bytes (type);
9853 rsize = (size + 3) / 4;
9856 if (TARGET_HARD_FLOAT && TARGET_FPRS
9857 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9858 || (TARGET_DOUBLE_FLOAT
9859 && (TYPE_MODE (type) == DFmode
9860 || TYPE_MODE (type) == TFmode
9861 || TYPE_MODE (type) == SDmode
9862 || TYPE_MODE (type) == DDmode
9863 || TYPE_MODE (type) == TDmode))))
9865 /* FP args go in FP registers, if present. */
9867 n_reg = (size + 7) / 8;
9868 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9869 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9870 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9875 /* Otherwise into GP registers. */
9884 /* Pull the value out of the saved registers.... */
9887 addr = create_tmp_var (ptr_type_node, "addr");
9889 /* AltiVec vectors never go in registers when -mabi=altivec. */
9890 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9894 lab_false = create_artificial_label (input_location);
9895 lab_over = create_artificial_label (input_location);
9897 /* Long long and SPE vectors are aligned in the registers.
9898 As are any other 2 gpr item such as complex int due to a
9899 historical mistake. */
9901 if (n_reg == 2 && reg == gpr)
9904 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9905 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9906 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9907 unshare_expr (reg), u);
9909 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9910 reg number is 0 for f1, so we want to make it odd. */
9911 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9913 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9914 build_int_cst (TREE_TYPE (reg), 1));
9915 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9918 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9919 t = build2 (GE_EXPR, boolean_type_node, u, t);
9920 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9921 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9922 gimplify_and_add (t, pre_p);
9926 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9928 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9929 build_int_cst (TREE_TYPE (reg), n_reg));
9930 u = fold_convert (sizetype, u);
9931 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9932 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9934 /* _Decimal32 varargs are located in the second word of the 64-bit
9935 FP register for 32-bit binaries. */
9936 if (!TARGET_POWERPC64
9937 && TARGET_HARD_FLOAT && TARGET_FPRS
9938 && TYPE_MODE (type) == SDmode)
9939 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9941 gimplify_assign (addr, t, pre_p);
9943 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9945 stmt = gimple_build_label (lab_false);
9946 gimple_seq_add_stmt (pre_p, stmt);
9948 if ((n_reg == 2 && !regalign) || n_reg > 2)
9950 /* Ensure that we don't find any more args in regs.
9951 Alignment has taken care of for special cases. */
9952 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9956 /* ... otherwise out of the overflow area. */
9958 /* Care for on-stack alignment if needed. */
9962 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9963 t = fold_convert (sizetype, t);
9964 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9966 t = fold_convert (TREE_TYPE (ovf), t);
9968 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9970 gimplify_assign (unshare_expr (addr), t, pre_p);
9972 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9973 gimplify_assign (unshare_expr (ovf), t, pre_p);
9977 stmt = gimple_build_label (lab_over);
9978 gimple_seq_add_stmt (pre_p, stmt);
9981 if (STRICT_ALIGNMENT
9982 && (TYPE_ALIGN (type)
9983 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9985 /* The value (of type complex double, for example) may not be
9986 aligned in memory in the saved registers, so copy via a
9987 temporary. (This is the same code as used for SPARC.) */
9988 tree tmp = create_tmp_var (type, "va_arg_tmp");
9989 tree dest_addr = build_fold_addr_expr (tmp);
9991 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9992 3, dest_addr, addr, size_int (rsize * 4));
9994 gimplify_and_add (copy, pre_p);
9998 addr = fold_convert (ptrtype, addr);
9999 return build_va_arg_indirect_ref (addr);
10005 def_builtin (int mask, const char *name, tree type, int code)
10007 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
10010 if (rs6000_builtin_decls[code])
10011 fatal_error ("internal error: builtin function to %s already processed",
10014 rs6000_builtin_decls[code] = t =
10015 add_builtin_function (name, type, code, BUILT_IN_MD,
10018 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
10019 switch (builtin_classify[code])
10022 gcc_unreachable ();
10024 /* assume builtin can do anything. */
10025 case RS6000_BTC_MISC:
10028 /* const function, function only depends on the inputs. */
10029 case RS6000_BTC_CONST:
10030 TREE_READONLY (t) = 1;
10031 TREE_NOTHROW (t) = 1;
10034 /* pure function, function can read global memory. */
10035 case RS6000_BTC_PURE:
10036 DECL_PURE_P (t) = 1;
10037 TREE_NOTHROW (t) = 1;
10040 /* Function is a math function. If rounding mode is on, then treat
10041 the function as not reading global memory, but it can have
10042 arbitrary side effects. If it is off, then assume the function is
10043 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10044 attribute in builtin-attribute.def that is used for the math
10046 case RS6000_BTC_FP_PURE:
10047 TREE_NOTHROW (t) = 1;
10048 if (flag_rounding_math)
10050 DECL_PURE_P (t) = 1;
10051 DECL_IS_NOVOPS (t) = 1;
10054 TREE_READONLY (t) = 1;
10060 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10062 static const struct builtin_description bdesc_3arg[] =
10064 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
10065 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
10066 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
10067 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
10068 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
10069 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
10070 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
10071 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
10072 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
10073 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10074 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10075 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10076 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10077 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10078 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10079 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10080 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10081 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10082 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10083 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10084 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10085 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10086 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10087 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10088 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10089 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10090 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10091 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10092 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10093 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10094 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10095 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10096 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10097 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10098 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10100 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10101 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10102 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10103 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10104 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10105 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10106 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10107 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10108 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10109 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10110 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10111 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10113 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10114 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10116 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10117 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10118 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10119 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10121 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10122 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10123 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10124 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10126 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10127 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10129 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10130 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10131 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10132 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10133 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10134 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10135 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10136 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10137 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10138 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10140 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10141 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10142 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10143 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10144 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10145 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10146 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10147 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10148 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10149 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10151 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10152 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10153 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10154 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10155 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10156 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10157 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10158 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10159 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10161 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10162 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10163 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10164 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10165 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10166 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10167 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10169 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10170 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10171 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10172 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10173 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10174 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10175 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10176 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10177 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10180 /* DST operations: void foo (void *, const int, const char). */
10182 static const struct builtin_description bdesc_dst[] =
10184 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10185 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10186 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10187 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10189 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10190 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10191 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10192 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10195 /* Simple binary operations: VECc = foo (VECa, VECb). */
10197 static struct builtin_description bdesc_2arg[] =
10199 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10200 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10201 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10202 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10203 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10204 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10205 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10206 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10207 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10208 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10209 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10210 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10211 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10212 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10213 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10214 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10215 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10216 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10217 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10218 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10219 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10220 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10221 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10222 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10223 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10224 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10225 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10226 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10227 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10228 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10229 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10230 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10231 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10232 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10233 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10234 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10235 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10236 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10237 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10238 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10239 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10240 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10241 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10242 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10243 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10244 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10245 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10246 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10247 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10248 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10249 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10250 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10251 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10252 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10253 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10254 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10255 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10256 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10257 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10258 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10259 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10260 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10261 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10262 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10263 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10264 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10265 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10266 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10267 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10268 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10269 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10270 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10271 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10272 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10273 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10274 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10275 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10276 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10277 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10278 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10279 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10280 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10281 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10282 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10283 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10284 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10285 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10286 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10287 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10288 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10289 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10290 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10291 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10292 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10293 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10294 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10295 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10296 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10297 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10298 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10299 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10300 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10301 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10302 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10303 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10304 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10305 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10306 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10307 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10308 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10309 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10310 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10311 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10312 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10313 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10314 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10315 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10317 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10318 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10319 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10320 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10321 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10322 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10323 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10324 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10325 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10326 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10327 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10328 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10330 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10331 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10332 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10333 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10334 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10335 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10336 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10337 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10338 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10339 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10340 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10341 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10343 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10344 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10345 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10346 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10347 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10348 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10350 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10351 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10352 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10353 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10354 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10355 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10356 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10357 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10358 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10359 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10360 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10361 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10363 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10364 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10376 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10377 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10403 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10404 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10419 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10420 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10437 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10438 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10472 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10473 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10476 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10477 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10478 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10480 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10491 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10493 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10494 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10496 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10497 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10498 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10499 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10500 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10501 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10502 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10503 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10504 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10505 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10507 /* Place holder, leave as first spe builtin. */
10508 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10509 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10510 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10511 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10512 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10513 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10514 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10515 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10516 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10517 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10518 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10519 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10520 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10521 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10522 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10523 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10524 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10525 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10526 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10527 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10528 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10529 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10530 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10531 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10532 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10533 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10534 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10535 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10536 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10537 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10538 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10539 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10540 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10541 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10542 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10543 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10544 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10545 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10546 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10547 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10548 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10549 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10550 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10551 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10552 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10553 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10554 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10555 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10556 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10557 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10558 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10559 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10560 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10561 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10562 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10563 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10564 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10565 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10566 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10567 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10568 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10569 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10570 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10571 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10572 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10573 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10574 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10575 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10576 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10577 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10578 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10579 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10580 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10581 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10582 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10583 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10584 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10585 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10586 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10587 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10588 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10589 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10590 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10591 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10592 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10593 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10594 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10595 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10596 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10597 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10598 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10599 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10600 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10601 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10602 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10603 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10604 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10605 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10606 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10607 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10608 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10609 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10610 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10611 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10612 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10613 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10614 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10615 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10616 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10618 /* SPE binary operations expecting a 5-bit unsigned literal. */
10619 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10621 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10622 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10623 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10624 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10625 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10626 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10627 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10628 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10629 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10630 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10631 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10632 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10633 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10634 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10635 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10636 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10637 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10638 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10639 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10640 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10641 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10642 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10643 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10644 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10645 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10646 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10648 /* Place-holder. Leave as last binary SPE builtin. */
10649 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10652 /* AltiVec predicates. */
10654 struct builtin_description_predicates
10656 const unsigned int mask;
10657 const enum insn_code icode;
10658 const char *const name;
10659 const enum rs6000_builtins code;
10662 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10664 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10665 ALTIVEC_BUILTIN_VCMPBFP_P },
10666 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10667 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10668 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10669 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10670 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10671 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10672 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10673 ALTIVEC_BUILTIN_VCMPEQUW_P },
10674 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10675 ALTIVEC_BUILTIN_VCMPGTSW_P },
10676 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10677 ALTIVEC_BUILTIN_VCMPGTUW_P },
10678 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10679 ALTIVEC_BUILTIN_VCMPEQUH_P },
10680 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10681 ALTIVEC_BUILTIN_VCMPGTSH_P },
10682 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10683 ALTIVEC_BUILTIN_VCMPGTUH_P },
10684 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10685 ALTIVEC_BUILTIN_VCMPEQUB_P },
10686 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10687 ALTIVEC_BUILTIN_VCMPGTSB_P },
10688 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10689 ALTIVEC_BUILTIN_VCMPGTUB_P },
10691 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10692 VSX_BUILTIN_XVCMPEQSP_P },
10693 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10694 VSX_BUILTIN_XVCMPGESP_P },
10695 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10696 VSX_BUILTIN_XVCMPGTSP_P },
10697 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10698 VSX_BUILTIN_XVCMPEQDP_P },
10699 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10700 VSX_BUILTIN_XVCMPGEDP_P },
10701 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10702 VSX_BUILTIN_XVCMPGTDP_P },
10704 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10705 ALTIVEC_BUILTIN_VCMPEQ_P },
10706 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10707 ALTIVEC_BUILTIN_VCMPGT_P },
10708 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10709 ALTIVEC_BUILTIN_VCMPGE_P }
10712 /* SPE predicates. */
10713 static struct builtin_description bdesc_spe_predicates[] =
10715 /* Place-holder. Leave as first. */
10716 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10717 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10718 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10719 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10720 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10721 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10722 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10723 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10724 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10725 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10726 /* Place-holder. Leave as last. */
10727 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10730 /* SPE evsel predicates. */
10731 static struct builtin_description bdesc_spe_evsel[] =
10733 /* Place-holder. Leave as first. */
10734 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10735 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10736 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10737 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10738 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10739 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10740 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10741 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10742 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10743 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10744 /* Place-holder. Leave as last. */
10745 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10748 /* PAIRED predicates. */
10749 static const struct builtin_description bdesc_paired_preds[] =
10751 /* Place-holder. Leave as first. */
10752 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10753 /* Place-holder. Leave as last. */
10754 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10757 /* ABS* operations. */
10759 static const struct builtin_description bdesc_abs[] =
10761 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10762 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10763 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10764 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10765 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10766 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10767 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10768 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10769 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10770 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10771 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10774 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10777 static struct builtin_description bdesc_1arg[] =
10779 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10780 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10781 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10782 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10783 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10784 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10785 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10786 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10787 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10788 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10789 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10790 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10791 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10792 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10793 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10794 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10795 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10796 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10798 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10799 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10800 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10801 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10802 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10803 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10804 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10806 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10807 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10808 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10809 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10810 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10811 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10812 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10814 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10815 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10816 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10817 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10818 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10819 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10821 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10822 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10823 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10824 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10825 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10826 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10828 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10829 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10830 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10831 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10833 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10834 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10835 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10836 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10837 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10838 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10839 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10840 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10841 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10843 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10844 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10845 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10846 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10847 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10848 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10849 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10850 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10851 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10853 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10854 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10855 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10856 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10857 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10880 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10881 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10882 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10884 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10885 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10886 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10887 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10889 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10890 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10891 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10892 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10893 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10894 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10895 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10896 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10897 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10898 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10899 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10900 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10901 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10902 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10903 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10904 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10905 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10906 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10907 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10908 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10909 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10910 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10911 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10912 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10913 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10914 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10915 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10916 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10917 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10918 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10920 /* Place-holder. Leave as last unary SPE builtin. */
10921 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10923 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10924 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10925 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10926 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10927 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10931 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10934 tree arg0 = CALL_EXPR_ARG (exp, 0);
10935 rtx op0 = expand_normal (arg0);
10936 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10937 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10939 if (icode == CODE_FOR_nothing)
10940 /* Builtin not supported on this processor. */
10943 /* If we got invalid arguments bail out before generating bad rtl. */
10944 if (arg0 == error_mark_node)
10947 if (icode == CODE_FOR_altivec_vspltisb
10948 || icode == CODE_FOR_altivec_vspltish
10949 || icode == CODE_FOR_altivec_vspltisw
10950 || icode == CODE_FOR_spe_evsplatfi
10951 || icode == CODE_FOR_spe_evsplati)
10953 /* Only allow 5-bit *signed* literals. */
10954 if (GET_CODE (op0) != CONST_INT
10955 || INTVAL (op0) > 15
10956 || INTVAL (op0) < -16)
10958 error ("argument 1 must be a 5-bit signed literal");
10964 || GET_MODE (target) != tmode
10965 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10966 target = gen_reg_rtx (tmode);
10968 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10969 op0 = copy_to_mode_reg (mode0, op0);
10971 pat = GEN_FCN (icode) (target, op0);
10980 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10982 rtx pat, scratch1, scratch2;
10983 tree arg0 = CALL_EXPR_ARG (exp, 0);
10984 rtx op0 = expand_normal (arg0);
10985 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10986 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10988 /* If we have invalid arguments, bail out before generating bad rtl. */
10989 if (arg0 == error_mark_node)
10993 || GET_MODE (target) != tmode
10994 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10995 target = gen_reg_rtx (tmode);
10997 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10998 op0 = copy_to_mode_reg (mode0, op0);
11000 scratch1 = gen_reg_rtx (mode0);
11001 scratch2 = gen_reg_rtx (mode0);
11003 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
11012 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
11015 tree arg0 = CALL_EXPR_ARG (exp, 0);
11016 tree arg1 = CALL_EXPR_ARG (exp, 1);
11017 rtx op0 = expand_normal (arg0);
11018 rtx op1 = expand_normal (arg1);
11019 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11020 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11021 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11023 if (icode == CODE_FOR_nothing)
11024 /* Builtin not supported on this processor. */
11027 /* If we got invalid arguments bail out before generating bad rtl. */
11028 if (arg0 == error_mark_node || arg1 == error_mark_node)
11031 if (icode == CODE_FOR_altivec_vcfux
11032 || icode == CODE_FOR_altivec_vcfsx
11033 || icode == CODE_FOR_altivec_vctsxs
11034 || icode == CODE_FOR_altivec_vctuxs
11035 || icode == CODE_FOR_altivec_vspltb
11036 || icode == CODE_FOR_altivec_vsplth
11037 || icode == CODE_FOR_altivec_vspltw
11038 || icode == CODE_FOR_spe_evaddiw
11039 || icode == CODE_FOR_spe_evldd
11040 || icode == CODE_FOR_spe_evldh
11041 || icode == CODE_FOR_spe_evldw
11042 || icode == CODE_FOR_spe_evlhhesplat
11043 || icode == CODE_FOR_spe_evlhhossplat
11044 || icode == CODE_FOR_spe_evlhhousplat
11045 || icode == CODE_FOR_spe_evlwhe
11046 || icode == CODE_FOR_spe_evlwhos
11047 || icode == CODE_FOR_spe_evlwhou
11048 || icode == CODE_FOR_spe_evlwhsplat
11049 || icode == CODE_FOR_spe_evlwwsplat
11050 || icode == CODE_FOR_spe_evrlwi
11051 || icode == CODE_FOR_spe_evslwi
11052 || icode == CODE_FOR_spe_evsrwis
11053 || icode == CODE_FOR_spe_evsubifw
11054 || icode == CODE_FOR_spe_evsrwiu)
11056 /* Only allow 5-bit unsigned literals. */
11058 if (TREE_CODE (arg1) != INTEGER_CST
11059 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11061 error ("argument 2 must be a 5-bit unsigned literal");
11067 || GET_MODE (target) != tmode
11068 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11069 target = gen_reg_rtx (tmode);
11071 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11072 op0 = copy_to_mode_reg (mode0, op0);
11073 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11074 op1 = copy_to_mode_reg (mode1, op1);
11076 pat = GEN_FCN (icode) (target, op0, op1);
11085 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11088 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11089 tree arg0 = CALL_EXPR_ARG (exp, 1);
11090 tree arg1 = CALL_EXPR_ARG (exp, 2);
11091 rtx op0 = expand_normal (arg0);
11092 rtx op1 = expand_normal (arg1);
11093 enum machine_mode tmode = SImode;
11094 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11095 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11098 if (TREE_CODE (cr6_form) != INTEGER_CST)
11100 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11104 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11106 gcc_assert (mode0 == mode1);
11108 /* If we have invalid arguments, bail out before generating bad rtl. */
11109 if (arg0 == error_mark_node || arg1 == error_mark_node)
11113 || GET_MODE (target) != tmode
11114 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11115 target = gen_reg_rtx (tmode);
11117 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11118 op0 = copy_to_mode_reg (mode0, op0);
11119 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11120 op1 = copy_to_mode_reg (mode1, op1);
11122 scratch = gen_reg_rtx (mode0);
11124 pat = GEN_FCN (icode) (scratch, op0, op1);
11129 /* The vec_any* and vec_all* predicates use the same opcodes for two
11130 different operations, but the bits in CR6 will be different
11131 depending on what information we want. So we have to play tricks
11132 with CR6 to get the right bits out.
11134 If you think this is disgusting, look at the specs for the
11135 AltiVec predicates. */
11137 switch (cr6_form_int)
11140 emit_insn (gen_cr6_test_for_zero (target));
11143 emit_insn (gen_cr6_test_for_zero_reverse (target));
11146 emit_insn (gen_cr6_test_for_lt (target));
11149 emit_insn (gen_cr6_test_for_lt_reverse (target));
11152 error ("argument 1 of __builtin_altivec_predicate is out of range");
11160 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11163 tree arg0 = CALL_EXPR_ARG (exp, 0);
11164 tree arg1 = CALL_EXPR_ARG (exp, 1);
11165 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11166 enum machine_mode mode0 = Pmode;
11167 enum machine_mode mode1 = Pmode;
11168 rtx op0 = expand_normal (arg0);
11169 rtx op1 = expand_normal (arg1);
11171 if (icode == CODE_FOR_nothing)
11172 /* Builtin not supported on this processor. */
11175 /* If we got invalid arguments bail out before generating bad rtl. */
11176 if (arg0 == error_mark_node || arg1 == error_mark_node)
11180 || GET_MODE (target) != tmode
11181 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11182 target = gen_reg_rtx (tmode);
11184 op1 = copy_to_mode_reg (mode1, op1);
11186 if (op0 == const0_rtx)
11188 addr = gen_rtx_MEM (tmode, op1);
11192 op0 = copy_to_mode_reg (mode0, op0);
11193 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11196 pat = GEN_FCN (icode) (target, addr);
11206 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11209 tree arg0 = CALL_EXPR_ARG (exp, 0);
11210 tree arg1 = CALL_EXPR_ARG (exp, 1);
11211 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11212 enum machine_mode mode0 = Pmode;
11213 enum machine_mode mode1 = Pmode;
11214 rtx op0 = expand_normal (arg0);
11215 rtx op1 = expand_normal (arg1);
11217 if (icode == CODE_FOR_nothing)
11218 /* Builtin not supported on this processor. */
11221 /* If we got invalid arguments bail out before generating bad rtl. */
11222 if (arg0 == error_mark_node || arg1 == error_mark_node)
11226 || GET_MODE (target) != tmode
11227 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11228 target = gen_reg_rtx (tmode);
11230 op1 = copy_to_mode_reg (mode1, op1);
11232 if (op0 == const0_rtx)
11234 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11238 op0 = copy_to_mode_reg (mode0, op0);
11239 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11242 pat = GEN_FCN (icode) (target, addr);
11252 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11254 tree arg0 = CALL_EXPR_ARG (exp, 0);
11255 tree arg1 = CALL_EXPR_ARG (exp, 1);
11256 tree arg2 = CALL_EXPR_ARG (exp, 2);
11257 rtx op0 = expand_normal (arg0);
11258 rtx op1 = expand_normal (arg1);
11259 rtx op2 = expand_normal (arg2);
11261 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11262 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11263 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11265 /* Invalid arguments. Bail before doing anything stoopid! */
11266 if (arg0 == error_mark_node
11267 || arg1 == error_mark_node
11268 || arg2 == error_mark_node)
11271 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11272 op0 = copy_to_mode_reg (mode2, op0);
11273 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11274 op1 = copy_to_mode_reg (mode0, op1);
11275 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11276 op2 = copy_to_mode_reg (mode1, op2);
11278 pat = GEN_FCN (icode) (op1, op2, op0);
11285 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11287 tree arg0 = CALL_EXPR_ARG (exp, 0);
11288 tree arg1 = CALL_EXPR_ARG (exp, 1);
11289 tree arg2 = CALL_EXPR_ARG (exp, 2);
11290 rtx op0 = expand_normal (arg0);
11291 rtx op1 = expand_normal (arg1);
11292 rtx op2 = expand_normal (arg2);
11294 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11295 enum machine_mode mode1 = Pmode;
11296 enum machine_mode mode2 = Pmode;
11298 /* Invalid arguments. Bail before doing anything stoopid! */
11299 if (arg0 == error_mark_node
11300 || arg1 == error_mark_node
11301 || arg2 == error_mark_node)
11304 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11305 op0 = copy_to_mode_reg (tmode, op0);
11307 op2 = copy_to_mode_reg (mode2, op2);
11309 if (op1 == const0_rtx)
11311 addr = gen_rtx_MEM (tmode, op2);
11315 op1 = copy_to_mode_reg (mode1, op1);
11316 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11319 pat = GEN_FCN (icode) (addr, op0);
11326 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11328 tree arg0 = CALL_EXPR_ARG (exp, 0);
11329 tree arg1 = CALL_EXPR_ARG (exp, 1);
11330 tree arg2 = CALL_EXPR_ARG (exp, 2);
11331 rtx op0 = expand_normal (arg0);
11332 rtx op1 = expand_normal (arg1);
11333 rtx op2 = expand_normal (arg2);
11335 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11336 enum machine_mode smode = insn_data[icode].operand[1].mode;
11337 enum machine_mode mode1 = Pmode;
11338 enum machine_mode mode2 = Pmode;
11340 /* Invalid arguments. Bail before doing anything stoopid! */
11341 if (arg0 == error_mark_node
11342 || arg1 == error_mark_node
11343 || arg2 == error_mark_node)
11346 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11347 op0 = copy_to_mode_reg (smode, op0);
11349 op2 = copy_to_mode_reg (mode2, op2);
11351 if (op1 == const0_rtx)
11353 addr = gen_rtx_MEM (tmode, op2);
11357 op1 = copy_to_mode_reg (mode1, op1);
11358 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11361 pat = GEN_FCN (icode) (addr, op0);
11368 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11371 tree arg0 = CALL_EXPR_ARG (exp, 0);
11372 tree arg1 = CALL_EXPR_ARG (exp, 1);
11373 tree arg2 = CALL_EXPR_ARG (exp, 2);
11374 rtx op0 = expand_normal (arg0);
11375 rtx op1 = expand_normal (arg1);
11376 rtx op2 = expand_normal (arg2);
11377 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11378 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11379 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11380 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11382 if (icode == CODE_FOR_nothing)
11383 /* Builtin not supported on this processor. */
11386 /* If we got invalid arguments bail out before generating bad rtl. */
11387 if (arg0 == error_mark_node
11388 || arg1 == error_mark_node
11389 || arg2 == error_mark_node)
11392 /* Check and prepare argument depending on the instruction code.
11394 Note that a switch statement instead of the sequence of tests
11395 would be incorrect as many of the CODE_FOR values could be
11396 CODE_FOR_nothing and that would yield multiple alternatives
11397 with identical values. We'd never reach here at runtime in
11399 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11400 || icode == CODE_FOR_altivec_vsldoi_v4si
11401 || icode == CODE_FOR_altivec_vsldoi_v8hi
11402 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11404 /* Only allow 4-bit unsigned literals. */
11406 if (TREE_CODE (arg2) != INTEGER_CST
11407 || TREE_INT_CST_LOW (arg2) & ~0xf)
11409 error ("argument 3 must be a 4-bit unsigned literal");
11413 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11414 || icode == CODE_FOR_vsx_xxpermdi_v2di
11415 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11416 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11417 || icode == CODE_FOR_vsx_xxsldwi_v4si
11418 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11419 || icode == CODE_FOR_vsx_xxsldwi_v2di
11420 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11422 /* Only allow 2-bit unsigned literals. */
11424 if (TREE_CODE (arg2) != INTEGER_CST
11425 || TREE_INT_CST_LOW (arg2) & ~0x3)
11427 error ("argument 3 must be a 2-bit unsigned literal");
11431 else if (icode == CODE_FOR_vsx_set_v2df
11432 || icode == CODE_FOR_vsx_set_v2di)
11434 /* Only allow 1-bit unsigned literals. */
11436 if (TREE_CODE (arg2) != INTEGER_CST
11437 || TREE_INT_CST_LOW (arg2) & ~0x1)
11439 error ("argument 3 must be a 1-bit unsigned literal");
11445 || GET_MODE (target) != tmode
11446 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11447 target = gen_reg_rtx (tmode);
11449 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11450 op0 = copy_to_mode_reg (mode0, op0);
11451 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11452 op1 = copy_to_mode_reg (mode1, op1);
11453 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11454 op2 = copy_to_mode_reg (mode2, op2);
11456 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11457 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11459 pat = GEN_FCN (icode) (target, op0, op1, op2);
11467 /* Expand the lvx builtins. */
11469 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11471 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11472 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11474 enum machine_mode tmode, mode0;
11476 enum insn_code icode;
11480 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11481 icode = CODE_FOR_vector_altivec_load_v16qi;
11483 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11484 icode = CODE_FOR_vector_altivec_load_v8hi;
11486 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11487 icode = CODE_FOR_vector_altivec_load_v4si;
11489 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11490 icode = CODE_FOR_vector_altivec_load_v4sf;
11492 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11493 icode = CODE_FOR_vector_altivec_load_v2df;
11495 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11496 icode = CODE_FOR_vector_altivec_load_v2di;
11499 *expandedp = false;
11505 arg0 = CALL_EXPR_ARG (exp, 0);
11506 op0 = expand_normal (arg0);
11507 tmode = insn_data[icode].operand[0].mode;
11508 mode0 = insn_data[icode].operand[1].mode;
11511 || GET_MODE (target) != tmode
11512 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11513 target = gen_reg_rtx (tmode);
11515 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11516 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11518 pat = GEN_FCN (icode) (target, op0);
11525 /* Expand the stvx builtins. */
11527 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11530 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11531 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11533 enum machine_mode mode0, mode1;
11535 enum insn_code icode;
11539 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11540 icode = CODE_FOR_vector_altivec_store_v16qi;
11542 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11543 icode = CODE_FOR_vector_altivec_store_v8hi;
11545 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11546 icode = CODE_FOR_vector_altivec_store_v4si;
11548 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11549 icode = CODE_FOR_vector_altivec_store_v4sf;
11551 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11552 icode = CODE_FOR_vector_altivec_store_v2df;
11554 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11555 icode = CODE_FOR_vector_altivec_store_v2di;
11558 *expandedp = false;
11562 arg0 = CALL_EXPR_ARG (exp, 0);
11563 arg1 = CALL_EXPR_ARG (exp, 1);
11564 op0 = expand_normal (arg0);
11565 op1 = expand_normal (arg1);
11566 mode0 = insn_data[icode].operand[0].mode;
11567 mode1 = insn_data[icode].operand[1].mode;
11569 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11570 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11571 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11572 op1 = copy_to_mode_reg (mode1, op1);
11574 pat = GEN_FCN (icode) (op0, op1);
11582 /* Expand the dst builtins. */
11584 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11587 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11588 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11589 tree arg0, arg1, arg2;
11590 enum machine_mode mode0, mode1;
11591 rtx pat, op0, op1, op2;
11592 const struct builtin_description *d;
11595 *expandedp = false;
11597 /* Handle DST variants. */
11599 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11600 if (d->code == fcode)
11602 arg0 = CALL_EXPR_ARG (exp, 0);
11603 arg1 = CALL_EXPR_ARG (exp, 1);
11604 arg2 = CALL_EXPR_ARG (exp, 2);
11605 op0 = expand_normal (arg0);
11606 op1 = expand_normal (arg1);
11607 op2 = expand_normal (arg2);
11608 mode0 = insn_data[d->icode].operand[0].mode;
11609 mode1 = insn_data[d->icode].operand[1].mode;
11611 /* Invalid arguments, bail out before generating bad rtl. */
11612 if (arg0 == error_mark_node
11613 || arg1 == error_mark_node
11614 || arg2 == error_mark_node)
11619 if (TREE_CODE (arg2) != INTEGER_CST
11620 || TREE_INT_CST_LOW (arg2) & ~0x3)
11622 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11626 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11627 op0 = copy_to_mode_reg (Pmode, op0);
11628 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11629 op1 = copy_to_mode_reg (mode1, op1);
11631 pat = GEN_FCN (d->icode) (op0, op1, op2);
11641 /* Expand vec_init builtin. */
11643 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11645 enum machine_mode tmode = TYPE_MODE (type);
11646 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11647 int i, n_elt = GET_MODE_NUNITS (tmode);
11648 rtvec v = rtvec_alloc (n_elt);
11650 gcc_assert (VECTOR_MODE_P (tmode));
11651 gcc_assert (n_elt == call_expr_nargs (exp));
11653 for (i = 0; i < n_elt; ++i)
11655 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11656 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11659 if (!target || !register_operand (target, tmode))
11660 target = gen_reg_rtx (tmode);
11662 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11666 /* Return the integer constant in ARG. Constrain it to be in the range
11667 of the subparts of VEC_TYPE; issue an error if not. */
11670 get_element_number (tree vec_type, tree arg)
11672 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11674 if (!host_integerp (arg, 1)
11675 || (elt = tree_low_cst (arg, 1), elt > max))
11677 error ("selector must be an integer constant in the range 0..%wi", max);
11684 /* Expand vec_set builtin. */
11686 altivec_expand_vec_set_builtin (tree exp)
11688 enum machine_mode tmode, mode1;
11689 tree arg0, arg1, arg2;
11693 arg0 = CALL_EXPR_ARG (exp, 0);
11694 arg1 = CALL_EXPR_ARG (exp, 1);
11695 arg2 = CALL_EXPR_ARG (exp, 2);
11697 tmode = TYPE_MODE (TREE_TYPE (arg0));
11698 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11699 gcc_assert (VECTOR_MODE_P (tmode));
11701 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11702 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11703 elt = get_element_number (TREE_TYPE (arg0), arg2);
11705 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11706 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11708 op0 = force_reg (tmode, op0);
11709 op1 = force_reg (mode1, op1);
11711 rs6000_expand_vector_set (op0, op1, elt);
11716 /* Expand vec_ext builtin. */
11718 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11720 enum machine_mode tmode, mode0;
11725 arg0 = CALL_EXPR_ARG (exp, 0);
11726 arg1 = CALL_EXPR_ARG (exp, 1);
11728 op0 = expand_normal (arg0);
11729 elt = get_element_number (TREE_TYPE (arg0), arg1);
11731 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11732 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11733 gcc_assert (VECTOR_MODE_P (mode0));
11735 op0 = force_reg (mode0, op0);
11737 if (optimize || !target || !register_operand (target, tmode))
11738 target = gen_reg_rtx (tmode);
11740 rs6000_expand_vector_extract (target, op0, elt);
11745 /* Expand the builtin in EXP and store the result in TARGET. Store
11746 true in *EXPANDEDP if we found a builtin to expand. */
11748 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11750 const struct builtin_description *d;
11751 const struct builtin_description_predicates *dp;
11753 enum insn_code icode;
11754 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11757 enum machine_mode tmode, mode0;
11758 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11760 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11761 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11762 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11763 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11766 error ("unresolved overload for Altivec builtin %qF", fndecl);
11770 target = altivec_expand_ld_builtin (exp, target, expandedp);
11774 target = altivec_expand_st_builtin (exp, target, expandedp);
11778 target = altivec_expand_dst_builtin (exp, target, expandedp);
11786 case ALTIVEC_BUILTIN_STVX:
11787 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11788 case ALTIVEC_BUILTIN_STVEBX:
11789 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11790 case ALTIVEC_BUILTIN_STVEHX:
11791 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11792 case ALTIVEC_BUILTIN_STVEWX:
11793 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11794 case ALTIVEC_BUILTIN_STVXL:
11795 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11797 case ALTIVEC_BUILTIN_STVLX:
11798 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11799 case ALTIVEC_BUILTIN_STVLXL:
11800 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11801 case ALTIVEC_BUILTIN_STVRX:
11802 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11803 case ALTIVEC_BUILTIN_STVRXL:
11804 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11806 case VSX_BUILTIN_STXVD2X_V2DF:
11807 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11808 case VSX_BUILTIN_STXVD2X_V2DI:
11809 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11810 case VSX_BUILTIN_STXVW4X_V4SF:
11811 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11812 case VSX_BUILTIN_STXVW4X_V4SI:
11813 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11814 case VSX_BUILTIN_STXVW4X_V8HI:
11815 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11816 case VSX_BUILTIN_STXVW4X_V16QI:
11817 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11819 case ALTIVEC_BUILTIN_MFVSCR:
11820 icode = CODE_FOR_altivec_mfvscr;
11821 tmode = insn_data[icode].operand[0].mode;
11824 || GET_MODE (target) != tmode
11825 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11826 target = gen_reg_rtx (tmode);
11828 pat = GEN_FCN (icode) (target);
11834 case ALTIVEC_BUILTIN_MTVSCR:
11835 icode = CODE_FOR_altivec_mtvscr;
11836 arg0 = CALL_EXPR_ARG (exp, 0);
11837 op0 = expand_normal (arg0);
11838 mode0 = insn_data[icode].operand[0].mode;
11840 /* If we got invalid arguments bail out before generating bad rtl. */
11841 if (arg0 == error_mark_node)
11844 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11845 op0 = copy_to_mode_reg (mode0, op0);
11847 pat = GEN_FCN (icode) (op0);
11852 case ALTIVEC_BUILTIN_DSSALL:
11853 emit_insn (gen_altivec_dssall ());
11856 case ALTIVEC_BUILTIN_DSS:
11857 icode = CODE_FOR_altivec_dss;
11858 arg0 = CALL_EXPR_ARG (exp, 0);
11860 op0 = expand_normal (arg0);
11861 mode0 = insn_data[icode].operand[0].mode;
11863 /* If we got invalid arguments bail out before generating bad rtl. */
11864 if (arg0 == error_mark_node)
11867 if (TREE_CODE (arg0) != INTEGER_CST
11868 || TREE_INT_CST_LOW (arg0) & ~0x3)
11870 error ("argument to dss must be a 2-bit unsigned literal");
11874 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11875 op0 = copy_to_mode_reg (mode0, op0);
11877 emit_insn (gen_altivec_dss (op0));
11880 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11881 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11882 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11883 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11884 case VSX_BUILTIN_VEC_INIT_V2DF:
11885 case VSX_BUILTIN_VEC_INIT_V2DI:
11886 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11888 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11889 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11890 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11891 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11892 case VSX_BUILTIN_VEC_SET_V2DF:
11893 case VSX_BUILTIN_VEC_SET_V2DI:
11894 return altivec_expand_vec_set_builtin (exp);
11896 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11897 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11898 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11899 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11900 case VSX_BUILTIN_VEC_EXT_V2DF:
11901 case VSX_BUILTIN_VEC_EXT_V2DI:
11902 return altivec_expand_vec_ext_builtin (exp, target);
11906 /* Fall through. */
11909 /* Expand abs* operations. */
11911 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11912 if (d->code == fcode)
11913 return altivec_expand_abs_builtin (d->icode, exp, target);
11915 /* Expand the AltiVec predicates. */
11916 dp = bdesc_altivec_preds;
11917 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11918 if (dp->code == fcode)
11919 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11921 /* LV* are funky. We initialized them differently. */
11924 case ALTIVEC_BUILTIN_LVSL:
11925 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11926 exp, target, false);
11927 case ALTIVEC_BUILTIN_LVSR:
11928 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11929 exp, target, false);
11930 case ALTIVEC_BUILTIN_LVEBX:
11931 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11932 exp, target, false);
11933 case ALTIVEC_BUILTIN_LVEHX:
11934 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11935 exp, target, false);
11936 case ALTIVEC_BUILTIN_LVEWX:
11937 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11938 exp, target, false);
11939 case ALTIVEC_BUILTIN_LVXL:
11940 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11941 exp, target, false);
11942 case ALTIVEC_BUILTIN_LVX:
11943 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11944 exp, target, false);
11945 case ALTIVEC_BUILTIN_LVLX:
11946 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11947 exp, target, true);
11948 case ALTIVEC_BUILTIN_LVLXL:
11949 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11950 exp, target, true);
11951 case ALTIVEC_BUILTIN_LVRX:
11952 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11953 exp, target, true);
11954 case ALTIVEC_BUILTIN_LVRXL:
11955 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11956 exp, target, true);
11957 case VSX_BUILTIN_LXVD2X_V2DF:
11958 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11959 exp, target, false);
11960 case VSX_BUILTIN_LXVD2X_V2DI:
11961 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11962 exp, target, false);
11963 case VSX_BUILTIN_LXVW4X_V4SF:
11964 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11965 exp, target, false);
11966 case VSX_BUILTIN_LXVW4X_V4SI:
11967 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11968 exp, target, false);
11969 case VSX_BUILTIN_LXVW4X_V8HI:
11970 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11971 exp, target, false);
11972 case VSX_BUILTIN_LXVW4X_V16QI:
11973 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11974 exp, target, false);
11978 /* Fall through. */
11981 *expandedp = false;
11985 /* Expand the builtin in EXP and store the result in TARGET. Store
11986 true in *EXPANDEDP if we found a builtin to expand. */
11988 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11990 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11991 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11992 const struct builtin_description *d;
11999 case PAIRED_BUILTIN_STX:
12000 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
12001 case PAIRED_BUILTIN_LX:
12002 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
12005 /* Fall through. */
12008 /* Expand the paired predicates. */
12009 d = bdesc_paired_preds;
12010 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
12011 if (d->code == fcode)
12012 return paired_expand_predicate_builtin (d->icode, exp, target);
12014 *expandedp = false;
12018 /* Binops that need to be initialized manually, but can be expanded
12019 automagically by rs6000_expand_binop_builtin. */
12020 static struct builtin_description bdesc_2arg_spe[] =
12022 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
12023 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
12024 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
12025 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
12026 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
12027 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
12028 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
12029 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
12030 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
12031 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
12032 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
12033 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
12034 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
12035 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
12036 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
12037 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
12038 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
12039 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
12040 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
12041 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
12042 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
12043 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
12046 /* Expand the builtin in EXP and store the result in TARGET. Store
12047 true in *EXPANDEDP if we found a builtin to expand.
12049 This expands the SPE builtins that are not simple unary and binary
12052 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
12054 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12056 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12057 enum insn_code icode;
12058 enum machine_mode tmode, mode0;
12060 struct builtin_description *d;
12065 /* Syntax check for a 5-bit unsigned immediate. */
12068 case SPE_BUILTIN_EVSTDD:
12069 case SPE_BUILTIN_EVSTDH:
12070 case SPE_BUILTIN_EVSTDW:
12071 case SPE_BUILTIN_EVSTWHE:
12072 case SPE_BUILTIN_EVSTWHO:
12073 case SPE_BUILTIN_EVSTWWE:
12074 case SPE_BUILTIN_EVSTWWO:
12075 arg1 = CALL_EXPR_ARG (exp, 2);
12076 if (TREE_CODE (arg1) != INTEGER_CST
12077 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12079 error ("argument 2 must be a 5-bit unsigned literal");
12087 /* The evsplat*i instructions are not quite generic. */
12090 case SPE_BUILTIN_EVSPLATFI:
12091 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12093 case SPE_BUILTIN_EVSPLATI:
12094 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12100 d = (struct builtin_description *) bdesc_2arg_spe;
12101 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12102 if (d->code == fcode)
12103 return rs6000_expand_binop_builtin (d->icode, exp, target);
12105 d = (struct builtin_description *) bdesc_spe_predicates;
12106 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12107 if (d->code == fcode)
12108 return spe_expand_predicate_builtin (d->icode, exp, target);
12110 d = (struct builtin_description *) bdesc_spe_evsel;
12111 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12112 if (d->code == fcode)
12113 return spe_expand_evsel_builtin (d->icode, exp, target);
12117 case SPE_BUILTIN_EVSTDDX:
12118 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12119 case SPE_BUILTIN_EVSTDHX:
12120 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12121 case SPE_BUILTIN_EVSTDWX:
12122 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12123 case SPE_BUILTIN_EVSTWHEX:
12124 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12125 case SPE_BUILTIN_EVSTWHOX:
12126 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12127 case SPE_BUILTIN_EVSTWWEX:
12128 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12129 case SPE_BUILTIN_EVSTWWOX:
12130 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12131 case SPE_BUILTIN_EVSTDD:
12132 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12133 case SPE_BUILTIN_EVSTDH:
12134 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12135 case SPE_BUILTIN_EVSTDW:
12136 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12137 case SPE_BUILTIN_EVSTWHE:
12138 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12139 case SPE_BUILTIN_EVSTWHO:
12140 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12141 case SPE_BUILTIN_EVSTWWE:
12142 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12143 case SPE_BUILTIN_EVSTWWO:
12144 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12145 case SPE_BUILTIN_MFSPEFSCR:
12146 icode = CODE_FOR_spe_mfspefscr;
12147 tmode = insn_data[icode].operand[0].mode;
12150 || GET_MODE (target) != tmode
12151 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12152 target = gen_reg_rtx (tmode);
12154 pat = GEN_FCN (icode) (target);
12159 case SPE_BUILTIN_MTSPEFSCR:
12160 icode = CODE_FOR_spe_mtspefscr;
12161 arg0 = CALL_EXPR_ARG (exp, 0);
12162 op0 = expand_normal (arg0);
12163 mode0 = insn_data[icode].operand[0].mode;
12165 if (arg0 == error_mark_node)
12168 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12169 op0 = copy_to_mode_reg (mode0, op0);
12171 pat = GEN_FCN (icode) (op0);
12179 *expandedp = false;
12184 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12186 rtx pat, scratch, tmp;
12187 tree form = CALL_EXPR_ARG (exp, 0);
12188 tree arg0 = CALL_EXPR_ARG (exp, 1);
12189 tree arg1 = CALL_EXPR_ARG (exp, 2);
12190 rtx op0 = expand_normal (arg0);
12191 rtx op1 = expand_normal (arg1);
12192 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12193 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12195 enum rtx_code code;
12197 if (TREE_CODE (form) != INTEGER_CST)
12199 error ("argument 1 of __builtin_paired_predicate must be a constant");
12203 form_int = TREE_INT_CST_LOW (form);
12205 gcc_assert (mode0 == mode1);
12207 if (arg0 == error_mark_node || arg1 == error_mark_node)
12211 || GET_MODE (target) != SImode
12212 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12213 target = gen_reg_rtx (SImode);
12214 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12215 op0 = copy_to_mode_reg (mode0, op0);
12216 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12217 op1 = copy_to_mode_reg (mode1, op1);
12219 scratch = gen_reg_rtx (CCFPmode);
12221 pat = GEN_FCN (icode) (scratch, op0, op1);
12243 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12246 error ("argument 1 of __builtin_paired_predicate is out of range");
12250 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12251 emit_move_insn (target, tmp);
12256 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12258 rtx pat, scratch, tmp;
12259 tree form = CALL_EXPR_ARG (exp, 0);
12260 tree arg0 = CALL_EXPR_ARG (exp, 1);
12261 tree arg1 = CALL_EXPR_ARG (exp, 2);
12262 rtx op0 = expand_normal (arg0);
12263 rtx op1 = expand_normal (arg1);
12264 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12265 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12267 enum rtx_code code;
12269 if (TREE_CODE (form) != INTEGER_CST)
12271 error ("argument 1 of __builtin_spe_predicate must be a constant");
12275 form_int = TREE_INT_CST_LOW (form);
12277 gcc_assert (mode0 == mode1);
12279 if (arg0 == error_mark_node || arg1 == error_mark_node)
12283 || GET_MODE (target) != SImode
12284 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12285 target = gen_reg_rtx (SImode);
12287 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12288 op0 = copy_to_mode_reg (mode0, op0);
12289 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12290 op1 = copy_to_mode_reg (mode1, op1);
12292 scratch = gen_reg_rtx (CCmode);
12294 pat = GEN_FCN (icode) (scratch, op0, op1);
12299 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12300 _lower_. We use one compare, but look in different bits of the
12301 CR for each variant.
12303 There are 2 elements in each SPE simd type (upper/lower). The CR
12304 bits are set as follows:
12306 BIT0 | BIT 1 | BIT 2 | BIT 3
12307 U | L | (U | L) | (U & L)
12309 So, for an "all" relationship, BIT 3 would be set.
12310 For an "any" relationship, BIT 2 would be set. Etc.
12312 Following traditional nomenclature, these bits map to:
12314 BIT0 | BIT 1 | BIT 2 | BIT 3
12317 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12322 /* All variant. OV bit. */
12324 /* We need to get to the OV bit, which is the ORDERED bit. We
12325 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12326 that's ugly and will make validate_condition_mode die.
12327 So let's just use another pattern. */
12328 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12330 /* Any variant. EQ bit. */
12334 /* Upper variant. LT bit. */
12338 /* Lower variant. GT bit. */
12343 error ("argument 1 of __builtin_spe_predicate is out of range");
12347 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12348 emit_move_insn (target, tmp);
12353 /* The evsel builtins look like this:
12355 e = __builtin_spe_evsel_OP (a, b, c, d);
12357 and work like this:
12359 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12360 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12364 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12367 tree arg0 = CALL_EXPR_ARG (exp, 0);
12368 tree arg1 = CALL_EXPR_ARG (exp, 1);
12369 tree arg2 = CALL_EXPR_ARG (exp, 2);
12370 tree arg3 = CALL_EXPR_ARG (exp, 3);
12371 rtx op0 = expand_normal (arg0);
12372 rtx op1 = expand_normal (arg1);
12373 rtx op2 = expand_normal (arg2);
12374 rtx op3 = expand_normal (arg3);
12375 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12376 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12378 gcc_assert (mode0 == mode1);
12380 if (arg0 == error_mark_node || arg1 == error_mark_node
12381 || arg2 == error_mark_node || arg3 == error_mark_node)
12385 || GET_MODE (target) != mode0
12386 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12387 target = gen_reg_rtx (mode0);
12389 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12390 op0 = copy_to_mode_reg (mode0, op0);
12391 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12392 op1 = copy_to_mode_reg (mode0, op1);
12393 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12394 op2 = copy_to_mode_reg (mode0, op2);
12395 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12396 op3 = copy_to_mode_reg (mode0, op3);
12398 /* Generate the compare. */
12399 scratch = gen_reg_rtx (CCmode);
12400 pat = GEN_FCN (icode) (scratch, op0, op1);
12405 if (mode0 == V2SImode)
12406 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12408 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12413 /* Expand an expression EXP that calls a built-in function,
12414 with result going to TARGET if that's convenient
12415 (and in mode MODE if that's convenient).
12416 SUBTARGET may be used as the target for computing one of EXP's operands.
12417 IGNORE is nonzero if the value is to be ignored. */
12420 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12421 enum machine_mode mode ATTRIBUTE_UNUSED,
12422 int ignore ATTRIBUTE_UNUSED)
12424 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12425 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12426 const struct builtin_description *d;
12433 case RS6000_BUILTIN_RECIP:
12434 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12436 case RS6000_BUILTIN_RECIPF:
12437 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12439 case RS6000_BUILTIN_RSQRTF:
12440 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12442 case RS6000_BUILTIN_RSQRT:
12443 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12445 case RS6000_BUILTIN_BSWAP_HI:
12446 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12448 case POWER7_BUILTIN_BPERMD:
12449 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12450 ? CODE_FOR_bpermd_di
12451 : CODE_FOR_bpermd_si), exp, target);
12453 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12454 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12456 int icode = (int) CODE_FOR_altivec_lvsr;
12457 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12458 enum machine_mode mode = insn_data[icode].operand[1].mode;
12462 gcc_assert (TARGET_ALTIVEC);
12464 arg = CALL_EXPR_ARG (exp, 0);
12465 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12466 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12467 addr = memory_address (mode, op);
12468 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12472 /* For the load case need to negate the address. */
12473 op = gen_reg_rtx (GET_MODE (addr));
12474 emit_insn (gen_rtx_SET (VOIDmode, op,
12475 gen_rtx_NEG (GET_MODE (addr), addr)));
12477 op = gen_rtx_MEM (mode, op);
12480 || GET_MODE (target) != tmode
12481 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12482 target = gen_reg_rtx (tmode);
12484 /*pat = gen_altivec_lvsr (target, op);*/
12485 pat = GEN_FCN (icode) (target, op);
12493 case ALTIVEC_BUILTIN_VCFUX:
12494 case ALTIVEC_BUILTIN_VCFSX:
12495 case ALTIVEC_BUILTIN_VCTUXS:
12496 case ALTIVEC_BUILTIN_VCTSXS:
12497 /* FIXME: There's got to be a nicer way to handle this case than
12498 constructing a new CALL_EXPR. */
12499 if (call_expr_nargs (exp) == 1)
12501 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12502 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12510 if (TARGET_ALTIVEC)
12512 ret = altivec_expand_builtin (exp, target, &success);
12519 ret = spe_expand_builtin (exp, target, &success);
12524 if (TARGET_PAIRED_FLOAT)
12526 ret = paired_expand_builtin (exp, target, &success);
12532 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12534 /* Handle simple unary operations. */
12535 d = (struct builtin_description *) bdesc_1arg;
12536 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12537 if (d->code == fcode)
12538 return rs6000_expand_unop_builtin (d->icode, exp, target);
12540 /* Handle simple binary operations. */
12541 d = (struct builtin_description *) bdesc_2arg;
12542 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12543 if (d->code == fcode)
12544 return rs6000_expand_binop_builtin (d->icode, exp, target);
12546 /* Handle simple ternary operations. */
12548 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12549 if (d->code == fcode)
12550 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12552 gcc_unreachable ();
12556 rs6000_init_builtins (void)
12561 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12562 V2SF_type_node = build_vector_type (float_type_node, 2);
12563 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12564 V2DF_type_node = build_vector_type (double_type_node, 2);
12565 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12566 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12567 V4SF_type_node = build_vector_type (float_type_node, 4);
12568 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12569 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12571 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12572 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12573 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12574 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12576 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12577 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12578 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12579 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12581 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12582 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12583 'vector unsigned short'. */
12585 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12586 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12587 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12588 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12589 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12591 long_integer_type_internal_node = long_integer_type_node;
12592 long_unsigned_type_internal_node = long_unsigned_type_node;
12593 long_long_integer_type_internal_node = long_long_integer_type_node;
12594 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12595 intQI_type_internal_node = intQI_type_node;
12596 uintQI_type_internal_node = unsigned_intQI_type_node;
12597 intHI_type_internal_node = intHI_type_node;
12598 uintHI_type_internal_node = unsigned_intHI_type_node;
12599 intSI_type_internal_node = intSI_type_node;
12600 uintSI_type_internal_node = unsigned_intSI_type_node;
12601 intDI_type_internal_node = intDI_type_node;
12602 uintDI_type_internal_node = unsigned_intDI_type_node;
12603 float_type_internal_node = float_type_node;
12604 double_type_internal_node = double_type_node;
12605 void_type_internal_node = void_type_node;
12607 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12609 builtin_mode_to_type[QImode][0] = integer_type_node;
12610 builtin_mode_to_type[HImode][0] = integer_type_node;
12611 builtin_mode_to_type[SImode][0] = intSI_type_node;
12612 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12613 builtin_mode_to_type[DImode][0] = intDI_type_node;
12614 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12615 builtin_mode_to_type[SFmode][0] = float_type_node;
12616 builtin_mode_to_type[DFmode][0] = double_type_node;
12617 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12618 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12619 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12620 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12621 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12622 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12623 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12624 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12625 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12626 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12627 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12628 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12629 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12631 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12632 get_identifier ("__bool char"),
12633 bool_char_type_node);
12634 TYPE_NAME (bool_char_type_node) = tdecl;
12635 (*lang_hooks.decls.pushdecl) (tdecl);
12636 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12637 get_identifier ("__bool short"),
12638 bool_short_type_node);
12639 TYPE_NAME (bool_short_type_node) = tdecl;
12640 (*lang_hooks.decls.pushdecl) (tdecl);
12641 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12642 get_identifier ("__bool int"),
12643 bool_int_type_node);
12644 TYPE_NAME (bool_int_type_node) = tdecl;
12645 (*lang_hooks.decls.pushdecl) (tdecl);
12646 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12648 TYPE_NAME (pixel_type_node) = tdecl;
12649 (*lang_hooks.decls.pushdecl) (tdecl);
12651 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12652 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12653 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12654 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12655 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12657 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12658 get_identifier ("__vector unsigned char"),
12659 unsigned_V16QI_type_node);
12660 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12661 (*lang_hooks.decls.pushdecl) (tdecl);
12662 tdecl = build_decl (BUILTINS_LOCATION,
12663 TYPE_DECL, get_identifier ("__vector signed char"),
12665 TYPE_NAME (V16QI_type_node) = tdecl;
12666 (*lang_hooks.decls.pushdecl) (tdecl);
12667 tdecl = build_decl (BUILTINS_LOCATION,
12668 TYPE_DECL, get_identifier ("__vector __bool char"),
12669 bool_V16QI_type_node);
12670 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12671 (*lang_hooks.decls.pushdecl) (tdecl);
12673 tdecl = build_decl (BUILTINS_LOCATION,
12674 TYPE_DECL, get_identifier ("__vector unsigned short"),
12675 unsigned_V8HI_type_node);
12676 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12677 (*lang_hooks.decls.pushdecl) (tdecl);
12678 tdecl = build_decl (BUILTINS_LOCATION,
12679 TYPE_DECL, get_identifier ("__vector signed short"),
12681 TYPE_NAME (V8HI_type_node) = tdecl;
12682 (*lang_hooks.decls.pushdecl) (tdecl);
12683 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12684 get_identifier ("__vector __bool short"),
12685 bool_V8HI_type_node);
12686 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12687 (*lang_hooks.decls.pushdecl) (tdecl);
12689 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12690 get_identifier ("__vector unsigned int"),
12691 unsigned_V4SI_type_node);
12692 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12693 (*lang_hooks.decls.pushdecl) (tdecl);
12694 tdecl = build_decl (BUILTINS_LOCATION,
12695 TYPE_DECL, get_identifier ("__vector signed int"),
12697 TYPE_NAME (V4SI_type_node) = tdecl;
12698 (*lang_hooks.decls.pushdecl) (tdecl);
12699 tdecl = build_decl (BUILTINS_LOCATION,
12700 TYPE_DECL, get_identifier ("__vector __bool int"),
12701 bool_V4SI_type_node);
12702 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12703 (*lang_hooks.decls.pushdecl) (tdecl);
12705 tdecl = build_decl (BUILTINS_LOCATION,
12706 TYPE_DECL, get_identifier ("__vector float"),
12708 TYPE_NAME (V4SF_type_node) = tdecl;
12709 (*lang_hooks.decls.pushdecl) (tdecl);
12710 tdecl = build_decl (BUILTINS_LOCATION,
12711 TYPE_DECL, get_identifier ("__vector __pixel"),
12712 pixel_V8HI_type_node);
12713 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12714 (*lang_hooks.decls.pushdecl) (tdecl);
12718 tdecl = build_decl (BUILTINS_LOCATION,
12719 TYPE_DECL, get_identifier ("__vector double"),
12721 TYPE_NAME (V2DF_type_node) = tdecl;
12722 (*lang_hooks.decls.pushdecl) (tdecl);
12724 tdecl = build_decl (BUILTINS_LOCATION,
12725 TYPE_DECL, get_identifier ("__vector long"),
12727 TYPE_NAME (V2DI_type_node) = tdecl;
12728 (*lang_hooks.decls.pushdecl) (tdecl);
12730 tdecl = build_decl (BUILTINS_LOCATION,
12731 TYPE_DECL, get_identifier ("__vector unsigned long"),
12732 unsigned_V2DI_type_node);
12733 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12734 (*lang_hooks.decls.pushdecl) (tdecl);
12736 tdecl = build_decl (BUILTINS_LOCATION,
12737 TYPE_DECL, get_identifier ("__vector __bool long"),
12738 bool_V2DI_type_node);
12739 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12740 (*lang_hooks.decls.pushdecl) (tdecl);
12743 if (TARGET_PAIRED_FLOAT)
12744 paired_init_builtins ();
12746 spe_init_builtins ();
12747 if (TARGET_ALTIVEC)
12748 altivec_init_builtins ();
12749 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12750 rs6000_common_init_builtins ();
12753 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12754 RS6000_BUILTIN_RECIP,
12755 "__builtin_recipdiv");
12756 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12757 RS6000_BUILTIN_RECIP);
12761 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12762 RS6000_BUILTIN_RECIPF,
12763 "__builtin_recipdivf");
12764 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12765 RS6000_BUILTIN_RECIPF);
12767 if (TARGET_FRSQRTE)
12769 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12770 RS6000_BUILTIN_RSQRT,
12771 "__builtin_rsqrt");
12772 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12773 RS6000_BUILTIN_RSQRT);
12775 if (TARGET_FRSQRTES)
12777 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12778 RS6000_BUILTIN_RSQRTF,
12779 "__builtin_rsqrtf");
12780 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12781 RS6000_BUILTIN_RSQRTF);
12783 if (TARGET_POPCNTD)
12785 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12786 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12787 POWER7_BUILTIN_BPERMD,
12788 "__builtin_bpermd");
12789 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12790 POWER7_BUILTIN_BPERMD);
12792 if (TARGET_POWERPC)
12794 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12795 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12796 unsigned_intHI_type_node,
12798 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12799 RS6000_BUILTIN_BSWAP_HI);
12803 /* AIX libm provides clog as __clog. */
12804 if (built_in_decls [BUILT_IN_CLOG])
12805 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12808 #ifdef SUBTARGET_INIT_BUILTINS
12809 SUBTARGET_INIT_BUILTINS;
12813 /* Returns the rs6000 builtin decl for CODE. */
12816 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12818 if (code >= RS6000_BUILTIN_COUNT)
12819 return error_mark_node;
12821 return rs6000_builtin_decls[code];
12824 /* Search through a set of builtins and enable the mask bits.
12825 DESC is an array of builtins.
12826 SIZE is the total number of builtins.
12827 START is the builtin enum at which to start.
12828 END is the builtin enum at which to end. */
12830 enable_mask_for_builtins (struct builtin_description *desc, int size,
12831 enum rs6000_builtins start,
12832 enum rs6000_builtins end)
12836 for (i = 0; i < size; ++i)
12837 if (desc[i].code == start)
12843 for (; i < size; ++i)
12845 /* Flip all the bits on. */
12846 desc[i].mask = target_flags;
12847 if (desc[i].code == end)
12853 spe_init_builtins (void)
12855 tree endlink = void_list_node;
12856 tree puint_type_node = build_pointer_type (unsigned_type_node);
12857 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12858 struct builtin_description *d;
12861 tree v2si_ftype_4_v2si
12862 = build_function_type
12863 (opaque_V2SI_type_node,
12864 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12865 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12866 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12867 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12870 tree v2sf_ftype_4_v2sf
12871 = build_function_type
12872 (opaque_V2SF_type_node,
12873 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12874 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12875 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12876 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12879 tree int_ftype_int_v2si_v2si
12880 = build_function_type
12881 (integer_type_node,
12882 tree_cons (NULL_TREE, integer_type_node,
12883 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12884 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12887 tree int_ftype_int_v2sf_v2sf
12888 = build_function_type
12889 (integer_type_node,
12890 tree_cons (NULL_TREE, integer_type_node,
12891 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12892 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12895 tree void_ftype_v2si_puint_int
12896 = build_function_type (void_type_node,
12897 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12898 tree_cons (NULL_TREE, puint_type_node,
12899 tree_cons (NULL_TREE,
12903 tree void_ftype_v2si_puint_char
12904 = build_function_type (void_type_node,
12905 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12906 tree_cons (NULL_TREE, puint_type_node,
12907 tree_cons (NULL_TREE,
12911 tree void_ftype_v2si_pv2si_int
12912 = build_function_type (void_type_node,
12913 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12914 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12915 tree_cons (NULL_TREE,
12919 tree void_ftype_v2si_pv2si_char
12920 = build_function_type (void_type_node,
12921 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12922 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12923 tree_cons (NULL_TREE,
12927 tree void_ftype_int
12928 = build_function_type (void_type_node,
12929 tree_cons (NULL_TREE, integer_type_node, endlink));
12931 tree int_ftype_void
12932 = build_function_type (integer_type_node, endlink);
12934 tree v2si_ftype_pv2si_int
12935 = build_function_type (opaque_V2SI_type_node,
12936 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12937 tree_cons (NULL_TREE, integer_type_node,
12940 tree v2si_ftype_puint_int
12941 = build_function_type (opaque_V2SI_type_node,
12942 tree_cons (NULL_TREE, puint_type_node,
12943 tree_cons (NULL_TREE, integer_type_node,
12946 tree v2si_ftype_pushort_int
12947 = build_function_type (opaque_V2SI_type_node,
12948 tree_cons (NULL_TREE, pushort_type_node,
12949 tree_cons (NULL_TREE, integer_type_node,
12952 tree v2si_ftype_signed_char
12953 = build_function_type (opaque_V2SI_type_node,
12954 tree_cons (NULL_TREE, signed_char_type_node,
12957 /* The initialization of the simple binary and unary builtins is
12958 done in rs6000_common_init_builtins, but we have to enable the
12959 mask bits here manually because we have run out of `target_flags'
12960 bits. We really need to redesign this mask business. */
12962 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12963 ARRAY_SIZE (bdesc_2arg),
12964 SPE_BUILTIN_EVADDW,
12965 SPE_BUILTIN_EVXOR);
12966 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12967 ARRAY_SIZE (bdesc_1arg),
12969 SPE_BUILTIN_EVSUBFUSIAAW);
12970 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12971 ARRAY_SIZE (bdesc_spe_predicates),
12972 SPE_BUILTIN_EVCMPEQ,
12973 SPE_BUILTIN_EVFSTSTLT);
12974 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12975 ARRAY_SIZE (bdesc_spe_evsel),
12976 SPE_BUILTIN_EVSEL_CMPGTS,
12977 SPE_BUILTIN_EVSEL_FSTSTEQ);
12979 (*lang_hooks.decls.pushdecl)
12980 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12981 get_identifier ("__ev64_opaque__"),
12982 opaque_V2SI_type_node));
12984 /* Initialize irregular SPE builtins. */
12986 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12987 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12988 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12989 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12990 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12991 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12992 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12993 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12994 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12995 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12996 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12997 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12998 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12999 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
13000 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
13001 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
13002 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
13003 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
13006 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
13007 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
13008 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
13009 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
13010 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
13011 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
13012 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
13013 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
13014 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
13015 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
13016 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
13017 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
13018 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
13019 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
13020 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
13021 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
13022 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
13023 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
13024 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
13025 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
13026 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
13027 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
13030 d = (struct builtin_description *) bdesc_spe_predicates;
13031 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
13035 switch (insn_data[d->icode].operand[1].mode)
13038 type = int_ftype_int_v2si_v2si;
13041 type = int_ftype_int_v2sf_v2sf;
13044 gcc_unreachable ();
13047 def_builtin (d->mask, d->name, type, d->code);
13050 /* Evsel predicates. */
13051 d = (struct builtin_description *) bdesc_spe_evsel;
13052 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
13056 switch (insn_data[d->icode].operand[1].mode)
13059 type = v2si_ftype_4_v2si;
13062 type = v2sf_ftype_4_v2sf;
13065 gcc_unreachable ();
13068 def_builtin (d->mask, d->name, type, d->code);
13073 paired_init_builtins (void)
13075 const struct builtin_description *d;
13077 tree endlink = void_list_node;
13079 tree int_ftype_int_v2sf_v2sf
13080 = build_function_type
13081 (integer_type_node,
13082 tree_cons (NULL_TREE, integer_type_node,
13083 tree_cons (NULL_TREE, V2SF_type_node,
13084 tree_cons (NULL_TREE, V2SF_type_node,
13086 tree pcfloat_type_node =
13087 build_pointer_type (build_qualified_type
13088 (float_type_node, TYPE_QUAL_CONST));
13090 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13091 long_integer_type_node,
13094 tree void_ftype_v2sf_long_pcfloat =
13095 build_function_type_list (void_type_node,
13097 long_integer_type_node,
13102 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13103 PAIRED_BUILTIN_LX);
13106 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13107 PAIRED_BUILTIN_STX);
13110 d = bdesc_paired_preds;
13111 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13115 switch (insn_data[d->icode].operand[1].mode)
13118 type = int_ftype_int_v2sf_v2sf;
13121 gcc_unreachable ();
13124 def_builtin (d->mask, d->name, type, d->code);
13129 altivec_init_builtins (void)
13131 const struct builtin_description *d;
13132 const struct builtin_description_predicates *dp;
13136 tree pvoid_type_node = build_pointer_type (void_type_node);
13138 tree pcvoid_type_node
13139 = build_pointer_type (build_qualified_type (void_type_node,
13142 tree int_ftype_opaque
13143 = build_function_type_list (integer_type_node,
13144 opaque_V4SI_type_node, NULL_TREE);
13145 tree opaque_ftype_opaque
13146 = build_function_type (integer_type_node,
13148 tree opaque_ftype_opaque_int
13149 = build_function_type_list (opaque_V4SI_type_node,
13150 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13151 tree opaque_ftype_opaque_opaque_int
13152 = build_function_type_list (opaque_V4SI_type_node,
13153 opaque_V4SI_type_node, opaque_V4SI_type_node,
13154 integer_type_node, NULL_TREE);
13155 tree int_ftype_int_opaque_opaque
13156 = build_function_type_list (integer_type_node,
13157 integer_type_node, opaque_V4SI_type_node,
13158 opaque_V4SI_type_node, NULL_TREE);
13159 tree int_ftype_int_v4si_v4si
13160 = build_function_type_list (integer_type_node,
13161 integer_type_node, V4SI_type_node,
13162 V4SI_type_node, NULL_TREE);
13163 tree void_ftype_v4si
13164 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13165 tree v8hi_ftype_void
13166 = build_function_type (V8HI_type_node, void_list_node);
13167 tree void_ftype_void
13168 = build_function_type (void_type_node, void_list_node);
13169 tree void_ftype_int
13170 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13172 tree opaque_ftype_long_pcvoid
13173 = build_function_type_list (opaque_V4SI_type_node,
13174 long_integer_type_node, pcvoid_type_node,
13176 tree v16qi_ftype_long_pcvoid
13177 = build_function_type_list (V16QI_type_node,
13178 long_integer_type_node, pcvoid_type_node,
13180 tree v8hi_ftype_long_pcvoid
13181 = build_function_type_list (V8HI_type_node,
13182 long_integer_type_node, pcvoid_type_node,
13184 tree v4si_ftype_long_pcvoid
13185 = build_function_type_list (V4SI_type_node,
13186 long_integer_type_node, pcvoid_type_node,
13188 tree v4sf_ftype_long_pcvoid
13189 = build_function_type_list (V4SF_type_node,
13190 long_integer_type_node, pcvoid_type_node,
13192 tree v2df_ftype_long_pcvoid
13193 = build_function_type_list (V2DF_type_node,
13194 long_integer_type_node, pcvoid_type_node,
13196 tree v2di_ftype_long_pcvoid
13197 = build_function_type_list (V2DI_type_node,
13198 long_integer_type_node, pcvoid_type_node,
13201 tree void_ftype_opaque_long_pvoid
13202 = build_function_type_list (void_type_node,
13203 opaque_V4SI_type_node, long_integer_type_node,
13204 pvoid_type_node, NULL_TREE);
13205 tree void_ftype_v4si_long_pvoid
13206 = build_function_type_list (void_type_node,
13207 V4SI_type_node, long_integer_type_node,
13208 pvoid_type_node, NULL_TREE);
13209 tree void_ftype_v16qi_long_pvoid
13210 = build_function_type_list (void_type_node,
13211 V16QI_type_node, long_integer_type_node,
13212 pvoid_type_node, NULL_TREE);
13213 tree void_ftype_v8hi_long_pvoid
13214 = build_function_type_list (void_type_node,
13215 V8HI_type_node, long_integer_type_node,
13216 pvoid_type_node, NULL_TREE);
13217 tree void_ftype_v4sf_long_pvoid
13218 = build_function_type_list (void_type_node,
13219 V4SF_type_node, long_integer_type_node,
13220 pvoid_type_node, NULL_TREE);
13221 tree void_ftype_v2df_long_pvoid
13222 = build_function_type_list (void_type_node,
13223 V2DF_type_node, long_integer_type_node,
13224 pvoid_type_node, NULL_TREE);
13225 tree void_ftype_v2di_long_pvoid
13226 = build_function_type_list (void_type_node,
13227 V2DI_type_node, long_integer_type_node,
13228 pvoid_type_node, NULL_TREE);
13229 tree int_ftype_int_v8hi_v8hi
13230 = build_function_type_list (integer_type_node,
13231 integer_type_node, V8HI_type_node,
13232 V8HI_type_node, NULL_TREE);
13233 tree int_ftype_int_v16qi_v16qi
13234 = build_function_type_list (integer_type_node,
13235 integer_type_node, V16QI_type_node,
13236 V16QI_type_node, NULL_TREE);
13237 tree int_ftype_int_v4sf_v4sf
13238 = build_function_type_list (integer_type_node,
13239 integer_type_node, V4SF_type_node,
13240 V4SF_type_node, NULL_TREE);
13241 tree int_ftype_int_v2df_v2df
13242 = build_function_type_list (integer_type_node,
13243 integer_type_node, V2DF_type_node,
13244 V2DF_type_node, NULL_TREE);
13245 tree v4si_ftype_v4si
13246 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13247 tree v8hi_ftype_v8hi
13248 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13249 tree v16qi_ftype_v16qi
13250 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13251 tree v4sf_ftype_v4sf
13252 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13253 tree v2df_ftype_v2df
13254 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13255 tree void_ftype_pcvoid_int_int
13256 = build_function_type_list (void_type_node,
13257 pcvoid_type_node, integer_type_node,
13258 integer_type_node, NULL_TREE);
13260 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13261 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13262 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13263 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13264 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13265 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13266 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13267 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13268 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13269 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13270 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13271 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13272 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13273 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13274 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13275 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13276 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13277 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13278 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13279 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13280 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13281 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13282 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13283 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13284 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13285 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13286 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13287 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13288 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13289 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13291 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13292 VSX_BUILTIN_LXVD2X_V2DF);
13293 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13294 VSX_BUILTIN_LXVD2X_V2DI);
13295 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13296 VSX_BUILTIN_LXVW4X_V4SF);
13297 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13298 VSX_BUILTIN_LXVW4X_V4SI);
13299 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13300 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13301 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13302 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13303 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13304 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13305 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13306 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13307 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13308 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13309 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13310 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13311 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13312 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13313 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13314 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13315 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13316 VSX_BUILTIN_VEC_LD);
13317 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13318 VSX_BUILTIN_VEC_ST);
13320 if (rs6000_cpu == PROCESSOR_CELL)
13322 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13323 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13324 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13325 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13327 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13328 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13329 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13330 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13332 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13333 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13334 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13335 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13337 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13338 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13339 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13340 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13342 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13343 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13344 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13346 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13347 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13348 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13349 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13350 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13351 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13352 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13353 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13354 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13355 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13356 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13357 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13359 /* Add the DST variants. */
13361 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13362 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13364 /* Initialize the predicates. */
13365 dp = bdesc_altivec_preds;
13366 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13368 enum machine_mode mode1;
13370 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13371 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13372 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13373 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13378 mode1 = insn_data[dp->icode].operand[1].mode;
13383 type = int_ftype_int_opaque_opaque;
13386 type = int_ftype_int_v4si_v4si;
13389 type = int_ftype_int_v8hi_v8hi;
13392 type = int_ftype_int_v16qi_v16qi;
13395 type = int_ftype_int_v4sf_v4sf;
13398 type = int_ftype_int_v2df_v2df;
13401 gcc_unreachable ();
13404 def_builtin (dp->mask, dp->name, type, dp->code);
13407 /* Initialize the abs* operators. */
13409 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13411 enum machine_mode mode0;
13414 mode0 = insn_data[d->icode].operand[0].mode;
13419 type = v4si_ftype_v4si;
13422 type = v8hi_ftype_v8hi;
13425 type = v16qi_ftype_v16qi;
13428 type = v4sf_ftype_v4sf;
13431 type = v2df_ftype_v2df;
13434 gcc_unreachable ();
13437 def_builtin (d->mask, d->name, type, d->code);
13440 if (TARGET_ALTIVEC)
13444 /* Initialize target builtin that implements
13445 targetm.vectorize.builtin_mask_for_load. */
13447 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13448 v16qi_ftype_long_pcvoid,
13449 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13450 BUILT_IN_MD, NULL, NULL_TREE);
13451 TREE_READONLY (decl) = 1;
13452 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13453 altivec_builtin_mask_for_load = decl;
13456 /* Access to the vec_init patterns. */
13457 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13458 integer_type_node, integer_type_node,
13459 integer_type_node, NULL_TREE);
13460 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13461 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13463 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13464 short_integer_type_node,
13465 short_integer_type_node,
13466 short_integer_type_node,
13467 short_integer_type_node,
13468 short_integer_type_node,
13469 short_integer_type_node,
13470 short_integer_type_node, NULL_TREE);
13471 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13472 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13474 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13475 char_type_node, char_type_node,
13476 char_type_node, char_type_node,
13477 char_type_node, char_type_node,
13478 char_type_node, char_type_node,
13479 char_type_node, char_type_node,
13480 char_type_node, char_type_node,
13481 char_type_node, char_type_node,
13482 char_type_node, NULL_TREE);
13483 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13484 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13486 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13487 float_type_node, float_type_node,
13488 float_type_node, NULL_TREE);
13489 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13490 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13494 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13495 double_type_node, NULL_TREE);
13496 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13497 VSX_BUILTIN_VEC_INIT_V2DF);
13499 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13500 intDI_type_node, NULL_TREE);
13501 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13502 VSX_BUILTIN_VEC_INIT_V2DI);
13505 /* Access to the vec_set patterns. */
13506 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13508 integer_type_node, NULL_TREE);
13509 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13510 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13512 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13514 integer_type_node, NULL_TREE);
13515 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13516 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13518 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13520 integer_type_node, NULL_TREE);
13521 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13522 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13524 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13526 integer_type_node, NULL_TREE);
13527 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13528 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13532 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13534 integer_type_node, NULL_TREE);
13535 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13536 VSX_BUILTIN_VEC_SET_V2DF);
13538 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13540 integer_type_node, NULL_TREE);
13541 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13542 VSX_BUILTIN_VEC_SET_V2DI);
13545 /* Access to the vec_extract patterns. */
13546 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13547 integer_type_node, NULL_TREE);
13548 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13549 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13551 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13552 integer_type_node, NULL_TREE);
13553 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13554 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13556 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13557 integer_type_node, NULL_TREE);
13558 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13559 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13561 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13562 integer_type_node, NULL_TREE);
13563 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13564 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13568 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13569 integer_type_node, NULL_TREE);
13570 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13571 VSX_BUILTIN_VEC_EXT_V2DF);
13573 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13574 integer_type_node, NULL_TREE);
13575 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13576 VSX_BUILTIN_VEC_EXT_V2DI);
13580 /* Hash function for builtin functions with up to 3 arguments and a return
13583 builtin_hash_function (const void *hash_entry)
13587 const struct builtin_hash_struct *bh =
13588 (const struct builtin_hash_struct *) hash_entry;
13590 for (i = 0; i < 4; i++)
13592 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13593 ret = (ret * 2) + bh->uns_p[i];
13599 /* Compare builtin hash entries H1 and H2 for equivalence. */
13601 builtin_hash_eq (const void *h1, const void *h2)
13603 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13604 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13606 return ((p1->mode[0] == p2->mode[0])
13607 && (p1->mode[1] == p2->mode[1])
13608 && (p1->mode[2] == p2->mode[2])
13609 && (p1->mode[3] == p2->mode[3])
13610 && (p1->uns_p[0] == p2->uns_p[0])
13611 && (p1->uns_p[1] == p2->uns_p[1])
13612 && (p1->uns_p[2] == p2->uns_p[2])
13613 && (p1->uns_p[3] == p2->uns_p[3]));
13616 /* Map types for builtin functions with an explicit return type and up to 3
13617 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13618 of the argument. */
13620 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13621 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13622 enum rs6000_builtins builtin, const char *name)
13624 struct builtin_hash_struct h;
13625 struct builtin_hash_struct *h2;
13629 tree ret_type = NULL_TREE;
13630 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13633 /* Create builtin_hash_table. */
13634 if (builtin_hash_table == NULL)
13635 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13636 builtin_hash_eq, NULL);
13638 h.type = NULL_TREE;
13639 h.mode[0] = mode_ret;
13640 h.mode[1] = mode_arg0;
13641 h.mode[2] = mode_arg1;
13642 h.mode[3] = mode_arg2;
13648 /* If the builtin is a type that produces unsigned results or takes unsigned
13649 arguments, and it is returned as a decl for the vectorizer (such as
13650 widening multiplies, permute), make sure the arguments and return value
13651 are type correct. */
13654 /* unsigned 2 argument functions. */
13655 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13656 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13657 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13658 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13664 /* unsigned 3 argument functions. */
13665 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13666 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13667 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13668 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13669 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13670 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13671 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13672 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13673 case VSX_BUILTIN_VPERM_16QI_UNS:
13674 case VSX_BUILTIN_VPERM_8HI_UNS:
13675 case VSX_BUILTIN_VPERM_4SI_UNS:
13676 case VSX_BUILTIN_VPERM_2DI_UNS:
13677 case VSX_BUILTIN_XXSEL_16QI_UNS:
13678 case VSX_BUILTIN_XXSEL_8HI_UNS:
13679 case VSX_BUILTIN_XXSEL_4SI_UNS:
13680 case VSX_BUILTIN_XXSEL_2DI_UNS:
13687 /* signed permute functions with unsigned char mask. */
13688 case ALTIVEC_BUILTIN_VPERM_16QI:
13689 case ALTIVEC_BUILTIN_VPERM_8HI:
13690 case ALTIVEC_BUILTIN_VPERM_4SI:
13691 case ALTIVEC_BUILTIN_VPERM_4SF:
13692 case ALTIVEC_BUILTIN_VPERM_2DI:
13693 case ALTIVEC_BUILTIN_VPERM_2DF:
13694 case VSX_BUILTIN_VPERM_16QI:
13695 case VSX_BUILTIN_VPERM_8HI:
13696 case VSX_BUILTIN_VPERM_4SI:
13697 case VSX_BUILTIN_VPERM_4SF:
13698 case VSX_BUILTIN_VPERM_2DI:
13699 case VSX_BUILTIN_VPERM_2DF:
13703 /* unsigned args, signed return. */
13704 case VSX_BUILTIN_XVCVUXDDP_UNS:
13705 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13709 /* signed args, unsigned return. */
13710 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13711 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13719 /* Figure out how many args are present. */
13720 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13724 fatal_error ("internal error: builtin function %s had no type", name);
13726 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13727 if (!ret_type && h.uns_p[0])
13728 ret_type = builtin_mode_to_type[h.mode[0]][0];
13731 fatal_error ("internal error: builtin function %s had an unexpected "
13732 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13734 for (i = 0; i < num_args; i++)
13736 int m = (int) h.mode[i+1];
13737 int uns_p = h.uns_p[i+1];
13739 arg_type[i] = builtin_mode_to_type[m][uns_p];
13740 if (!arg_type[i] && uns_p)
13741 arg_type[i] = builtin_mode_to_type[m][0];
13744 fatal_error ("internal error: builtin function %s, argument %d "
13745 "had unexpected argument type %s", name, i,
13746 GET_MODE_NAME (m));
13749 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13750 if (*found == NULL)
13752 h2 = ggc_alloc_builtin_hash_struct ();
13754 *found = (void *)h2;
13755 args = void_list_node;
13757 for (i = num_args - 1; i >= 0; i--)
13758 args = tree_cons (NULL_TREE, arg_type[i], args);
13760 h2->type = build_function_type (ret_type, args);
13763 return ((struct builtin_hash_struct *)(*found))->type;
13767 rs6000_common_init_builtins (void)
13769 const struct builtin_description *d;
13772 tree opaque_ftype_opaque = NULL_TREE;
13773 tree opaque_ftype_opaque_opaque = NULL_TREE;
13774 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13775 tree v2si_ftype_qi = NULL_TREE;
13776 tree v2si_ftype_v2si_qi = NULL_TREE;
13777 tree v2si_ftype_int_qi = NULL_TREE;
13779 if (!TARGET_PAIRED_FLOAT)
13781 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13782 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13785 /* Add the ternary operators. */
13787 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13790 int mask = d->mask;
13792 if ((mask != 0 && (mask & target_flags) == 0)
13793 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13796 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13797 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13798 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13799 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13801 if (! (type = opaque_ftype_opaque_opaque_opaque))
13802 type = opaque_ftype_opaque_opaque_opaque
13803 = build_function_type_list (opaque_V4SI_type_node,
13804 opaque_V4SI_type_node,
13805 opaque_V4SI_type_node,
13806 opaque_V4SI_type_node,
13811 enum insn_code icode = d->icode;
13812 if (d->name == 0 || icode == CODE_FOR_nothing)
13815 type = builtin_function_type (insn_data[icode].operand[0].mode,
13816 insn_data[icode].operand[1].mode,
13817 insn_data[icode].operand[2].mode,
13818 insn_data[icode].operand[3].mode,
13822 def_builtin (d->mask, d->name, type, d->code);
13825 /* Add the binary operators. */
13827 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13829 enum machine_mode mode0, mode1, mode2;
13831 int mask = d->mask;
13833 if ((mask != 0 && (mask & target_flags) == 0)
13834 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13837 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13838 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13839 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13840 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13842 if (! (type = opaque_ftype_opaque_opaque))
13843 type = opaque_ftype_opaque_opaque
13844 = build_function_type_list (opaque_V4SI_type_node,
13845 opaque_V4SI_type_node,
13846 opaque_V4SI_type_node,
13851 enum insn_code icode = d->icode;
13852 if (d->name == 0 || icode == CODE_FOR_nothing)
13855 mode0 = insn_data[icode].operand[0].mode;
13856 mode1 = insn_data[icode].operand[1].mode;
13857 mode2 = insn_data[icode].operand[2].mode;
13859 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13861 if (! (type = v2si_ftype_v2si_qi))
13862 type = v2si_ftype_v2si_qi
13863 = build_function_type_list (opaque_V2SI_type_node,
13864 opaque_V2SI_type_node,
13869 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13870 && mode2 == QImode)
13872 if (! (type = v2si_ftype_int_qi))
13873 type = v2si_ftype_int_qi
13874 = build_function_type_list (opaque_V2SI_type_node,
13881 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13885 def_builtin (d->mask, d->name, type, d->code);
13888 /* Add the simple unary operators. */
13889 d = (struct builtin_description *) bdesc_1arg;
13890 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13892 enum machine_mode mode0, mode1;
13894 int mask = d->mask;
13896 if ((mask != 0 && (mask & target_flags) == 0)
13897 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13900 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13901 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13902 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13903 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13905 if (! (type = opaque_ftype_opaque))
13906 type = opaque_ftype_opaque
13907 = build_function_type_list (opaque_V4SI_type_node,
13908 opaque_V4SI_type_node,
13913 enum insn_code icode = d->icode;
13914 if (d->name == 0 || icode == CODE_FOR_nothing)
13917 mode0 = insn_data[icode].operand[0].mode;
13918 mode1 = insn_data[icode].operand[1].mode;
13920 if (mode0 == V2SImode && mode1 == QImode)
13922 if (! (type = v2si_ftype_qi))
13923 type = v2si_ftype_qi
13924 = build_function_type_list (opaque_V2SI_type_node,
13930 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13934 def_builtin (d->mask, d->name, type, d->code);
13939 rs6000_init_libfuncs (void)
13941 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13942 && !TARGET_POWER2 && !TARGET_POWERPC)
13944 /* AIX library routines for float->int conversion. */
13945 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13946 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13947 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13948 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13951 if (!TARGET_IEEEQUAD)
13952 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13953 if (!TARGET_XL_COMPAT)
13955 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13956 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13957 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13958 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13960 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13962 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13963 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13964 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13965 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13966 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13967 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13968 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13970 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13971 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13972 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13973 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13974 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13975 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13976 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13977 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13980 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13981 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13985 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13986 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13987 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13988 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13992 /* 32-bit SVR4 quad floating point routines. */
13994 set_optab_libfunc (add_optab, TFmode, "_q_add");
13995 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13996 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13997 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13998 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13999 if (TARGET_PPC_GPOPT || TARGET_POWER2)
14000 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
14002 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
14003 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
14004 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
14005 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
14006 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
14007 set_optab_libfunc (le_optab, TFmode, "_q_fle");
14009 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
14010 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
14011 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
14012 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
14013 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
14014 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
14015 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
14016 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
14021 /* Expand a block clear operation, and return 1 if successful. Return 0
14022 if we should let the compiler generate normal code.
14024 operands[0] is the destination
14025 operands[1] is the length
14026 operands[3] is the alignment */
14029 expand_block_clear (rtx operands[])
14031 rtx orig_dest = operands[0];
14032 rtx bytes_rtx = operands[1];
14033 rtx align_rtx = operands[3];
14034 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
14035 HOST_WIDE_INT align;
14036 HOST_WIDE_INT bytes;
14041 /* If this is not a fixed size move, just call memcpy */
14045 /* This must be a fixed size alignment */
14046 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14047 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14049 /* Anything to clear? */
14050 bytes = INTVAL (bytes_rtx);
14054 /* Use the builtin memset after a point, to avoid huge code bloat.
14055 When optimize_size, avoid any significant code bloat; calling
14056 memset is about 4 instructions, so allow for one instruction to
14057 load zero and three to do clearing. */
14058 if (TARGET_ALTIVEC && align >= 128)
14060 else if (TARGET_POWERPC64 && align >= 32)
14062 else if (TARGET_SPE && align >= 64)
14067 if (optimize_size && bytes > 3 * clear_step)
14069 if (! optimize_size && bytes > 8 * clear_step)
14072 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14074 enum machine_mode mode = BLKmode;
14077 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14082 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14087 else if (bytes >= 8 && TARGET_POWERPC64
14088 /* 64-bit loads and stores require word-aligned
14090 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14095 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14096 { /* move 4 bytes */
14100 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14101 { /* move 2 bytes */
14105 else /* move 1 byte at a time */
14111 dest = adjust_address (orig_dest, mode, offset);
14113 emit_move_insn (dest, CONST0_RTX (mode));
14120 /* Expand a block move operation, and return 1 if successful. Return 0
14121 if we should let the compiler generate normal code.
14123 operands[0] is the destination
14124 operands[1] is the source
14125 operands[2] is the length
14126 operands[3] is the alignment */
14128 #define MAX_MOVE_REG 4
14131 expand_block_move (rtx operands[])
14133 rtx orig_dest = operands[0];
14134 rtx orig_src = operands[1];
14135 rtx bytes_rtx = operands[2];
14136 rtx align_rtx = operands[3];
14137 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14142 rtx stores[MAX_MOVE_REG];
14145 /* If this is not a fixed size move, just call memcpy */
14149 /* This must be a fixed size alignment */
14150 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14151 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14153 /* Anything to move? */
14154 bytes = INTVAL (bytes_rtx);
14158 if (bytes > rs6000_block_move_inline_limit)
14161 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14164 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14165 rtx (*mov) (rtx, rtx);
14167 enum machine_mode mode = BLKmode;
14170 /* Altivec first, since it will be faster than a string move
14171 when it applies, and usually not significantly larger. */
14172 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14176 gen_func.mov = gen_movv4si;
14178 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14182 gen_func.mov = gen_movv2si;
14184 else if (TARGET_STRING
14185 && bytes > 24 /* move up to 32 bytes at a time */
14191 && ! fixed_regs[10]
14192 && ! fixed_regs[11]
14193 && ! fixed_regs[12])
14195 move_bytes = (bytes > 32) ? 32 : bytes;
14196 gen_func.movmemsi = gen_movmemsi_8reg;
14198 else if (TARGET_STRING
14199 && bytes > 16 /* move up to 24 bytes at a time */
14205 && ! fixed_regs[10])
14207 move_bytes = (bytes > 24) ? 24 : bytes;
14208 gen_func.movmemsi = gen_movmemsi_6reg;
14210 else if (TARGET_STRING
14211 && bytes > 8 /* move up to 16 bytes at a time */
14215 && ! fixed_regs[8])
14217 move_bytes = (bytes > 16) ? 16 : bytes;
14218 gen_func.movmemsi = gen_movmemsi_4reg;
14220 else if (bytes >= 8 && TARGET_POWERPC64
14221 /* 64-bit loads and stores require word-aligned
14223 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14227 gen_func.mov = gen_movdi;
14229 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14230 { /* move up to 8 bytes at a time */
14231 move_bytes = (bytes > 8) ? 8 : bytes;
14232 gen_func.movmemsi = gen_movmemsi_2reg;
14234 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14235 { /* move 4 bytes */
14238 gen_func.mov = gen_movsi;
14240 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14241 { /* move 2 bytes */
14244 gen_func.mov = gen_movhi;
14246 else if (TARGET_STRING && bytes > 1)
14247 { /* move up to 4 bytes at a time */
14248 move_bytes = (bytes > 4) ? 4 : bytes;
14249 gen_func.movmemsi = gen_movmemsi_1reg;
14251 else /* move 1 byte at a time */
14255 gen_func.mov = gen_movqi;
14258 src = adjust_address (orig_src, mode, offset);
14259 dest = adjust_address (orig_dest, mode, offset);
14261 if (mode != BLKmode)
14263 rtx tmp_reg = gen_reg_rtx (mode);
14265 emit_insn ((*gen_func.mov) (tmp_reg, src));
14266 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14269 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14272 for (i = 0; i < num_reg; i++)
14273 emit_insn (stores[i]);
14277 if (mode == BLKmode)
14279 /* Move the address into scratch registers. The movmemsi
14280 patterns require zero offset. */
14281 if (!REG_P (XEXP (src, 0)))
14283 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14284 src = replace_equiv_address (src, src_reg);
14286 set_mem_size (src, GEN_INT (move_bytes));
14288 if (!REG_P (XEXP (dest, 0)))
14290 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14291 dest = replace_equiv_address (dest, dest_reg);
14293 set_mem_size (dest, GEN_INT (move_bytes));
14295 emit_insn ((*gen_func.movmemsi) (dest, src,
14296 GEN_INT (move_bytes & 31),
14305 /* Return a string to perform a load_multiple operation.
14306 operands[0] is the vector.
14307 operands[1] is the source address.
14308 operands[2] is the first destination register. */
14311 rs6000_output_load_multiple (rtx operands[3])
14313 /* We have to handle the case where the pseudo used to contain the address
14314 is assigned to one of the output registers. */
14316 int words = XVECLEN (operands[0], 0);
14319 if (XVECLEN (operands[0], 0) == 1)
14320 return "{l|lwz} %2,0(%1)";
14322 for (i = 0; i < words; i++)
14323 if (refers_to_regno_p (REGNO (operands[2]) + i,
14324 REGNO (operands[2]) + i + 1, operands[1], 0))
14328 xop[0] = GEN_INT (4 * (words-1));
14329 xop[1] = operands[1];
14330 xop[2] = operands[2];
14331 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14336 xop[0] = GEN_INT (4 * (words-1));
14337 xop[1] = operands[1];
14338 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14339 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);
14344 for (j = 0; j < words; j++)
14347 xop[0] = GEN_INT (j * 4);
14348 xop[1] = operands[1];
14349 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14350 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14352 xop[0] = GEN_INT (i * 4);
14353 xop[1] = operands[1];
14354 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14359 return "{lsi|lswi} %2,%1,%N0";
14363 /* A validation routine: say whether CODE, a condition code, and MODE
14364 match. The other alternatives either don't make sense or should
14365 never be generated. */
14368 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14370 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14371 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14372 && GET_MODE_CLASS (mode) == MODE_CC);
14374 /* These don't make sense. */
14375 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14376 || mode != CCUNSmode);
14378 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14379 || mode == CCUNSmode);
14381 gcc_assert (mode == CCFPmode
14382 || (code != ORDERED && code != UNORDERED
14383 && code != UNEQ && code != LTGT
14384 && code != UNGT && code != UNLT
14385 && code != UNGE && code != UNLE));
14387 /* These should never be generated except for
14388 flag_finite_math_only. */
14389 gcc_assert (mode != CCFPmode
14390 || flag_finite_math_only
14391 || (code != LE && code != GE
14392 && code != UNEQ && code != LTGT
14393 && code != UNGT && code != UNLT));
14395 /* These are invalid; the information is not there. */
14396 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14400 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14401 mask required to convert the result of a rotate insn into a shift
14402 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14405 includes_lshift_p (rtx shiftop, rtx andop)
14407 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14409 shift_mask <<= INTVAL (shiftop);
14411 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14414 /* Similar, but for right shift. */
14417 includes_rshift_p (rtx shiftop, rtx andop)
14419 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14421 shift_mask >>= INTVAL (shiftop);
14423 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14426 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14427 to perform a left shift. It must have exactly SHIFTOP least
14428 significant 0's, then one or more 1's, then zero or more 0's. */
14431 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14433 if (GET_CODE (andop) == CONST_INT)
14435 HOST_WIDE_INT c, lsb, shift_mask;
14437 c = INTVAL (andop);
14438 if (c == 0 || c == ~0)
14442 shift_mask <<= INTVAL (shiftop);
14444 /* Find the least significant one bit. */
14447 /* It must coincide with the LSB of the shift mask. */
14448 if (-lsb != shift_mask)
14451 /* Invert to look for the next transition (if any). */
14454 /* Remove the low group of ones (originally low group of zeros). */
14457 /* Again find the lsb, and check we have all 1's above. */
14461 else if (GET_CODE (andop) == CONST_DOUBLE
14462 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14464 HOST_WIDE_INT low, high, lsb;
14465 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14467 low = CONST_DOUBLE_LOW (andop);
14468 if (HOST_BITS_PER_WIDE_INT < 64)
14469 high = CONST_DOUBLE_HIGH (andop);
14471 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14472 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14475 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14477 shift_mask_high = ~0;
14478 if (INTVAL (shiftop) > 32)
14479 shift_mask_high <<= INTVAL (shiftop) - 32;
14481 lsb = high & -high;
14483 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14489 lsb = high & -high;
14490 return high == -lsb;
14493 shift_mask_low = ~0;
14494 shift_mask_low <<= INTVAL (shiftop);
14498 if (-lsb != shift_mask_low)
14501 if (HOST_BITS_PER_WIDE_INT < 64)
14506 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14508 lsb = high & -high;
14509 return high == -lsb;
14513 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14519 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14520 to perform a left shift. It must have SHIFTOP or more least
14521 significant 0's, with the remainder of the word 1's. */
14524 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14526 if (GET_CODE (andop) == CONST_INT)
14528 HOST_WIDE_INT c, lsb, shift_mask;
14531 shift_mask <<= INTVAL (shiftop);
14532 c = INTVAL (andop);
14534 /* Find the least significant one bit. */
14537 /* It must be covered by the shift mask.
14538 This test also rejects c == 0. */
14539 if ((lsb & shift_mask) == 0)
14542 /* Check we have all 1's above the transition, and reject all 1's. */
14543 return c == -lsb && lsb != 1;
14545 else if (GET_CODE (andop) == CONST_DOUBLE
14546 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14548 HOST_WIDE_INT low, lsb, shift_mask_low;
14550 low = CONST_DOUBLE_LOW (andop);
14552 if (HOST_BITS_PER_WIDE_INT < 64)
14554 HOST_WIDE_INT high, shift_mask_high;
14556 high = CONST_DOUBLE_HIGH (andop);
14560 shift_mask_high = ~0;
14561 if (INTVAL (shiftop) > 32)
14562 shift_mask_high <<= INTVAL (shiftop) - 32;
14564 lsb = high & -high;
14566 if ((lsb & shift_mask_high) == 0)
14569 return high == -lsb;
14575 shift_mask_low = ~0;
14576 shift_mask_low <<= INTVAL (shiftop);
14580 if ((lsb & shift_mask_low) == 0)
14583 return low == -lsb && lsb != 1;
14589 /* Return 1 if operands will generate a valid arguments to rlwimi
14590 instruction for insert with right shift in 64-bit mode. The mask may
14591 not start on the first bit or stop on the last bit because wrap-around
14592 effects of instruction do not correspond to semantics of RTL insn. */
14595 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14597 if (INTVAL (startop) > 32
14598 && INTVAL (startop) < 64
14599 && INTVAL (sizeop) > 1
14600 && INTVAL (sizeop) + INTVAL (startop) < 64
14601 && INTVAL (shiftop) > 0
14602 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14603 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14609 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14610 for lfq and stfq insns iff the registers are hard registers. */
14613 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14615 /* We might have been passed a SUBREG. */
14616 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14619 /* We might have been passed non floating point registers. */
14620 if (!FP_REGNO_P (REGNO (reg1))
14621 || !FP_REGNO_P (REGNO (reg2)))
14624 return (REGNO (reg1) == REGNO (reg2) - 1);
14627 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14628 addr1 and addr2 must be in consecutive memory locations
14629 (addr2 == addr1 + 8). */
14632 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14635 unsigned int reg1, reg2;
14636 int offset1, offset2;
14638 /* The mems cannot be volatile. */
14639 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14642 addr1 = XEXP (mem1, 0);
14643 addr2 = XEXP (mem2, 0);
14645 /* Extract an offset (if used) from the first addr. */
14646 if (GET_CODE (addr1) == PLUS)
14648 /* If not a REG, return zero. */
14649 if (GET_CODE (XEXP (addr1, 0)) != REG)
14653 reg1 = REGNO (XEXP (addr1, 0));
14654 /* The offset must be constant! */
14655 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14657 offset1 = INTVAL (XEXP (addr1, 1));
14660 else if (GET_CODE (addr1) != REG)
14664 reg1 = REGNO (addr1);
14665 /* This was a simple (mem (reg)) expression. Offset is 0. */
14669 /* And now for the second addr. */
14670 if (GET_CODE (addr2) == PLUS)
14672 /* If not a REG, return zero. */
14673 if (GET_CODE (XEXP (addr2, 0)) != REG)
14677 reg2 = REGNO (XEXP (addr2, 0));
14678 /* The offset must be constant. */
14679 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14681 offset2 = INTVAL (XEXP (addr2, 1));
14684 else if (GET_CODE (addr2) != REG)
14688 reg2 = REGNO (addr2);
14689 /* This was a simple (mem (reg)) expression. Offset is 0. */
14693 /* Both of these must have the same base register. */
14697 /* The offset for the second addr must be 8 more than the first addr. */
14698 if (offset2 != offset1 + 8)
14701 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14708 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14710 static bool eliminated = false;
14713 if (mode != SDmode)
14714 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14717 rtx mem = cfun->machine->sdmode_stack_slot;
14718 gcc_assert (mem != NULL_RTX);
14722 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14723 cfun->machine->sdmode_stack_slot = mem;
14729 if (TARGET_DEBUG_ADDR)
14731 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14732 GET_MODE_NAME (mode));
14734 fprintf (stderr, "\tNULL_RTX\n");
14743 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14745 /* Don't walk into types. */
14746 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14748 *walk_subtrees = 0;
14752 switch (TREE_CODE (*tp))
14761 case VIEW_CONVERT_EXPR:
14762 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14772 enum reload_reg_type {
14774 VECTOR_REGISTER_TYPE,
14775 OTHER_REGISTER_TYPE
14778 static enum reload_reg_type
14779 rs6000_reload_register_type (enum reg_class rclass)
14785 return GPR_REGISTER_TYPE;
14790 return VECTOR_REGISTER_TYPE;
14793 return OTHER_REGISTER_TYPE;
14797 /* Inform reload about cases where moving X with a mode MODE to a register in
14798 RCLASS requires an extra scratch or immediate register. Return the class
14799 needed for the immediate register.
14801 For VSX and Altivec, we may need a register to convert sp+offset into
14805 rs6000_secondary_reload (bool in_p,
14807 reg_class_t rclass_i,
14808 enum machine_mode mode,
14809 secondary_reload_info *sri)
14811 enum reg_class rclass = (enum reg_class) rclass_i;
14812 reg_class_t ret = ALL_REGS;
14813 enum insn_code icode;
14814 bool default_p = false;
14816 sri->icode = CODE_FOR_nothing;
14818 /* Convert vector loads and stores into gprs to use an additional base
14820 icode = rs6000_vector_reload[mode][in_p != false];
14821 if (icode != CODE_FOR_nothing)
14824 sri->icode = CODE_FOR_nothing;
14825 sri->extra_cost = 0;
14827 if (GET_CODE (x) == MEM)
14829 rtx addr = XEXP (x, 0);
14831 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14832 an extra register in that case, but it would need an extra
14833 register if the addressing is reg+reg or (reg+reg)&(-16). */
14834 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14836 if (!legitimate_indirect_address_p (addr, false)
14837 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14839 sri->icode = icode;
14840 /* account for splitting the loads, and converting the
14841 address from reg+reg to reg. */
14842 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14843 + ((GET_CODE (addr) == AND) ? 1 : 0));
14846 /* Loads to and stores from vector registers can only do reg+reg
14847 addressing. Altivec registers can also do (reg+reg)&(-16). */
14848 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14849 || rclass == FLOAT_REGS || rclass == NO_REGS)
14851 if (!VECTOR_MEM_ALTIVEC_P (mode)
14852 && GET_CODE (addr) == AND
14853 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14854 && INTVAL (XEXP (addr, 1)) == -16
14855 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14856 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14858 sri->icode = icode;
14859 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14862 else if (!legitimate_indirect_address_p (addr, false)
14863 && (rclass == NO_REGS
14864 || !legitimate_indexed_address_p (addr, false)))
14866 sri->icode = icode;
14867 sri->extra_cost = 1;
14870 icode = CODE_FOR_nothing;
14872 /* Any other loads, including to pseudo registers which haven't been
14873 assigned to a register yet, default to require a scratch
14877 sri->icode = icode;
14878 sri->extra_cost = 2;
14881 else if (REG_P (x))
14883 int regno = true_regnum (x);
14885 icode = CODE_FOR_nothing;
14886 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14890 enum reg_class xclass = REGNO_REG_CLASS (regno);
14891 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14892 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14894 /* If memory is needed, use default_secondary_reload to create the
14896 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14909 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14911 gcc_assert (ret != ALL_REGS);
14913 if (TARGET_DEBUG_ADDR)
14916 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14918 reg_class_names[ret],
14919 in_p ? "true" : "false",
14920 reg_class_names[rclass],
14921 GET_MODE_NAME (mode));
14924 fprintf (stderr, ", default secondary reload");
14926 if (sri->icode != CODE_FOR_nothing)
14927 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14928 insn_data[sri->icode].name, sri->extra_cost);
14930 fprintf (stderr, "\n");
14938 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14939 to SP+reg addressing. */
14942 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14944 int regno = true_regnum (reg);
14945 enum machine_mode mode = GET_MODE (reg);
14946 enum reg_class rclass;
14948 rtx and_op2 = NULL_RTX;
14951 rtx scratch_or_premodify = scratch;
14955 if (TARGET_DEBUG_ADDR)
14957 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14958 store_p ? "store" : "load");
14959 fprintf (stderr, "reg:\n");
14961 fprintf (stderr, "mem:\n");
14963 fprintf (stderr, "scratch:\n");
14964 debug_rtx (scratch);
14967 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14968 gcc_assert (GET_CODE (mem) == MEM);
14969 rclass = REGNO_REG_CLASS (regno);
14970 addr = XEXP (mem, 0);
14974 /* GPRs can handle reg + small constant, all other addresses need to use
14975 the scratch register. */
14978 if (GET_CODE (addr) == AND)
14980 and_op2 = XEXP (addr, 1);
14981 addr = XEXP (addr, 0);
14984 if (GET_CODE (addr) == PRE_MODIFY)
14986 scratch_or_premodify = XEXP (addr, 0);
14987 gcc_assert (REG_P (scratch_or_premodify));
14988 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14989 addr = XEXP (addr, 1);
14992 if (GET_CODE (addr) == PLUS
14993 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14994 || and_op2 != NULL_RTX))
14996 addr_op1 = XEXP (addr, 0);
14997 addr_op2 = XEXP (addr, 1);
14998 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
15000 if (!REG_P (addr_op2)
15001 && (GET_CODE (addr_op2) != CONST_INT
15002 || !satisfies_constraint_I (addr_op2)))
15004 if (TARGET_DEBUG_ADDR)
15007 "\nMove plus addr to register %s, mode = %s: ",
15008 rs6000_reg_names[REGNO (scratch)],
15009 GET_MODE_NAME (mode));
15010 debug_rtx (addr_op2);
15012 rs6000_emit_move (scratch, addr_op2, Pmode);
15013 addr_op2 = scratch;
15016 emit_insn (gen_rtx_SET (VOIDmode,
15017 scratch_or_premodify,
15018 gen_rtx_PLUS (Pmode,
15022 addr = scratch_or_premodify;
15023 scratch_or_premodify = scratch;
15025 else if (!legitimate_indirect_address_p (addr, false)
15026 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
15028 if (TARGET_DEBUG_ADDR)
15030 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15031 rs6000_reg_names[REGNO (scratch_or_premodify)],
15032 GET_MODE_NAME (mode));
15035 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15036 addr = scratch_or_premodify;
15037 scratch_or_premodify = scratch;
15041 /* Float/Altivec registers can only handle reg+reg addressing. Move
15042 other addresses into a scratch register. */
15047 /* With float regs, we need to handle the AND ourselves, since we can't
15048 use the Altivec instruction with an implicit AND -16. Allow scalar
15049 loads to float registers to use reg+offset even if VSX. */
15050 if (GET_CODE (addr) == AND
15051 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
15052 || GET_CODE (XEXP (addr, 1)) != CONST_INT
15053 || INTVAL (XEXP (addr, 1)) != -16
15054 || !VECTOR_MEM_ALTIVEC_P (mode)))
15056 and_op2 = XEXP (addr, 1);
15057 addr = XEXP (addr, 0);
15060 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15061 as the address later. */
15062 if (GET_CODE (addr) == PRE_MODIFY
15063 && (!VECTOR_MEM_VSX_P (mode)
15064 || and_op2 != NULL_RTX
15065 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
15067 scratch_or_premodify = XEXP (addr, 0);
15068 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
15070 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15071 addr = XEXP (addr, 1);
15074 if (legitimate_indirect_address_p (addr, false) /* reg */
15075 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15076 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15077 || (GET_CODE (addr) == AND /* Altivec memory */
15078 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15079 && INTVAL (XEXP (addr, 1)) == -16
15080 && VECTOR_MEM_ALTIVEC_P (mode))
15081 || (rclass == FLOAT_REGS /* legacy float mem */
15082 && GET_MODE_SIZE (mode) == 8
15083 && and_op2 == NULL_RTX
15084 && scratch_or_premodify == scratch
15085 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15088 else if (GET_CODE (addr) == PLUS)
15090 addr_op1 = XEXP (addr, 0);
15091 addr_op2 = XEXP (addr, 1);
15092 gcc_assert (REG_P (addr_op1));
15094 if (TARGET_DEBUG_ADDR)
15096 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15097 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15098 debug_rtx (addr_op2);
15100 rs6000_emit_move (scratch, addr_op2, Pmode);
15101 emit_insn (gen_rtx_SET (VOIDmode,
15102 scratch_or_premodify,
15103 gen_rtx_PLUS (Pmode,
15106 addr = scratch_or_premodify;
15107 scratch_or_premodify = scratch;
15110 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15111 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15113 if (TARGET_DEBUG_ADDR)
15115 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15116 rs6000_reg_names[REGNO (scratch_or_premodify)],
15117 GET_MODE_NAME (mode));
15121 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15122 addr = scratch_or_premodify;
15123 scratch_or_premodify = scratch;
15127 gcc_unreachable ();
15132 gcc_unreachable ();
15135 /* If the original address involved a pre-modify that we couldn't use the VSX
15136 memory instruction with update, and we haven't taken care of already,
15137 store the address in the pre-modify register and use that as the
15139 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15141 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15142 addr = scratch_or_premodify;
15145 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15146 memory instruction, recreate the AND now, including the clobber which is
15147 generated by the general ANDSI3/ANDDI3 patterns for the
15148 andi. instruction. */
15149 if (and_op2 != NULL_RTX)
15151 if (! legitimate_indirect_address_p (addr, false))
15153 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15157 if (TARGET_DEBUG_ADDR)
15159 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15160 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15161 debug_rtx (and_op2);
15164 and_rtx = gen_rtx_SET (VOIDmode,
15166 gen_rtx_AND (Pmode,
15170 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15171 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15172 gen_rtvec (2, and_rtx, cc_clobber)));
15176 /* Adjust the address if it changed. */
15177 if (addr != XEXP (mem, 0))
15179 mem = change_address (mem, mode, addr);
15180 if (TARGET_DEBUG_ADDR)
15181 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15184 /* Now create the move. */
15186 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15188 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15193 /* Target hook to return the cover classes for Integrated Register Allocator.
15194 Cover classes is a set of non-intersected register classes covering all hard
15195 registers used for register allocation purpose. Any move between two
15196 registers of a cover class should be cheaper than load or store of the
15197 registers. The value is array of register classes with LIM_REG_CLASSES used
15200 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
15201 account for the Altivec and Floating registers being subsets of the VSX
15202 register set under VSX, but distinct register sets on pre-VSX machines. */
15204 static const reg_class_t *
15205 rs6000_ira_cover_classes (void)
15207 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
15208 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
15210 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
15213 /* Allocate a 64-bit stack slot to be used for copying SDmode
15214 values through if this function has any SDmode references. */
15217 rs6000_alloc_sdmode_stack_slot (void)
15221 gimple_stmt_iterator gsi;
15223 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15226 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15228 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15231 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15232 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15238 /* Check for any SDmode parameters of the function. */
15239 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15241 if (TREE_TYPE (t) == error_mark_node)
15244 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15245 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15247 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15248 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15256 rs6000_instantiate_decls (void)
15258 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15259 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15262 /* Given an rtx X being reloaded into a reg required to be
15263 in class CLASS, return the class of reg to actually use.
15264 In general this is just CLASS; but on some machines
15265 in some cases it is preferable to use a more restrictive class.
15267 On the RS/6000, we have to return NO_REGS when we want to reload a
15268 floating-point CONST_DOUBLE to force it to be copied to memory.
15270 We also don't want to reload integer values into floating-point
15271 registers if we can at all help it. In fact, this can
15272 cause reload to die, if it tries to generate a reload of CTR
15273 into a FP register and discovers it doesn't have the memory location
15276 ??? Would it be a good idea to have reload do the converse, that is
15277 try to reload floating modes into FP registers if possible?
15280 static enum reg_class
15281 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15283 enum machine_mode mode = GET_MODE (x);
15285 if (VECTOR_UNIT_VSX_P (mode)
15286 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15289 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15290 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15291 && easy_vector_constant (x, mode))
15292 return ALTIVEC_REGS;
15294 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15297 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15298 return GENERAL_REGS;
15300 /* For VSX, prefer the traditional registers for 64-bit values because we can
15301 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15302 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15303 prefer Altivec loads.. */
15304 if (rclass == VSX_REGS)
15306 if (GET_MODE_SIZE (mode) <= 8)
15309 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15310 return ALTIVEC_REGS;
15318 /* Debug version of rs6000_preferred_reload_class. */
15319 static enum reg_class
15320 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15322 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15325 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15327 reg_class_names[ret], reg_class_names[rclass],
15328 GET_MODE_NAME (GET_MODE (x)));
15334 /* If we are copying between FP or AltiVec registers and anything else, we need
15335 a memory location. The exception is when we are targeting ppc64 and the
15336 move to/from fpr to gpr instructions are available. Also, under VSX, you
15337 can copy vector registers from the FP register set to the Altivec register
15338 set and vice versa. */
15341 rs6000_secondary_memory_needed (enum reg_class class1,
15342 enum reg_class class2,
15343 enum machine_mode mode)
15345 if (class1 == class2)
15348 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15349 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15350 between these classes. But we need memory for other things that can go in
15351 FLOAT_REGS like SFmode. */
15353 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15354 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15355 || class1 == FLOAT_REGS))
15356 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15357 && class2 != FLOAT_REGS);
15359 if (class1 == VSX_REGS || class2 == VSX_REGS)
15362 if (class1 == FLOAT_REGS
15363 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15364 || ((mode != DFmode)
15365 && (mode != DDmode)
15366 && (mode != DImode))))
15369 if (class2 == FLOAT_REGS
15370 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15371 || ((mode != DFmode)
15372 && (mode != DDmode)
15373 && (mode != DImode))))
15376 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15382 /* Debug version of rs6000_secondary_memory_needed. */
15384 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15385 enum reg_class class2,
15386 enum machine_mode mode)
15388 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15391 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15392 "class2 = %s, mode = %s\n",
15393 ret ? "true" : "false", reg_class_names[class1],
15394 reg_class_names[class2], GET_MODE_NAME (mode));
15399 /* Return the register class of a scratch register needed to copy IN into
15400 or out of a register in RCLASS in MODE. If it can be done directly,
15401 NO_REGS is returned. */
15403 static enum reg_class
15404 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15409 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15411 && MACHOPIC_INDIRECT
15415 /* We cannot copy a symbolic operand directly into anything
15416 other than BASE_REGS for TARGET_ELF. So indicate that a
15417 register from BASE_REGS is needed as an intermediate
15420 On Darwin, pic addresses require a load from memory, which
15421 needs a base register. */
15422 if (rclass != BASE_REGS
15423 && (GET_CODE (in) == SYMBOL_REF
15424 || GET_CODE (in) == HIGH
15425 || GET_CODE (in) == LABEL_REF
15426 || GET_CODE (in) == CONST))
15430 if (GET_CODE (in) == REG)
15432 regno = REGNO (in);
15433 if (regno >= FIRST_PSEUDO_REGISTER)
15435 regno = true_regnum (in);
15436 if (regno >= FIRST_PSEUDO_REGISTER)
15440 else if (GET_CODE (in) == SUBREG)
15442 regno = true_regnum (in);
15443 if (regno >= FIRST_PSEUDO_REGISTER)
15449 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15451 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15452 || (regno >= 0 && INT_REGNO_P (regno)))
15455 /* Constants, memory, and FP registers can go into FP registers. */
15456 if ((regno == -1 || FP_REGNO_P (regno))
15457 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15458 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15460 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15463 && (regno == -1 || VSX_REGNO_P (regno))
15464 && VSX_REG_CLASS_P (rclass))
15467 /* Memory, and AltiVec registers can go into AltiVec registers. */
15468 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15469 && rclass == ALTIVEC_REGS)
15472 /* We can copy among the CR registers. */
15473 if ((rclass == CR_REGS || rclass == CR0_REGS)
15474 && regno >= 0 && CR_REGNO_P (regno))
15477 /* Otherwise, we need GENERAL_REGS. */
15478 return GENERAL_REGS;
15481 /* Debug version of rs6000_secondary_reload_class. */
15482 static enum reg_class
15483 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15484 enum machine_mode mode, rtx in)
15486 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15488 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15489 "mode = %s, input rtx:\n",
15490 reg_class_names[ret], reg_class_names[rclass],
15491 GET_MODE_NAME (mode));
15497 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15500 rs6000_cannot_change_mode_class (enum machine_mode from,
15501 enum machine_mode to,
15502 enum reg_class rclass)
15504 unsigned from_size = GET_MODE_SIZE (from);
15505 unsigned to_size = GET_MODE_SIZE (to);
15507 if (from_size != to_size)
15509 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15510 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15511 && reg_classes_intersect_p (xclass, rclass));
15514 if (TARGET_E500_DOUBLE
15515 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15516 || (((to) == TFmode) + ((from) == TFmode)) == 1
15517 || (((to) == DDmode) + ((from) == DDmode)) == 1
15518 || (((to) == TDmode) + ((from) == TDmode)) == 1
15519 || (((to) == DImode) + ((from) == DImode)) == 1))
15522 /* Since the VSX register set includes traditional floating point registers
15523 and altivec registers, just check for the size being different instead of
15524 trying to check whether the modes are vector modes. Otherwise it won't
15525 allow say DF and DI to change classes. */
15526 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15527 return (from_size != 8 && from_size != 16);
15529 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15530 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15533 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15534 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15540 /* Debug version of rs6000_cannot_change_mode_class. */
15542 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15543 enum machine_mode to,
15544 enum reg_class rclass)
15546 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15549 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15550 "to = %s, rclass = %s\n",
15551 ret ? "true" : "false",
15552 GET_MODE_NAME (from), GET_MODE_NAME (to),
15553 reg_class_names[rclass]);
15558 /* Given a comparison operation, return the bit number in CCR to test. We
15559 know this is a valid comparison.
15561 SCC_P is 1 if this is for an scc. That means that %D will have been
15562 used instead of %C, so the bits will be in different places.
15564 Return -1 if OP isn't a valid comparison for some reason. */
15567 ccr_bit (rtx op, int scc_p)
15569 enum rtx_code code = GET_CODE (op);
15570 enum machine_mode cc_mode;
15575 if (!COMPARISON_P (op))
15578 reg = XEXP (op, 0);
15580 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15582 cc_mode = GET_MODE (reg);
15583 cc_regnum = REGNO (reg);
15584 base_bit = 4 * (cc_regnum - CR0_REGNO);
15586 validate_condition_mode (code, cc_mode);
15588 /* When generating a sCOND operation, only positive conditions are
15591 || code == EQ || code == GT || code == LT || code == UNORDERED
15592 || code == GTU || code == LTU);
15597 return scc_p ? base_bit + 3 : base_bit + 2;
15599 return base_bit + 2;
15600 case GT: case GTU: case UNLE:
15601 return base_bit + 1;
15602 case LT: case LTU: case UNGE:
15604 case ORDERED: case UNORDERED:
15605 return base_bit + 3;
15608 /* If scc, we will have done a cror to put the bit in the
15609 unordered position. So test that bit. For integer, this is ! LT
15610 unless this is an scc insn. */
15611 return scc_p ? base_bit + 3 : base_bit;
15614 return scc_p ? base_bit + 3 : base_bit + 1;
15617 gcc_unreachable ();
15621 /* Return the GOT register. */
15624 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15626 /* The second flow pass currently (June 1999) can't update
15627 regs_ever_live without disturbing other parts of the compiler, so
15628 update it here to make the prolog/epilogue code happy. */
15629 if (!can_create_pseudo_p ()
15630 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15631 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15633 crtl->uses_pic_offset_table = 1;
15635 return pic_offset_table_rtx;
15638 static rs6000_stack_t stack_info;
15640 /* Function to init struct machine_function.
15641 This will be called, via a pointer variable,
15642 from push_function_context. */
15644 static struct machine_function *
15645 rs6000_init_machine_status (void)
15647 stack_info.reload_completed = 0;
15648 return ggc_alloc_cleared_machine_function ();
15651 /* These macros test for integers and extract the low-order bits. */
15653 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15654 && GET_MODE (X) == VOIDmode)
15656 #define INT_LOWPART(X) \
15657 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15660 extract_MB (rtx op)
15663 unsigned long val = INT_LOWPART (op);
15665 /* If the high bit is zero, the value is the first 1 bit we find
15667 if ((val & 0x80000000) == 0)
15669 gcc_assert (val & 0xffffffff);
15672 while (((val <<= 1) & 0x80000000) == 0)
15677 /* If the high bit is set and the low bit is not, or the mask is all
15678 1's, the value is zero. */
15679 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15682 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15685 while (((val >>= 1) & 1) != 0)
15692 extract_ME (rtx op)
15695 unsigned long val = INT_LOWPART (op);
15697 /* If the low bit is zero, the value is the first 1 bit we find from
15699 if ((val & 1) == 0)
15701 gcc_assert (val & 0xffffffff);
15704 while (((val >>= 1) & 1) == 0)
15710 /* If the low bit is set and the high bit is not, or the mask is all
15711 1's, the value is 31. */
15712 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15715 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15718 while (((val <<= 1) & 0x80000000) != 0)
15724 /* Locate some local-dynamic symbol still in use by this function
15725 so that we can print its name in some tls_ld pattern. */
15727 static const char *
15728 rs6000_get_some_local_dynamic_name (void)
15732 if (cfun->machine->some_ld_name)
15733 return cfun->machine->some_ld_name;
15735 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15737 && for_each_rtx (&PATTERN (insn),
15738 rs6000_get_some_local_dynamic_name_1, 0))
15739 return cfun->machine->some_ld_name;
15741 gcc_unreachable ();
15744 /* Helper function for rs6000_get_some_local_dynamic_name. */
15747 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15751 if (GET_CODE (x) == SYMBOL_REF)
15753 const char *str = XSTR (x, 0);
15754 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15756 cfun->machine->some_ld_name = str;
15764 /* Write out a function code label. */
15767 rs6000_output_function_entry (FILE *file, const char *fname)
15769 if (fname[0] != '.')
15771 switch (DEFAULT_ABI)
15774 gcc_unreachable ();
15780 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15789 RS6000_OUTPUT_BASENAME (file, fname);
15792 /* Print an operand. Recognize special options, documented below. */
15795 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15796 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15798 #define SMALL_DATA_RELOC "sda21"
15799 #define SMALL_DATA_REG 0
15803 print_operand (FILE *file, rtx x, int code)
15807 unsigned HOST_WIDE_INT uval;
15812 /* Write out an instruction after the call which may be replaced
15813 with glue code by the loader. This depends on the AIX version. */
15814 asm_fprintf (file, RS6000_CALL_GLUE);
15817 /* %a is output_address. */
15820 /* If X is a constant integer whose low-order 5 bits are zero,
15821 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15822 in the AIX assembler where "sri" with a zero shift count
15823 writes a trash instruction. */
15824 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15831 /* If constant, low-order 16 bits of constant, unsigned.
15832 Otherwise, write normally. */
15834 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15836 print_operand (file, x, 0);
15840 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15841 for 64-bit mask direction. */
15842 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15845 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15849 /* X is a CR register. Print the number of the GT bit of the CR. */
15850 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15851 output_operand_lossage ("invalid %%c value");
15853 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15857 /* Like 'J' but get to the GT bit only. */
15858 gcc_assert (GET_CODE (x) == REG);
15860 /* Bit 1 is GT bit. */
15861 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15863 /* Add one for shift count in rlinm for scc. */
15864 fprintf (file, "%d", i + 1);
15868 /* X is a CR register. Print the number of the EQ bit of the CR */
15869 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15870 output_operand_lossage ("invalid %%E value");
15872 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15876 /* X is a CR register. Print the shift count needed to move it
15877 to the high-order four bits. */
15878 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15879 output_operand_lossage ("invalid %%f value");
15881 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15885 /* Similar, but print the count for the rotate in the opposite
15887 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15888 output_operand_lossage ("invalid %%F value");
15890 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15894 /* X is a constant integer. If it is negative, print "m",
15895 otherwise print "z". This is to make an aze or ame insn. */
15896 if (GET_CODE (x) != CONST_INT)
15897 output_operand_lossage ("invalid %%G value");
15898 else if (INTVAL (x) >= 0)
15905 /* If constant, output low-order five bits. Otherwise, write
15908 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15910 print_operand (file, x, 0);
15914 /* If constant, output low-order six bits. Otherwise, write
15917 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15919 print_operand (file, x, 0);
15923 /* Print `i' if this is a constant, else nothing. */
15929 /* Write the bit number in CCR for jump. */
15930 i = ccr_bit (x, 0);
15932 output_operand_lossage ("invalid %%j code");
15934 fprintf (file, "%d", i);
15938 /* Similar, but add one for shift count in rlinm for scc and pass
15939 scc flag to `ccr_bit'. */
15940 i = ccr_bit (x, 1);
15942 output_operand_lossage ("invalid %%J code");
15944 /* If we want bit 31, write a shift count of zero, not 32. */
15945 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15949 /* X must be a constant. Write the 1's complement of the
15952 output_operand_lossage ("invalid %%k value");
15954 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15958 /* X must be a symbolic constant on ELF. Write an
15959 expression suitable for an 'addi' that adds in the low 16
15960 bits of the MEM. */
15961 if (GET_CODE (x) == CONST)
15963 if (GET_CODE (XEXP (x, 0)) != PLUS
15964 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15965 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15966 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15967 output_operand_lossage ("invalid %%K value");
15969 print_operand_address (file, x);
15970 fputs ("@l", file);
15973 /* %l is output_asm_label. */
15976 /* Write second word of DImode or DFmode reference. Works on register
15977 or non-indexed memory only. */
15978 if (GET_CODE (x) == REG)
15979 fputs (reg_names[REGNO (x) + 1], file);
15980 else if (GET_CODE (x) == MEM)
15982 /* Handle possible auto-increment. Since it is pre-increment and
15983 we have already done it, we can just use an offset of word. */
15984 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15985 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15986 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15988 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15989 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15992 output_address (XEXP (adjust_address_nv (x, SImode,
15996 if (small_data_operand (x, GET_MODE (x)))
15997 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15998 reg_names[SMALL_DATA_REG]);
16003 /* MB value for a mask operand. */
16004 if (! mask_operand (x, SImode))
16005 output_operand_lossage ("invalid %%m value");
16007 fprintf (file, "%d", extract_MB (x));
16011 /* ME value for a mask operand. */
16012 if (! mask_operand (x, SImode))
16013 output_operand_lossage ("invalid %%M value");
16015 fprintf (file, "%d", extract_ME (x));
16018 /* %n outputs the negative of its operand. */
16021 /* Write the number of elements in the vector times 4. */
16022 if (GET_CODE (x) != PARALLEL)
16023 output_operand_lossage ("invalid %%N value");
16025 fprintf (file, "%d", XVECLEN (x, 0) * 4);
16029 /* Similar, but subtract 1 first. */
16030 if (GET_CODE (x) != PARALLEL)
16031 output_operand_lossage ("invalid %%O value");
16033 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
16037 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16039 || INT_LOWPART (x) < 0
16040 || (i = exact_log2 (INT_LOWPART (x))) < 0)
16041 output_operand_lossage ("invalid %%p value");
16043 fprintf (file, "%d", i);
16047 /* The operand must be an indirect memory reference. The result
16048 is the register name. */
16049 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
16050 || REGNO (XEXP (x, 0)) >= 32)
16051 output_operand_lossage ("invalid %%P value");
16053 fputs (reg_names[REGNO (XEXP (x, 0))], file);
16057 /* This outputs the logical code corresponding to a boolean
16058 expression. The expression may have one or both operands
16059 negated (if one, only the first one). For condition register
16060 logical operations, it will also treat the negated
16061 CR codes as NOTs, but not handle NOTs of them. */
16063 const char *const *t = 0;
16065 enum rtx_code code = GET_CODE (x);
16066 static const char * const tbl[3][3] = {
16067 { "and", "andc", "nor" },
16068 { "or", "orc", "nand" },
16069 { "xor", "eqv", "xor" } };
16073 else if (code == IOR)
16075 else if (code == XOR)
16078 output_operand_lossage ("invalid %%q value");
16080 if (GET_CODE (XEXP (x, 0)) != NOT)
16084 if (GET_CODE (XEXP (x, 1)) == NOT)
16102 /* X is a CR register. Print the mask for `mtcrf'. */
16103 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16104 output_operand_lossage ("invalid %%R value");
16106 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16110 /* Low 5 bits of 32 - value */
16112 output_operand_lossage ("invalid %%s value");
16114 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16118 /* PowerPC64 mask position. All 0's is excluded.
16119 CONST_INT 32-bit mask is considered sign-extended so any
16120 transition must occur within the CONST_INT, not on the boundary. */
16121 if (! mask64_operand (x, DImode))
16122 output_operand_lossage ("invalid %%S value");
16124 uval = INT_LOWPART (x);
16126 if (uval & 1) /* Clear Left */
16128 #if HOST_BITS_PER_WIDE_INT > 64
16129 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16133 else /* Clear Right */
16136 #if HOST_BITS_PER_WIDE_INT > 64
16137 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16143 gcc_assert (i >= 0);
16144 fprintf (file, "%d", i);
16148 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16149 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16151 /* Bit 3 is OV bit. */
16152 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16154 /* If we want bit 31, write a shift count of zero, not 32. */
16155 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16159 /* Print the symbolic name of a branch target register. */
16160 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16161 && REGNO (x) != CTR_REGNO))
16162 output_operand_lossage ("invalid %%T value");
16163 else if (REGNO (x) == LR_REGNO)
16164 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16166 fputs ("ctr", file);
16170 /* High-order 16 bits of constant for use in unsigned operand. */
16172 output_operand_lossage ("invalid %%u value");
16174 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16175 (INT_LOWPART (x) >> 16) & 0xffff);
16179 /* High-order 16 bits of constant for use in signed operand. */
16181 output_operand_lossage ("invalid %%v value");
16183 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16184 (INT_LOWPART (x) >> 16) & 0xffff);
16188 /* Print `u' if this has an auto-increment or auto-decrement. */
16189 if (GET_CODE (x) == MEM
16190 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16191 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16192 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16197 /* Print the trap code for this operand. */
16198 switch (GET_CODE (x))
16201 fputs ("eq", file); /* 4 */
16204 fputs ("ne", file); /* 24 */
16207 fputs ("lt", file); /* 16 */
16210 fputs ("le", file); /* 20 */
16213 fputs ("gt", file); /* 8 */
16216 fputs ("ge", file); /* 12 */
16219 fputs ("llt", file); /* 2 */
16222 fputs ("lle", file); /* 6 */
16225 fputs ("lgt", file); /* 1 */
16228 fputs ("lge", file); /* 5 */
16231 gcc_unreachable ();
16236 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16239 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16240 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16242 print_operand (file, x, 0);
16246 /* MB value for a PowerPC64 rldic operand. */
16247 val = (GET_CODE (x) == CONST_INT
16248 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16253 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16254 if ((val <<= 1) < 0)
16257 #if HOST_BITS_PER_WIDE_INT == 32
16258 if (GET_CODE (x) == CONST_INT && i >= 0)
16259 i += 32; /* zero-extend high-part was all 0's */
16260 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16262 val = CONST_DOUBLE_LOW (x);
16268 for ( ; i < 64; i++)
16269 if ((val <<= 1) < 0)
16274 fprintf (file, "%d", i + 1);
16278 /* X is a FPR or Altivec register used in a VSX context. */
16279 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16280 output_operand_lossage ("invalid %%x value");
16283 int reg = REGNO (x);
16284 int vsx_reg = (FP_REGNO_P (reg)
16286 : reg - FIRST_ALTIVEC_REGNO + 32);
16288 #ifdef TARGET_REGNAMES
16289 if (TARGET_REGNAMES)
16290 fprintf (file, "%%vs%d", vsx_reg);
16293 fprintf (file, "%d", vsx_reg);
16298 if (GET_CODE (x) == MEM
16299 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16300 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16301 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16306 /* Like 'L', for third word of TImode */
16307 if (GET_CODE (x) == REG)
16308 fputs (reg_names[REGNO (x) + 2], file);
16309 else if (GET_CODE (x) == MEM)
16311 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16312 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16313 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16314 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16315 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16317 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16318 if (small_data_operand (x, GET_MODE (x)))
16319 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16320 reg_names[SMALL_DATA_REG]);
16325 /* X is a SYMBOL_REF. Write out the name preceded by a
16326 period and without any trailing data in brackets. Used for function
16327 names. If we are configured for System V (or the embedded ABI) on
16328 the PowerPC, do not emit the period, since those systems do not use
16329 TOCs and the like. */
16330 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16332 /* Mark the decl as referenced so that cgraph will output the
16334 if (SYMBOL_REF_DECL (x))
16335 mark_decl_referenced (SYMBOL_REF_DECL (x));
16337 /* For macho, check to see if we need a stub. */
16340 const char *name = XSTR (x, 0);
16342 if (darwin_emit_branch_islands
16343 && MACHOPIC_INDIRECT
16344 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16345 name = machopic_indirection_name (x, /*stub_p=*/true);
16347 assemble_name (file, name);
16349 else if (!DOT_SYMBOLS)
16350 assemble_name (file, XSTR (x, 0));
16352 rs6000_output_function_entry (file, XSTR (x, 0));
16356 /* Like 'L', for last word of TImode. */
16357 if (GET_CODE (x) == REG)
16358 fputs (reg_names[REGNO (x) + 3], file);
16359 else if (GET_CODE (x) == MEM)
16361 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16362 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16363 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16364 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16365 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16367 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16368 if (small_data_operand (x, GET_MODE (x)))
16369 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16370 reg_names[SMALL_DATA_REG]);
16374 /* Print AltiVec or SPE memory operand. */
16379 gcc_assert (GET_CODE (x) == MEM);
16383 /* Ugly hack because %y is overloaded. */
16384 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16385 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16386 || GET_MODE (x) == TFmode
16387 || GET_MODE (x) == TImode))
16389 /* Handle [reg]. */
16390 if (GET_CODE (tmp) == REG)
16392 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16395 /* Handle [reg+UIMM]. */
16396 else if (GET_CODE (tmp) == PLUS &&
16397 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16401 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16403 x = INTVAL (XEXP (tmp, 1));
16404 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16408 /* Fall through. Must be [reg+reg]. */
16410 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16411 && GET_CODE (tmp) == AND
16412 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16413 && INTVAL (XEXP (tmp, 1)) == -16)
16414 tmp = XEXP (tmp, 0);
16415 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16416 && GET_CODE (tmp) == PRE_MODIFY)
16417 tmp = XEXP (tmp, 1);
16418 if (GET_CODE (tmp) == REG)
16419 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16422 if (!GET_CODE (tmp) == PLUS
16423 || !REG_P (XEXP (tmp, 0))
16424 || !REG_P (XEXP (tmp, 1)))
16426 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16430 if (REGNO (XEXP (tmp, 0)) == 0)
16431 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16432 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16434 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16435 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16441 if (GET_CODE (x) == REG)
16442 fprintf (file, "%s", reg_names[REGNO (x)]);
16443 else if (GET_CODE (x) == MEM)
16445 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16446 know the width from the mode. */
16447 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16448 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16449 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16450 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16451 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16452 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16453 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16454 output_address (XEXP (XEXP (x, 0), 1));
16456 output_address (XEXP (x, 0));
16460 if (toc_relative_expr_p (x))
16461 /* This hack along with a corresponding hack in
16462 rs6000_output_addr_const_extra arranges to output addends
16463 where the assembler expects to find them. eg.
16464 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16465 without this hack would be output as "x@toc+4". We
16467 output_addr_const (file, tocrel_base);
16469 output_addr_const (file, x);
16474 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16478 output_operand_lossage ("invalid %%xn code");
16482 /* Print the address of an operand. */
16485 print_operand_address (FILE *file, rtx x)
16487 if (GET_CODE (x) == REG)
16488 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16489 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16490 || GET_CODE (x) == LABEL_REF)
16492 output_addr_const (file, x);
16493 if (small_data_operand (x, GET_MODE (x)))
16494 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16495 reg_names[SMALL_DATA_REG]);
16497 gcc_assert (!TARGET_TOC);
16499 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16501 gcc_assert (REG_P (XEXP (x, 0)));
16502 if (REGNO (XEXP (x, 0)) == 0)
16503 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16504 reg_names[ REGNO (XEXP (x, 0)) ]);
16506 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16507 reg_names[ REGNO (XEXP (x, 1)) ]);
16509 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16510 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16511 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16513 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16514 && CONSTANT_P (XEXP (x, 1)))
16516 fprintf (file, "lo16(");
16517 output_addr_const (file, XEXP (x, 1));
16518 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16521 else if (legitimate_constant_pool_address_p (x, QImode, true))
16523 /* This hack along with a corresponding hack in
16524 rs6000_output_addr_const_extra arranges to output addends
16525 where the assembler expects to find them. eg.
16527 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16528 without this hack would be output as "x@toc+8@l(9)". We
16529 want "x+8@toc@l(9)". */
16530 output_addr_const (file, tocrel_base);
16531 if (GET_CODE (x) == LO_SUM)
16532 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16534 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16537 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16538 && CONSTANT_P (XEXP (x, 1)))
16540 output_addr_const (file, XEXP (x, 1));
16541 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16545 gcc_unreachable ();
16548 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16551 rs6000_output_addr_const_extra (FILE *file, rtx x)
16553 if (GET_CODE (x) == UNSPEC)
16554 switch (XINT (x, 1))
16556 case UNSPEC_TOCREL:
16557 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16558 output_addr_const (file, XVECEXP (x, 0, 0));
16559 if (x == tocrel_base && tocrel_offset != const0_rtx)
16561 if (INTVAL (tocrel_offset) >= 0)
16562 fprintf (file, "+");
16563 output_addr_const (file, tocrel_offset);
16565 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16568 assemble_name (file, toc_label_name);
16570 else if (TARGET_ELF)
16571 fputs ("@toc", file);
16575 case UNSPEC_MACHOPIC_OFFSET:
16576 output_addr_const (file, XVECEXP (x, 0, 0));
16578 machopic_output_function_base_name (file);
16585 /* Target hook for assembling integer objects. The PowerPC version has
16586 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16587 is defined. It also needs to handle DI-mode objects on 64-bit
16591 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16593 #ifdef RELOCATABLE_NEEDS_FIXUP
16594 /* Special handling for SI values. */
16595 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16597 static int recurse = 0;
16599 /* For -mrelocatable, we mark all addresses that need to be fixed up
16600 in the .fixup section. */
16601 if (TARGET_RELOCATABLE
16602 && in_section != toc_section
16603 && in_section != text_section
16604 && !unlikely_text_section_p (in_section)
16606 && GET_CODE (x) != CONST_INT
16607 && GET_CODE (x) != CONST_DOUBLE
16613 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16615 ASM_OUTPUT_LABEL (asm_out_file, buf);
16616 fprintf (asm_out_file, "\t.long\t(");
16617 output_addr_const (asm_out_file, x);
16618 fprintf (asm_out_file, ")@fixup\n");
16619 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16620 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16621 fprintf (asm_out_file, "\t.long\t");
16622 assemble_name (asm_out_file, buf);
16623 fprintf (asm_out_file, "\n\t.previous\n");
16627 /* Remove initial .'s to turn a -mcall-aixdesc function
16628 address into the address of the descriptor, not the function
16630 else if (GET_CODE (x) == SYMBOL_REF
16631 && XSTR (x, 0)[0] == '.'
16632 && DEFAULT_ABI == ABI_AIX)
16634 const char *name = XSTR (x, 0);
16635 while (*name == '.')
16638 fprintf (asm_out_file, "\t.long\t%s\n", name);
16642 #endif /* RELOCATABLE_NEEDS_FIXUP */
16643 return default_assemble_integer (x, size, aligned_p);
16646 #ifdef HAVE_GAS_HIDDEN
16647 /* Emit an assembler directive to set symbol visibility for DECL to
16648 VISIBILITY_TYPE. */
16651 rs6000_assemble_visibility (tree decl, int vis)
16653 /* Functions need to have their entry point symbol visibility set as
16654 well as their descriptor symbol visibility. */
16655 if (DEFAULT_ABI == ABI_AIX
16657 && TREE_CODE (decl) == FUNCTION_DECL)
16659 static const char * const visibility_types[] = {
16660 NULL, "internal", "hidden", "protected"
16663 const char *name, *type;
16665 name = ((* targetm.strip_name_encoding)
16666 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16667 type = visibility_types[vis];
16669 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16670 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16673 default_assemble_visibility (decl, vis);
16678 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16680 /* Reversal of FP compares takes care -- an ordered compare
16681 becomes an unordered compare and vice versa. */
16682 if (mode == CCFPmode
16683 && (!flag_finite_math_only
16684 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16685 || code == UNEQ || code == LTGT))
16686 return reverse_condition_maybe_unordered (code);
16688 return reverse_condition (code);
16691 /* Generate a compare for CODE. Return a brand-new rtx that
16692 represents the result of the compare. */
16695 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16697 enum machine_mode comp_mode;
16698 rtx compare_result;
16699 enum rtx_code code = GET_CODE (cmp);
16700 rtx op0 = XEXP (cmp, 0);
16701 rtx op1 = XEXP (cmp, 1);
16703 if (FLOAT_MODE_P (mode))
16704 comp_mode = CCFPmode;
16705 else if (code == GTU || code == LTU
16706 || code == GEU || code == LEU)
16707 comp_mode = CCUNSmode;
16708 else if ((code == EQ || code == NE)
16709 && GET_CODE (op0) == SUBREG
16710 && GET_CODE (op1) == SUBREG
16711 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16712 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16713 /* These are unsigned values, perhaps there will be a later
16714 ordering compare that can be shared with this one.
16715 Unfortunately we cannot detect the signedness of the operands
16716 for non-subregs. */
16717 comp_mode = CCUNSmode;
16719 comp_mode = CCmode;
16721 /* First, the compare. */
16722 compare_result = gen_reg_rtx (comp_mode);
16724 /* E500 FP compare instructions on the GPRs. Yuck! */
16725 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16726 && FLOAT_MODE_P (mode))
16728 rtx cmp, or_result, compare_result2;
16729 enum machine_mode op_mode = GET_MODE (op0);
16731 if (op_mode == VOIDmode)
16732 op_mode = GET_MODE (op1);
16734 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16735 This explains the following mess. */
16739 case EQ: case UNEQ: case NE: case LTGT:
16743 cmp = (flag_finite_math_only && !flag_trapping_math)
16744 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16745 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16749 cmp = (flag_finite_math_only && !flag_trapping_math)
16750 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16751 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16755 cmp = (flag_finite_math_only && !flag_trapping_math)
16756 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16757 : gen_cmptfeq_gpr (compare_result, op0, op1);
16761 gcc_unreachable ();
16765 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16769 cmp = (flag_finite_math_only && !flag_trapping_math)
16770 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16771 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16775 cmp = (flag_finite_math_only && !flag_trapping_math)
16776 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16777 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16781 cmp = (flag_finite_math_only && !flag_trapping_math)
16782 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16783 : gen_cmptfgt_gpr (compare_result, op0, op1);
16787 gcc_unreachable ();
16791 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16795 cmp = (flag_finite_math_only && !flag_trapping_math)
16796 ? gen_tstsflt_gpr (compare_result, op0, op1)
16797 : gen_cmpsflt_gpr (compare_result, op0, op1);
16801 cmp = (flag_finite_math_only && !flag_trapping_math)
16802 ? gen_tstdflt_gpr (compare_result, op0, op1)
16803 : gen_cmpdflt_gpr (compare_result, op0, op1);
16807 cmp = (flag_finite_math_only && !flag_trapping_math)
16808 ? gen_tsttflt_gpr (compare_result, op0, op1)
16809 : gen_cmptflt_gpr (compare_result, op0, op1);
16813 gcc_unreachable ();
16817 gcc_unreachable ();
16820 /* Synthesize LE and GE from LT/GT || EQ. */
16821 if (code == LE || code == GE || code == LEU || code == GEU)
16827 case LE: code = LT; break;
16828 case GE: code = GT; break;
16829 case LEU: code = LT; break;
16830 case GEU: code = GT; break;
16831 default: gcc_unreachable ();
16834 compare_result2 = gen_reg_rtx (CCFPmode);
16840 cmp = (flag_finite_math_only && !flag_trapping_math)
16841 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16842 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16846 cmp = (flag_finite_math_only && !flag_trapping_math)
16847 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16848 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16852 cmp = (flag_finite_math_only && !flag_trapping_math)
16853 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16854 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16858 gcc_unreachable ();
16862 /* OR them together. */
16863 or_result = gen_reg_rtx (CCFPmode);
16864 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16866 compare_result = or_result;
16871 if (code == NE || code == LTGT)
16881 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16882 CLOBBERs to match cmptf_internal2 pattern. */
16883 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16884 && GET_MODE (op0) == TFmode
16885 && !TARGET_IEEEQUAD
16886 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16887 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16889 gen_rtx_SET (VOIDmode,
16891 gen_rtx_COMPARE (comp_mode, op0, op1)),
16892 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16893 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16894 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16895 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16896 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16897 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16898 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16899 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16900 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16901 else if (GET_CODE (op1) == UNSPEC
16902 && XINT (op1, 1) == UNSPEC_SP_TEST)
16904 rtx op1b = XVECEXP (op1, 0, 0);
16905 comp_mode = CCEQmode;
16906 compare_result = gen_reg_rtx (CCEQmode);
16908 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16910 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16913 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16914 gen_rtx_COMPARE (comp_mode, op0, op1)));
16917 /* Some kinds of FP comparisons need an OR operation;
16918 under flag_finite_math_only we don't bother. */
16919 if (FLOAT_MODE_P (mode)
16920 && !flag_finite_math_only
16921 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16922 && (code == LE || code == GE
16923 || code == UNEQ || code == LTGT
16924 || code == UNGT || code == UNLT))
16926 enum rtx_code or1, or2;
16927 rtx or1_rtx, or2_rtx, compare2_rtx;
16928 rtx or_result = gen_reg_rtx (CCEQmode);
16932 case LE: or1 = LT; or2 = EQ; break;
16933 case GE: or1 = GT; or2 = EQ; break;
16934 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16935 case LTGT: or1 = LT; or2 = GT; break;
16936 case UNGT: or1 = UNORDERED; or2 = GT; break;
16937 case UNLT: or1 = UNORDERED; or2 = LT; break;
16938 default: gcc_unreachable ();
16940 validate_condition_mode (or1, comp_mode);
16941 validate_condition_mode (or2, comp_mode);
16942 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16943 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16944 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16945 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16947 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16949 compare_result = or_result;
16953 validate_condition_mode (code, GET_MODE (compare_result));
16955 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16959 /* Emit the RTL for an sISEL pattern. */
16962 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16964 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16968 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16971 enum machine_mode op_mode;
16972 enum rtx_code cond_code;
16973 rtx result = operands[0];
16975 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16977 rs6000_emit_sISEL (mode, operands);
16981 condition_rtx = rs6000_generate_compare (operands[1], mode);
16982 cond_code = GET_CODE (condition_rtx);
16984 if (FLOAT_MODE_P (mode)
16985 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16989 PUT_MODE (condition_rtx, SImode);
16990 t = XEXP (condition_rtx, 0);
16992 gcc_assert (cond_code == NE || cond_code == EQ);
16994 if (cond_code == NE)
16995 emit_insn (gen_e500_flip_gt_bit (t, t));
16997 emit_insn (gen_move_from_CR_gt_bit (result, t));
17001 if (cond_code == NE
17002 || cond_code == GE || cond_code == LE
17003 || cond_code == GEU || cond_code == LEU
17004 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
17006 rtx not_result = gen_reg_rtx (CCEQmode);
17007 rtx not_op, rev_cond_rtx;
17008 enum machine_mode cc_mode;
17010 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
17012 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
17013 SImode, XEXP (condition_rtx, 0), const0_rtx);
17014 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
17015 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
17016 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
17019 op_mode = GET_MODE (XEXP (operands[1], 0));
17020 if (op_mode == VOIDmode)
17021 op_mode = GET_MODE (XEXP (operands[1], 1));
17023 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
17025 PUT_MODE (condition_rtx, DImode);
17026 convert_move (result, condition_rtx, 0);
17030 PUT_MODE (condition_rtx, SImode);
17031 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
17035 /* Emit a branch of kind CODE to location LOC. */
17038 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
17040 rtx condition_rtx, loc_ref;
17042 condition_rtx = rs6000_generate_compare (operands[0], mode);
17043 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
17044 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
17045 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
17046 loc_ref, pc_rtx)));
17049 /* Return the string to output a conditional branch to LABEL, which is
17050 the operand number of the label, or -1 if the branch is really a
17051 conditional return.
17053 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17054 condition code register and its mode specifies what kind of
17055 comparison we made.
17057 REVERSED is nonzero if we should reverse the sense of the comparison.
17059 INSN is the insn. */
17062 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
17064 static char string[64];
17065 enum rtx_code code = GET_CODE (op);
17066 rtx cc_reg = XEXP (op, 0);
17067 enum machine_mode mode = GET_MODE (cc_reg);
17068 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
17069 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
17070 int really_reversed = reversed ^ need_longbranch;
17076 validate_condition_mode (code, mode);
17078 /* Work out which way this really branches. We could use
17079 reverse_condition_maybe_unordered here always but this
17080 makes the resulting assembler clearer. */
17081 if (really_reversed)
17083 /* Reversal of FP compares takes care -- an ordered compare
17084 becomes an unordered compare and vice versa. */
17085 if (mode == CCFPmode)
17086 code = reverse_condition_maybe_unordered (code);
17088 code = reverse_condition (code);
17091 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17093 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17098 /* Opposite of GT. */
17107 gcc_unreachable ();
17113 /* Not all of these are actually distinct opcodes, but
17114 we distinguish them for clarity of the resulting assembler. */
17115 case NE: case LTGT:
17116 ccode = "ne"; break;
17117 case EQ: case UNEQ:
17118 ccode = "eq"; break;
17120 ccode = "ge"; break;
17121 case GT: case GTU: case UNGT:
17122 ccode = "gt"; break;
17124 ccode = "le"; break;
17125 case LT: case LTU: case UNLT:
17126 ccode = "lt"; break;
17127 case UNORDERED: ccode = "un"; break;
17128 case ORDERED: ccode = "nu"; break;
17129 case UNGE: ccode = "nl"; break;
17130 case UNLE: ccode = "ng"; break;
17132 gcc_unreachable ();
17135 /* Maybe we have a guess as to how likely the branch is.
17136 The old mnemonics don't have a way to specify this information. */
17138 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17139 if (note != NULL_RTX)
17141 /* PROB is the difference from 50%. */
17142 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17144 /* Only hint for highly probable/improbable branches on newer
17145 cpus as static prediction overrides processor dynamic
17146 prediction. For older cpus we may as well always hint, but
17147 assume not taken for branches that are very close to 50% as a
17148 mispredicted taken branch is more expensive than a
17149 mispredicted not-taken branch. */
17150 if (rs6000_always_hint
17151 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17152 && br_prob_note_reliable_p (note)))
17154 if (abs (prob) > REG_BR_PROB_BASE / 20
17155 && ((prob > 0) ^ need_longbranch))
17163 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17165 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17167 /* We need to escape any '%' characters in the reg_names string.
17168 Assume they'd only be the first character.... */
17169 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17171 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17175 /* If the branch distance was too far, we may have to use an
17176 unconditional branch to go the distance. */
17177 if (need_longbranch)
17178 s += sprintf (s, ",$+8\n\tb %s", label);
17180 s += sprintf (s, ",%s", label);
17186 /* Return the string to flip the GT bit on a CR. */
17188 output_e500_flip_gt_bit (rtx dst, rtx src)
17190 static char string[64];
17193 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17194 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17197 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17198 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17200 sprintf (string, "crnot %d,%d", a, b);
17204 /* Return insn for VSX or Altivec comparisons. */
17207 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17210 enum machine_mode mode = GET_MODE (op0);
17218 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17224 mask = gen_reg_rtx (mode);
17225 emit_insn (gen_rtx_SET (VOIDmode,
17227 gen_rtx_fmt_ee (code, mode, op0, op1)));
17234 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17235 DMODE is expected destination mode. This is a recursive function. */
17238 rs6000_emit_vector_compare (enum rtx_code rcode,
17240 enum machine_mode dmode)
17243 bool swap_operands = false;
17244 bool try_again = false;
17246 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17247 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17249 /* See if the comparison works as is. */
17250 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17258 swap_operands = true;
17263 swap_operands = true;
17271 /* Invert condition and try again.
17272 e.g., A != B becomes ~(A==B). */
17274 enum rtx_code rev_code;
17275 enum insn_code nor_code;
17278 rev_code = reverse_condition_maybe_unordered (rcode);
17279 if (rev_code == UNKNOWN)
17282 nor_code = optab_handler (one_cmpl_optab, dmode);
17283 if (nor_code == CODE_FOR_nothing)
17286 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17290 mask = gen_reg_rtx (dmode);
17291 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17299 /* Try GT/GTU/LT/LTU OR EQ */
17302 enum insn_code ior_code;
17303 enum rtx_code new_code;
17324 gcc_unreachable ();
17327 ior_code = optab_handler (ior_optab, dmode);
17328 if (ior_code == CODE_FOR_nothing)
17331 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17335 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17339 mask = gen_reg_rtx (dmode);
17340 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17358 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17363 /* You only get two chances. */
17367 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17368 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17369 operands for the relation operation COND. */
17372 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17373 rtx cond, rtx cc_op0, rtx cc_op1)
17375 enum machine_mode dest_mode = GET_MODE (dest);
17376 enum rtx_code rcode = GET_CODE (cond);
17377 enum machine_mode cc_mode = CCmode;
17381 bool invert_move = false;
17383 if (VECTOR_UNIT_NONE_P (dest_mode))
17388 /* Swap operands if we can, and fall back to doing the operation as
17389 specified, and doing a NOR to invert the test. */
17395 /* Invert condition and try again.
17396 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17397 invert_move = true;
17398 rcode = reverse_condition_maybe_unordered (rcode);
17399 if (rcode == UNKNOWN)
17403 /* Mark unsigned tests with CCUNSmode. */
17408 cc_mode = CCUNSmode;
17415 /* Get the vector mask for the given relational operations. */
17416 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17424 op_true = op_false;
17428 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17429 emit_insn (gen_rtx_SET (VOIDmode,
17431 gen_rtx_IF_THEN_ELSE (dest_mode,
17438 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17439 operands of the last comparison is nonzero/true, FALSE_COND if it
17440 is zero/false. Return 0 if the hardware has no such operation. */
17443 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17445 enum rtx_code code = GET_CODE (op);
17446 rtx op0 = XEXP (op, 0);
17447 rtx op1 = XEXP (op, 1);
17448 REAL_VALUE_TYPE c1;
17449 enum machine_mode compare_mode = GET_MODE (op0);
17450 enum machine_mode result_mode = GET_MODE (dest);
17452 bool is_against_zero;
17454 /* These modes should always match. */
17455 if (GET_MODE (op1) != compare_mode
17456 /* In the isel case however, we can use a compare immediate, so
17457 op1 may be a small constant. */
17458 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17460 if (GET_MODE (true_cond) != result_mode)
17462 if (GET_MODE (false_cond) != result_mode)
17465 /* First, work out if the hardware can do this at all, or
17466 if it's too slow.... */
17467 if (!FLOAT_MODE_P (compare_mode))
17470 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17473 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17474 && SCALAR_FLOAT_MODE_P (compare_mode))
17477 is_against_zero = op1 == CONST0_RTX (compare_mode);
17479 /* A floating-point subtract might overflow, underflow, or produce
17480 an inexact result, thus changing the floating-point flags, so it
17481 can't be generated if we care about that. It's safe if one side
17482 of the construct is zero, since then no subtract will be
17484 if (SCALAR_FLOAT_MODE_P (compare_mode)
17485 && flag_trapping_math && ! is_against_zero)
17488 /* Eliminate half of the comparisons by switching operands, this
17489 makes the remaining code simpler. */
17490 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17491 || code == LTGT || code == LT || code == UNLE)
17493 code = reverse_condition_maybe_unordered (code);
17495 true_cond = false_cond;
17499 /* UNEQ and LTGT take four instructions for a comparison with zero,
17500 it'll probably be faster to use a branch here too. */
17501 if (code == UNEQ && HONOR_NANS (compare_mode))
17504 if (GET_CODE (op1) == CONST_DOUBLE)
17505 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17507 /* We're going to try to implement comparisons by performing
17508 a subtract, then comparing against zero. Unfortunately,
17509 Inf - Inf is NaN which is not zero, and so if we don't
17510 know that the operand is finite and the comparison
17511 would treat EQ different to UNORDERED, we can't do it. */
17512 if (HONOR_INFINITIES (compare_mode)
17513 && code != GT && code != UNGE
17514 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17515 /* Constructs of the form (a OP b ? a : b) are safe. */
17516 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17517 || (! rtx_equal_p (op0, true_cond)
17518 && ! rtx_equal_p (op1, true_cond))))
17521 /* At this point we know we can use fsel. */
17523 /* Reduce the comparison to a comparison against zero. */
17524 if (! is_against_zero)
17526 temp = gen_reg_rtx (compare_mode);
17527 emit_insn (gen_rtx_SET (VOIDmode, temp,
17528 gen_rtx_MINUS (compare_mode, op0, op1)));
17530 op1 = CONST0_RTX (compare_mode);
17533 /* If we don't care about NaNs we can reduce some of the comparisons
17534 down to faster ones. */
17535 if (! HONOR_NANS (compare_mode))
17541 true_cond = false_cond;
17554 /* Now, reduce everything down to a GE. */
17561 temp = gen_reg_rtx (compare_mode);
17562 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17567 temp = gen_reg_rtx (compare_mode);
17568 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17573 temp = gen_reg_rtx (compare_mode);
17574 emit_insn (gen_rtx_SET (VOIDmode, temp,
17575 gen_rtx_NEG (compare_mode,
17576 gen_rtx_ABS (compare_mode, op0))));
17581 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17582 temp = gen_reg_rtx (result_mode);
17583 emit_insn (gen_rtx_SET (VOIDmode, temp,
17584 gen_rtx_IF_THEN_ELSE (result_mode,
17585 gen_rtx_GE (VOIDmode,
17587 true_cond, false_cond)));
17588 false_cond = true_cond;
17591 temp = gen_reg_rtx (compare_mode);
17592 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17597 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17598 temp = gen_reg_rtx (result_mode);
17599 emit_insn (gen_rtx_SET (VOIDmode, temp,
17600 gen_rtx_IF_THEN_ELSE (result_mode,
17601 gen_rtx_GE (VOIDmode,
17603 true_cond, false_cond)));
17604 true_cond = false_cond;
17607 temp = gen_reg_rtx (compare_mode);
17608 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17613 gcc_unreachable ();
17616 emit_insn (gen_rtx_SET (VOIDmode, dest,
17617 gen_rtx_IF_THEN_ELSE (result_mode,
17618 gen_rtx_GE (VOIDmode,
17620 true_cond, false_cond)));
17624 /* Same as above, but for ints (isel). */
17627 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17629 rtx condition_rtx, cr;
17630 enum machine_mode mode = GET_MODE (dest);
17631 enum rtx_code cond_code;
17632 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17635 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17638 /* We still have to do the compare, because isel doesn't do a
17639 compare, it just looks at the CRx bits set by a previous compare
17641 condition_rtx = rs6000_generate_compare (op, mode);
17642 cond_code = GET_CODE (condition_rtx);
17643 cr = XEXP (condition_rtx, 0);
17644 signedp = GET_MODE (cr) == CCmode;
17646 isel_func = (mode == SImode
17647 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17648 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17652 case LT: case GT: case LTU: case GTU: case EQ:
17653 /* isel handles these directly. */
17657 /* We need to swap the sense of the comparison. */
17660 true_cond = false_cond;
17662 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17667 false_cond = force_reg (mode, false_cond);
17668 if (true_cond != const0_rtx)
17669 true_cond = force_reg (mode, true_cond);
17671 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17677 output_isel (rtx *operands)
17679 enum rtx_code code;
17681 code = GET_CODE (operands[1]);
17683 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17685 gcc_assert (GET_CODE (operands[2]) == REG
17686 && GET_CODE (operands[3]) == REG);
17687 PUT_CODE (operands[1], reverse_condition (code));
17688 return "isel %0,%3,%2,%j1";
17691 return "isel %0,%2,%3,%j1";
17695 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17697 enum machine_mode mode = GET_MODE (op0);
17701 /* VSX/altivec have direct min/max insns. */
17702 if ((code == SMAX || code == SMIN)
17703 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17704 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17706 emit_insn (gen_rtx_SET (VOIDmode,
17708 gen_rtx_fmt_ee (code, mode, op0, op1)));
17712 if (code == SMAX || code == SMIN)
17717 if (code == SMAX || code == UMAX)
17718 target = emit_conditional_move (dest, c, op0, op1, mode,
17719 op0, op1, mode, 0);
17721 target = emit_conditional_move (dest, c, op0, op1, mode,
17722 op1, op0, mode, 0);
17723 gcc_assert (target);
17724 if (target != dest)
17725 emit_move_insn (dest, target);
17728 /* Emit instructions to perform a load-reserved/store-conditional operation.
17729 The operation performed is an atomic
17730 (set M (CODE:MODE M OP))
17731 If not NULL, BEFORE is atomically set to M before the operation, and
17732 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17733 If SYNC_P then a memory barrier is emitted before the operation.
17734 Either OP or M may be wrapped in a NOT operation. */
17737 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17738 rtx m, rtx op, rtx before_param, rtx after_param,
17741 enum machine_mode used_mode;
17742 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17745 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17746 rtx shift = NULL_RTX;
17749 emit_insn (gen_lwsync ());
17753 /* If this is smaller than SImode, we'll have to use SImode with
17755 if (mode == QImode || mode == HImode)
17759 if (MEM_ALIGN (used_m) >= 32)
17762 if (BYTES_BIG_ENDIAN)
17763 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17765 shift = GEN_INT (ishift);
17766 used_m = change_address (used_m, SImode, 0);
17770 rtx addrSI, aligned_addr;
17771 int shift_mask = mode == QImode ? 0x18 : 0x10;
17773 addrSI = gen_lowpart_common (SImode,
17774 force_reg (Pmode, XEXP (used_m, 0)));
17775 addrSI = force_reg (SImode, addrSI);
17776 shift = gen_reg_rtx (SImode);
17778 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17779 GEN_INT (shift_mask)));
17780 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17782 aligned_addr = expand_binop (Pmode, and_optab,
17784 GEN_INT (-4), NULL_RTX,
17785 1, OPTAB_LIB_WIDEN);
17786 used_m = change_address (used_m, SImode, aligned_addr);
17787 set_mem_align (used_m, 32);
17789 /* It's safe to keep the old alias set of USED_M, because
17790 the operation is atomic and only affects the original
17794 if (GET_CODE (op) == NOT)
17796 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17797 oldop = gen_rtx_NOT (SImode, oldop);
17800 oldop = lowpart_subreg (SImode, op, mode);
17806 newop = expand_binop (SImode, and_optab,
17807 oldop, GEN_INT (imask), NULL_RTX,
17808 1, OPTAB_LIB_WIDEN);
17809 emit_insn (gen_ashlsi3 (newop, newop, shift));
17812 case NOT: /* NAND */
17813 newop = expand_binop (SImode, ior_optab,
17814 oldop, GEN_INT (~imask), NULL_RTX,
17815 1, OPTAB_LIB_WIDEN);
17816 emit_insn (gen_rotlsi3 (newop, newop, shift));
17820 newop = expand_binop (SImode, ior_optab,
17821 oldop, GEN_INT (~imask), NULL_RTX,
17822 1, OPTAB_LIB_WIDEN);
17823 emit_insn (gen_rotlsi3 (newop, newop, shift));
17831 newop = expand_binop (SImode, and_optab,
17832 oldop, GEN_INT (imask), NULL_RTX,
17833 1, OPTAB_LIB_WIDEN);
17834 emit_insn (gen_ashlsi3 (newop, newop, shift));
17836 mask = gen_reg_rtx (SImode);
17837 emit_move_insn (mask, GEN_INT (imask));
17838 emit_insn (gen_ashlsi3 (mask, mask, shift));
17841 newop = gen_rtx_PLUS (SImode, m, newop);
17843 newop = gen_rtx_MINUS (SImode, m, newop);
17844 newop = gen_rtx_AND (SImode, newop, mask);
17845 newop = gen_rtx_IOR (SImode, newop,
17846 gen_rtx_AND (SImode,
17847 gen_rtx_NOT (SImode, mask),
17853 gcc_unreachable ();
17857 used_mode = SImode;
17858 before = gen_reg_rtx (used_mode);
17859 after = gen_reg_rtx (used_mode);
17864 before = before_param;
17865 after = after_param;
17867 if (before == NULL_RTX)
17868 before = gen_reg_rtx (used_mode);
17869 if (after == NULL_RTX)
17870 after = gen_reg_rtx (used_mode);
17873 if ((code == PLUS || code == MINUS)
17874 && used_mode != mode)
17875 the_op = op; /* Computed above. */
17876 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17877 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17878 else if (code == NOT)
17879 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17880 gen_rtx_NOT (used_mode, m),
17881 gen_rtx_NOT (used_mode, op));
17883 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17885 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17886 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17887 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17888 gen_rtx_UNSPEC (used_mode,
17889 gen_rtvec (1, the_op),
17891 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17893 if ((code == PLUS || code == MINUS) && used_mode != mode)
17894 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17895 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17897 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17898 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17900 /* Shift and mask the return values properly. */
17901 if (used_mode != mode && before_param)
17903 emit_insn (gen_lshrsi3 (before, before, shift));
17904 convert_move (before_param, before, 1);
17907 if (used_mode != mode && after_param)
17909 emit_insn (gen_lshrsi3 (after, after, shift));
17910 convert_move (after_param, after, 1);
17913 /* The previous sequence will end with a branch that's dependent on
17914 the conditional store, so placing an isync will ensure that no
17915 other instructions (especially, no load or store instructions)
17916 can start before the atomic operation completes. */
17918 emit_insn (gen_isync ());
17921 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17922 COND is true. Mark the jump as unlikely to be taken. */
17925 emit_unlikely_jump (rtx cond, rtx label)
17927 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17930 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17931 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17932 add_reg_note (x, REG_BR_PROB, very_unlikely);
17935 /* A subroutine of the atomic operation splitters. Emit a load-locked
17936 instruction in MODE. */
17939 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17941 rtx (*fn) (rtx, rtx) = NULL;
17942 if (mode == SImode)
17943 fn = gen_load_locked_si;
17944 else if (mode == DImode)
17945 fn = gen_load_locked_di;
17946 emit_insn (fn (reg, mem));
17949 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17950 instruction in MODE. */
17953 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17955 rtx (*fn) (rtx, rtx, rtx) = NULL;
17956 if (mode == SImode)
17957 fn = gen_store_conditional_si;
17958 else if (mode == DImode)
17959 fn = gen_store_conditional_di;
17961 /* Emit sync before stwcx. to address PPC405 Erratum. */
17962 if (PPC405_ERRATUM77)
17963 emit_insn (gen_memory_barrier ());
17965 emit_insn (fn (res, mem, val));
17968 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17969 to perform. MEM is the memory on which to operate. VAL is the second
17970 operand of the binary operator. BEFORE and AFTER are optional locations to
17971 return the value of MEM either before of after the operation. SCRATCH is
17972 a scratch register. */
17975 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17976 rtx before, rtx after, rtx scratch)
17978 enum machine_mode mode = GET_MODE (mem);
17979 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17981 emit_insn (gen_lwsync ());
17983 label = gen_label_rtx ();
17984 emit_label (label);
17985 label = gen_rtx_LABEL_REF (VOIDmode, label);
17987 if (before == NULL_RTX)
17989 emit_load_locked (mode, before, mem);
17992 x = gen_rtx_IOR (mode,
17993 gen_rtx_NOT (mode, before),
17994 gen_rtx_NOT (mode, val));
17995 else if (code == AND)
17996 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17998 x = gen_rtx_fmt_ee (code, mode, before, val);
18000 if (after != NULL_RTX)
18001 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
18002 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
18004 emit_store_conditional (mode, cond, mem, scratch);
18006 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18007 emit_unlikely_jump (x, label);
18009 emit_insn (gen_isync ());
18012 /* Expand an atomic compare and swap operation. MEM is the memory on which
18013 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18014 value to be stored. SCRATCH is a scratch GPR. */
18017 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
18020 enum machine_mode mode = GET_MODE (mem);
18021 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18023 emit_insn (gen_lwsync ());
18025 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18026 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18027 emit_label (XEXP (label1, 0));
18029 emit_load_locked (mode, retval, mem);
18031 x = gen_rtx_COMPARE (CCmode, retval, oldval);
18032 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18034 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18035 emit_unlikely_jump (x, label2);
18037 emit_move_insn (scratch, newval);
18038 emit_store_conditional (mode, cond, mem, scratch);
18040 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18041 emit_unlikely_jump (x, label1);
18043 emit_insn (gen_isync ());
18044 emit_label (XEXP (label2, 0));
18047 /* Expand an atomic test and set operation. MEM is the memory on which
18048 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18051 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
18053 enum machine_mode mode = GET_MODE (mem);
18054 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18056 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18057 emit_label (XEXP (label, 0));
18059 emit_load_locked (mode, retval, mem);
18060 emit_move_insn (scratch, val);
18061 emit_store_conditional (mode, cond, mem, scratch);
18063 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18064 emit_unlikely_jump (x, label);
18066 emit_insn (gen_isync ());
18070 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
18072 enum machine_mode mode = GET_MODE (mem);
18073 rtx addrSI, align, wdst, shift, mask;
18074 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18075 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18077 /* Shift amount for subword relative to aligned word. */
18078 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18079 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18080 shift = gen_reg_rtx (SImode);
18081 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18082 GEN_INT (shift_mask)));
18083 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18085 /* Shift and mask old value into position within word. */
18086 oldval = convert_modes (SImode, mode, oldval, 1);
18087 oldval = expand_binop (SImode, and_optab,
18088 oldval, GEN_INT (imask), NULL_RTX,
18089 1, OPTAB_LIB_WIDEN);
18090 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18092 /* Shift and mask new value into position within word. */
18093 newval = convert_modes (SImode, mode, newval, 1);
18094 newval = expand_binop (SImode, and_optab,
18095 newval, GEN_INT (imask), NULL_RTX,
18096 1, OPTAB_LIB_WIDEN);
18097 emit_insn (gen_ashlsi3 (newval, newval, shift));
18099 /* Mask for insertion. */
18100 mask = gen_reg_rtx (SImode);
18101 emit_move_insn (mask, GEN_INT (imask));
18102 emit_insn (gen_ashlsi3 (mask, mask, shift));
18104 /* Address of aligned word containing subword. */
18105 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18106 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18107 mem = change_address (mem, SImode, align);
18108 set_mem_align (mem, 32);
18109 MEM_VOLATILE_P (mem) = 1;
18111 wdst = gen_reg_rtx (SImode);
18112 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18113 oldval, newval, mem));
18115 /* Shift the result back. */
18116 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18118 emit_move_insn (dst, gen_lowpart (mode, wdst));
18122 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18123 rtx oldval, rtx newval, rtx mem,
18126 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18128 emit_insn (gen_lwsync ());
18129 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18130 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18131 emit_label (XEXP (label1, 0));
18133 emit_load_locked (SImode, scratch, mem);
18135 /* Mask subword within loaded value for comparison with oldval.
18136 Use UNSPEC_AND to avoid clobber.*/
18137 emit_insn (gen_rtx_SET (SImode, dest,
18138 gen_rtx_UNSPEC (SImode,
18139 gen_rtvec (2, scratch, mask),
18142 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18143 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18145 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18146 emit_unlikely_jump (x, label2);
18148 /* Clear subword within loaded value for insertion of new value. */
18149 emit_insn (gen_rtx_SET (SImode, scratch,
18150 gen_rtx_AND (SImode,
18151 gen_rtx_NOT (SImode, mask), scratch)));
18152 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18153 emit_store_conditional (SImode, cond, mem, scratch);
18155 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18156 emit_unlikely_jump (x, label1);
18158 emit_insn (gen_isync ());
18159 emit_label (XEXP (label2, 0));
18163 /* Emit instructions to move SRC to DST. Called by splitters for
18164 multi-register moves. It will emit at most one instruction for
18165 each register that is accessed; that is, it won't emit li/lis pairs
18166 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18170 rs6000_split_multireg_move (rtx dst, rtx src)
18172 /* The register number of the first register being moved. */
18174 /* The mode that is to be moved. */
18175 enum machine_mode mode;
18176 /* The mode that the move is being done in, and its size. */
18177 enum machine_mode reg_mode;
18179 /* The number of registers that will be moved. */
18182 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18183 mode = GET_MODE (dst);
18184 nregs = hard_regno_nregs[reg][mode];
18185 if (FP_REGNO_P (reg))
18186 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18187 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18188 else if (ALTIVEC_REGNO_P (reg))
18189 reg_mode = V16QImode;
18190 else if (TARGET_E500_DOUBLE && mode == TFmode)
18193 reg_mode = word_mode;
18194 reg_mode_size = GET_MODE_SIZE (reg_mode);
18196 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18198 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18200 /* Move register range backwards, if we might have destructive
18203 for (i = nregs - 1; i >= 0; i--)
18204 emit_insn (gen_rtx_SET (VOIDmode,
18205 simplify_gen_subreg (reg_mode, dst, mode,
18206 i * reg_mode_size),
18207 simplify_gen_subreg (reg_mode, src, mode,
18208 i * reg_mode_size)));
18214 bool used_update = false;
18215 rtx restore_basereg = NULL_RTX;
18217 if (MEM_P (src) && INT_REGNO_P (reg))
18221 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18222 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18225 breg = XEXP (XEXP (src, 0), 0);
18226 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18227 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18228 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18229 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18230 src = replace_equiv_address (src, breg);
18232 else if (! rs6000_offsettable_memref_p (src))
18234 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18236 rtx basereg = XEXP (XEXP (src, 0), 0);
18239 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18240 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18241 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18242 used_update = true;
18245 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18246 XEXP (XEXP (src, 0), 1)));
18247 src = replace_equiv_address (src, basereg);
18251 rtx basereg = gen_rtx_REG (Pmode, reg);
18252 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18253 src = replace_equiv_address (src, basereg);
18257 breg = XEXP (src, 0);
18258 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18259 breg = XEXP (breg, 0);
18261 /* If the base register we are using to address memory is
18262 also a destination reg, then change that register last. */
18264 && REGNO (breg) >= REGNO (dst)
18265 && REGNO (breg) < REGNO (dst) + nregs)
18266 j = REGNO (breg) - REGNO (dst);
18268 else if (MEM_P (dst) && INT_REGNO_P (reg))
18272 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18273 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18276 breg = XEXP (XEXP (dst, 0), 0);
18277 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18278 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18279 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18281 /* We have to update the breg before doing the store.
18282 Use store with update, if available. */
18286 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18287 emit_insn (TARGET_32BIT
18288 ? (TARGET_POWERPC64
18289 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18290 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18291 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18292 used_update = true;
18295 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18296 dst = replace_equiv_address (dst, breg);
18298 else if (!rs6000_offsettable_memref_p (dst)
18299 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18301 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18303 rtx basereg = XEXP (XEXP (dst, 0), 0);
18306 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18307 emit_insn (gen_rtx_SET (VOIDmode,
18308 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18309 used_update = true;
18312 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18313 XEXP (XEXP (dst, 0), 1)));
18314 dst = replace_equiv_address (dst, basereg);
18318 rtx basereg = XEXP (XEXP (dst, 0), 0);
18319 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18320 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18322 && REG_P (offsetreg)
18323 && REGNO (basereg) != REGNO (offsetreg));
18324 if (REGNO (basereg) == 0)
18326 rtx tmp = offsetreg;
18327 offsetreg = basereg;
18330 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18331 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18332 dst = replace_equiv_address (dst, basereg);
18335 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18336 gcc_assert (rs6000_offsettable_memref_p (dst));
18339 for (i = 0; i < nregs; i++)
18341 /* Calculate index to next subword. */
18346 /* If compiler already emitted move of first word by
18347 store with update, no need to do anything. */
18348 if (j == 0 && used_update)
18351 emit_insn (gen_rtx_SET (VOIDmode,
18352 simplify_gen_subreg (reg_mode, dst, mode,
18353 j * reg_mode_size),
18354 simplify_gen_subreg (reg_mode, src, mode,
18355 j * reg_mode_size)));
18357 if (restore_basereg != NULL_RTX)
18358 emit_insn (restore_basereg);
18363 /* This page contains routines that are used to determine what the
18364 function prologue and epilogue code will do and write them out. */
18366 /* Return the first fixed-point register that is required to be
18367 saved. 32 if none. */
18370 first_reg_to_save (void)
18374 /* Find lowest numbered live register. */
18375 for (first_reg = 13; first_reg <= 31; first_reg++)
18376 if (df_regs_ever_live_p (first_reg)
18377 && (! call_used_regs[first_reg]
18378 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18379 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18380 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18381 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18386 && crtl->uses_pic_offset_table
18387 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18388 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18394 /* Similar, for FP regs. */
18397 first_fp_reg_to_save (void)
18401 /* Find lowest numbered live register. */
18402 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18403 if (df_regs_ever_live_p (first_reg))
18409 /* Similar, for AltiVec regs. */
18412 first_altivec_reg_to_save (void)
18416 /* Stack frame remains as is unless we are in AltiVec ABI. */
18417 if (! TARGET_ALTIVEC_ABI)
18418 return LAST_ALTIVEC_REGNO + 1;
18420 /* On Darwin, the unwind routines are compiled without
18421 TARGET_ALTIVEC, and use save_world to save/restore the
18422 altivec registers when necessary. */
18423 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18424 && ! TARGET_ALTIVEC)
18425 return FIRST_ALTIVEC_REGNO + 20;
18427 /* Find lowest numbered live register. */
18428 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18429 if (df_regs_ever_live_p (i))
18435 /* Return a 32-bit mask of the AltiVec registers we need to set in
18436 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18437 the 32-bit word is 0. */
18439 static unsigned int
18440 compute_vrsave_mask (void)
18442 unsigned int i, mask = 0;
18444 /* On Darwin, the unwind routines are compiled without
18445 TARGET_ALTIVEC, and use save_world to save/restore the
18446 call-saved altivec registers when necessary. */
18447 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18448 && ! TARGET_ALTIVEC)
18451 /* First, find out if we use _any_ altivec registers. */
18452 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18453 if (df_regs_ever_live_p (i))
18454 mask |= ALTIVEC_REG_BIT (i);
18459 /* Next, remove the argument registers from the set. These must
18460 be in the VRSAVE mask set by the caller, so we don't need to add
18461 them in again. More importantly, the mask we compute here is
18462 used to generate CLOBBERs in the set_vrsave insn, and we do not
18463 wish the argument registers to die. */
18464 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18465 mask &= ~ALTIVEC_REG_BIT (i);
18467 /* Similarly, remove the return value from the set. */
18470 diddle_return_value (is_altivec_return_reg, &yes);
18472 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18478 /* For a very restricted set of circumstances, we can cut down the
18479 size of prologues/epilogues by calling our own save/restore-the-world
18483 compute_save_world_info (rs6000_stack_t *info_ptr)
18485 info_ptr->world_save_p = 1;
18486 info_ptr->world_save_p
18487 = (WORLD_SAVE_P (info_ptr)
18488 && DEFAULT_ABI == ABI_DARWIN
18489 && ! (cfun->calls_setjmp && flag_exceptions)
18490 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18491 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18492 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18493 && info_ptr->cr_save_p);
18495 /* This will not work in conjunction with sibcalls. Make sure there
18496 are none. (This check is expensive, but seldom executed.) */
18497 if (WORLD_SAVE_P (info_ptr))
18500 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18501 if ( GET_CODE (insn) == CALL_INSN
18502 && SIBLING_CALL_P (insn))
18504 info_ptr->world_save_p = 0;
18509 if (WORLD_SAVE_P (info_ptr))
18511 /* Even if we're not touching VRsave, make sure there's room on the
18512 stack for it, if it looks like we're calling SAVE_WORLD, which
18513 will attempt to save it. */
18514 info_ptr->vrsave_size = 4;
18516 /* If we are going to save the world, we need to save the link register too. */
18517 info_ptr->lr_save_p = 1;
18519 /* "Save" the VRsave register too if we're saving the world. */
18520 if (info_ptr->vrsave_mask == 0)
18521 info_ptr->vrsave_mask = compute_vrsave_mask ();
18523 /* Because the Darwin register save/restore routines only handle
18524 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18526 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18527 && (info_ptr->first_altivec_reg_save
18528 >= FIRST_SAVED_ALTIVEC_REGNO));
18535 is_altivec_return_reg (rtx reg, void *xyes)
18537 bool *yes = (bool *) xyes;
18538 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18543 /* Determine the strategy for savings/restoring registers. */
18546 SAVRES_MULTIPLE = 0x1,
18547 SAVE_INLINE_FPRS = 0x2,
18548 SAVE_INLINE_GPRS = 0x4,
18549 REST_INLINE_FPRS = 0x8,
18550 REST_INLINE_GPRS = 0x10,
18551 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18552 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18553 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18557 rs6000_savres_strategy (rs6000_stack_t *info,
18558 bool using_static_chain_p)
18562 if (TARGET_MULTIPLE
18563 && !TARGET_POWERPC64
18564 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18565 && info->first_gp_reg_save < 31
18566 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18567 strategy |= SAVRES_MULTIPLE;
18569 if (crtl->calls_eh_return
18570 || cfun->machine->ra_need_lr
18571 || info->total_size > 32767)
18572 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18573 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18575 if (info->first_fp_reg_save == 64
18576 || FP_SAVE_INLINE (info->first_fp_reg_save)
18577 /* The out-of-line FP routines use double-precision stores;
18578 we can't use those routines if we don't have such stores. */
18579 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18580 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18581 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18583 if (info->first_gp_reg_save == 32
18584 || GP_SAVE_INLINE (info->first_gp_reg_save)
18585 || !((strategy & SAVRES_MULTIPLE)
18586 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18587 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18589 /* Don't bother to try to save things out-of-line if r11 is occupied
18590 by the static chain. It would require too much fiddling and the
18591 static chain is rarely used anyway. */
18592 if (using_static_chain_p)
18593 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18595 /* If we are going to use store multiple, then don't even bother
18596 with the out-of-line routines, since the store-multiple
18597 instruction will always be smaller. */
18598 if ((strategy & SAVRES_MULTIPLE))
18599 strategy |= SAVE_INLINE_GPRS;
18601 /* The situation is more complicated with load multiple. We'd
18602 prefer to use the out-of-line routines for restores, since the
18603 "exit" out-of-line routines can handle the restore of LR and the
18604 frame teardown. However if doesn't make sense to use the
18605 out-of-line routine if that is the only reason we'd need to save
18606 LR, and we can't use the "exit" out-of-line gpr restore if we
18607 have saved some fprs; In those cases it is advantageous to use
18608 load multiple when available. */
18609 if ((strategy & SAVRES_MULTIPLE)
18610 && (!info->lr_save_p
18611 || info->first_fp_reg_save != 64))
18612 strategy |= REST_INLINE_GPRS;
18614 /* We can only use load multiple or the out-of-line routines to
18615 restore if we've used store multiple or out-of-line routines
18616 in the prologue, i.e. if we've saved all the registers from
18617 first_gp_reg_save. Otherwise, we risk loading garbage. */
18618 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18619 strategy |= REST_INLINE_GPRS;
18621 /* Saving CR interferes with the exit routines used on the SPE, so
18624 && info->spe_64bit_regs_used
18625 && info->cr_save_p)
18626 strategy |= REST_INLINE_GPRS;
18628 #ifdef POWERPC_LINUX
18631 if (!(strategy & SAVE_INLINE_FPRS))
18632 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18633 else if (!(strategy & SAVE_INLINE_GPRS)
18634 && info->first_fp_reg_save == 64)
18635 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18638 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18639 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18644 /* Calculate the stack information for the current function. This is
18645 complicated by having two separate calling sequences, the AIX calling
18646 sequence and the V.4 calling sequence.
18648 AIX (and Darwin/Mac OS X) stack frames look like:
18650 SP----> +---------------------------------------+
18651 | back chain to caller | 0 0
18652 +---------------------------------------+
18653 | saved CR | 4 8 (8-11)
18654 +---------------------------------------+
18656 +---------------------------------------+
18657 | reserved for compilers | 12 24
18658 +---------------------------------------+
18659 | reserved for binders | 16 32
18660 +---------------------------------------+
18661 | saved TOC pointer | 20 40
18662 +---------------------------------------+
18663 | Parameter save area (P) | 24 48
18664 +---------------------------------------+
18665 | Alloca space (A) | 24+P etc.
18666 +---------------------------------------+
18667 | Local variable space (L) | 24+P+A
18668 +---------------------------------------+
18669 | Float/int conversion temporary (X) | 24+P+A+L
18670 +---------------------------------------+
18671 | Save area for AltiVec registers (W) | 24+P+A+L+X
18672 +---------------------------------------+
18673 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18674 +---------------------------------------+
18675 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18676 +---------------------------------------+
18677 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18678 +---------------------------------------+
18679 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18680 +---------------------------------------+
18681 old SP->| back chain to caller's caller |
18682 +---------------------------------------+
18684 The required alignment for AIX configurations is two words (i.e., 8
18688 V.4 stack frames look like:
18690 SP----> +---------------------------------------+
18691 | back chain to caller | 0
18692 +---------------------------------------+
18693 | caller's saved LR | 4
18694 +---------------------------------------+
18695 | Parameter save area (P) | 8
18696 +---------------------------------------+
18697 | Alloca space (A) | 8+P
18698 +---------------------------------------+
18699 | Varargs save area (V) | 8+P+A
18700 +---------------------------------------+
18701 | Local variable space (L) | 8+P+A+V
18702 +---------------------------------------+
18703 | Float/int conversion temporary (X) | 8+P+A+V+L
18704 +---------------------------------------+
18705 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18706 +---------------------------------------+
18707 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18708 +---------------------------------------+
18709 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18710 +---------------------------------------+
18711 | SPE: area for 64-bit GP registers |
18712 +---------------------------------------+
18713 | SPE alignment padding |
18714 +---------------------------------------+
18715 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18716 +---------------------------------------+
18717 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18718 +---------------------------------------+
18719 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18720 +---------------------------------------+
18721 old SP->| back chain to caller's caller |
18722 +---------------------------------------+
18724 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18725 given. (But note below and in sysv4.h that we require only 8 and
18726 may round up the size of our stack frame anyways. The historical
18727 reason is early versions of powerpc-linux which didn't properly
18728 align the stack at program startup. A happy side-effect is that
18729 -mno-eabi libraries can be used with -meabi programs.)
18731 The EABI configuration defaults to the V.4 layout. However,
18732 the stack alignment requirements may differ. If -mno-eabi is not
18733 given, the required stack alignment is 8 bytes; if -mno-eabi is
18734 given, the required alignment is 16 bytes. (But see V.4 comment
18737 #ifndef ABI_STACK_BOUNDARY
18738 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18741 static rs6000_stack_t *
18742 rs6000_stack_info (void)
18744 #ifdef ENABLE_CHECKING
18745 static rs6000_stack_t info_save;
18747 rs6000_stack_t *info_ptr = &stack_info;
18748 int reg_size = TARGET_32BIT ? 4 : 8;
18752 HOST_WIDE_INT non_fixed_size;
18753 bool using_static_chain_p;
18755 #ifdef ENABLE_CHECKING
18756 memcpy (&info_save, &stack_info, sizeof stack_info);
18758 if (reload_completed && info_ptr->reload_completed)
18762 memset (&stack_info, 0, sizeof (stack_info));
18763 info_ptr->reload_completed = reload_completed;
18767 /* Cache value so we don't rescan instruction chain over and over. */
18768 if (cfun->machine->insn_chain_scanned_p == 0)
18769 cfun->machine->insn_chain_scanned_p
18770 = spe_func_has_64bit_regs_p () + 1;
18771 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18774 /* Select which calling sequence. */
18775 info_ptr->abi = DEFAULT_ABI;
18777 /* Calculate which registers need to be saved & save area size. */
18778 info_ptr->first_gp_reg_save = first_reg_to_save ();
18779 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18780 even if it currently looks like we won't. Reload may need it to
18781 get at a constant; if so, it will have already created a constant
18782 pool entry for it. */
18783 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18784 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18785 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18786 && crtl->uses_const_pool
18787 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18788 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18790 first_gp = info_ptr->first_gp_reg_save;
18792 info_ptr->gp_size = reg_size * (32 - first_gp);
18794 /* For the SPE, we have an additional upper 32-bits on each GPR.
18795 Ideally we should save the entire 64-bits only when the upper
18796 half is used in SIMD instructions. Since we only record
18797 registers live (not the size they are used in), this proves
18798 difficult because we'd have to traverse the instruction chain at
18799 the right time, taking reload into account. This is a real pain,
18800 so we opt to save the GPRs in 64-bits always if but one register
18801 gets used in 64-bits. Otherwise, all the registers in the frame
18802 get saved in 32-bits.
18804 So... since when we save all GPRs (except the SP) in 64-bits, the
18805 traditional GP save area will be empty. */
18806 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18807 info_ptr->gp_size = 0;
18809 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18810 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18812 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18813 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18814 - info_ptr->first_altivec_reg_save);
18816 /* Does this function call anything? */
18817 info_ptr->calls_p = (! current_function_is_leaf
18818 || cfun->machine->ra_needs_full_frame);
18820 /* Determine if we need to save the condition code registers. */
18821 if (df_regs_ever_live_p (CR2_REGNO)
18822 || df_regs_ever_live_p (CR3_REGNO)
18823 || df_regs_ever_live_p (CR4_REGNO))
18825 info_ptr->cr_save_p = 1;
18826 if (DEFAULT_ABI == ABI_V4)
18827 info_ptr->cr_size = reg_size;
18830 /* If the current function calls __builtin_eh_return, then we need
18831 to allocate stack space for registers that will hold data for
18832 the exception handler. */
18833 if (crtl->calls_eh_return)
18836 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18839 /* SPE saves EH registers in 64-bits. */
18840 ehrd_size = i * (TARGET_SPE_ABI
18841 && info_ptr->spe_64bit_regs_used != 0
18842 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18847 /* Determine various sizes. */
18848 info_ptr->reg_size = reg_size;
18849 info_ptr->fixed_size = RS6000_SAVE_AREA;
18850 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18851 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18852 TARGET_ALTIVEC ? 16 : 8);
18853 if (FRAME_GROWS_DOWNWARD)
18854 info_ptr->vars_size
18855 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18856 + info_ptr->parm_size,
18857 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18858 - (info_ptr->fixed_size + info_ptr->vars_size
18859 + info_ptr->parm_size);
18861 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18862 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18864 info_ptr->spe_gp_size = 0;
18866 if (TARGET_ALTIVEC_ABI)
18867 info_ptr->vrsave_mask = compute_vrsave_mask ();
18869 info_ptr->vrsave_mask = 0;
18871 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18872 info_ptr->vrsave_size = 4;
18874 info_ptr->vrsave_size = 0;
18876 compute_save_world_info (info_ptr);
18878 /* Calculate the offsets. */
18879 switch (DEFAULT_ABI)
18883 gcc_unreachable ();
18887 info_ptr->fp_save_offset = - info_ptr->fp_size;
18888 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18890 if (TARGET_ALTIVEC_ABI)
18892 info_ptr->vrsave_save_offset
18893 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18895 /* Align stack so vector save area is on a quadword boundary.
18896 The padding goes above the vectors. */
18897 if (info_ptr->altivec_size != 0)
18898 info_ptr->altivec_padding_size
18899 = info_ptr->vrsave_save_offset & 0xF;
18901 info_ptr->altivec_padding_size = 0;
18903 info_ptr->altivec_save_offset
18904 = info_ptr->vrsave_save_offset
18905 - info_ptr->altivec_padding_size
18906 - info_ptr->altivec_size;
18907 gcc_assert (info_ptr->altivec_size == 0
18908 || info_ptr->altivec_save_offset % 16 == 0);
18910 /* Adjust for AltiVec case. */
18911 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18914 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18915 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18916 info_ptr->lr_save_offset = 2*reg_size;
18920 info_ptr->fp_save_offset = - info_ptr->fp_size;
18921 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18922 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18924 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18926 /* Align stack so SPE GPR save area is aligned on a
18927 double-word boundary. */
18928 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18929 info_ptr->spe_padding_size
18930 = 8 - (-info_ptr->cr_save_offset % 8);
18932 info_ptr->spe_padding_size = 0;
18934 info_ptr->spe_gp_save_offset
18935 = info_ptr->cr_save_offset
18936 - info_ptr->spe_padding_size
18937 - info_ptr->spe_gp_size;
18939 /* Adjust for SPE case. */
18940 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18942 else if (TARGET_ALTIVEC_ABI)
18944 info_ptr->vrsave_save_offset
18945 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18947 /* Align stack so vector save area is on a quadword boundary. */
18948 if (info_ptr->altivec_size != 0)
18949 info_ptr->altivec_padding_size
18950 = 16 - (-info_ptr->vrsave_save_offset % 16);
18952 info_ptr->altivec_padding_size = 0;
18954 info_ptr->altivec_save_offset
18955 = info_ptr->vrsave_save_offset
18956 - info_ptr->altivec_padding_size
18957 - info_ptr->altivec_size;
18959 /* Adjust for AltiVec case. */
18960 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18963 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18964 info_ptr->ehrd_offset -= ehrd_size;
18965 info_ptr->lr_save_offset = reg_size;
18969 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18970 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18971 + info_ptr->gp_size
18972 + info_ptr->altivec_size
18973 + info_ptr->altivec_padding_size
18974 + info_ptr->spe_gp_size
18975 + info_ptr->spe_padding_size
18977 + info_ptr->cr_size
18978 + info_ptr->vrsave_size,
18981 non_fixed_size = (info_ptr->vars_size
18982 + info_ptr->parm_size
18983 + info_ptr->save_size);
18985 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18986 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18988 /* Determine if we need to save the link register. */
18989 if (info_ptr->calls_p
18990 || (DEFAULT_ABI == ABI_AIX
18992 && !TARGET_PROFILE_KERNEL)
18993 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18994 #ifdef TARGET_RELOCATABLE
18995 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18997 || rs6000_ra_ever_killed ())
18998 info_ptr->lr_save_p = 1;
19000 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19001 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19002 && call_used_regs[STATIC_CHAIN_REGNUM]);
19003 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
19004 using_static_chain_p);
19006 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
19007 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
19008 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
19009 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
19010 info_ptr->lr_save_p = 1;
19012 if (info_ptr->lr_save_p)
19013 df_set_regs_ever_live (LR_REGNO, true);
19015 /* Determine if we need to allocate any stack frame:
19017 For AIX we need to push the stack if a frame pointer is needed
19018 (because the stack might be dynamically adjusted), if we are
19019 debugging, if we make calls, or if the sum of fp_save, gp_save,
19020 and local variables are more than the space needed to save all
19021 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19022 + 18*8 = 288 (GPR13 reserved).
19024 For V.4 we don't have the stack cushion that AIX uses, but assume
19025 that the debugger can handle stackless frames. */
19027 if (info_ptr->calls_p)
19028 info_ptr->push_p = 1;
19030 else if (DEFAULT_ABI == ABI_V4)
19031 info_ptr->push_p = non_fixed_size != 0;
19033 else if (frame_pointer_needed)
19034 info_ptr->push_p = 1;
19036 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
19037 info_ptr->push_p = 1;
19040 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
19042 /* Zero offsets if we're not saving those registers. */
19043 if (info_ptr->fp_size == 0)
19044 info_ptr->fp_save_offset = 0;
19046 if (info_ptr->gp_size == 0)
19047 info_ptr->gp_save_offset = 0;
19049 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
19050 info_ptr->altivec_save_offset = 0;
19052 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
19053 info_ptr->vrsave_save_offset = 0;
19055 if (! TARGET_SPE_ABI
19056 || info_ptr->spe_64bit_regs_used == 0
19057 || info_ptr->spe_gp_size == 0)
19058 info_ptr->spe_gp_save_offset = 0;
19060 if (! info_ptr->lr_save_p)
19061 info_ptr->lr_save_offset = 0;
19063 if (! info_ptr->cr_save_p)
19064 info_ptr->cr_save_offset = 0;
19066 #ifdef ENABLE_CHECKING
19067 gcc_assert (!(reload_completed && info_save.reload_completed)
19068 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
19073 /* Return true if the current function uses any GPRs in 64-bit SIMD
19077 spe_func_has_64bit_regs_p (void)
19081 /* Functions that save and restore all the call-saved registers will
19082 need to save/restore the registers in 64-bits. */
19083 if (crtl->calls_eh_return
19084 || cfun->calls_setjmp
19085 || crtl->has_nonlocal_goto)
19088 insns = get_insns ();
19090 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19096 /* FIXME: This should be implemented with attributes...
19098 (set_attr "spe64" "true")....then,
19099 if (get_spe64(insn)) return true;
19101 It's the only reliable way to do the stuff below. */
19103 i = PATTERN (insn);
19104 if (GET_CODE (i) == SET)
19106 enum machine_mode mode = GET_MODE (SET_SRC (i));
19108 if (SPE_VECTOR_MODE (mode))
19110 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19120 debug_stack_info (rs6000_stack_t *info)
19122 const char *abi_string;
19125 info = rs6000_stack_info ();
19127 fprintf (stderr, "\nStack information for function %s:\n",
19128 ((current_function_decl && DECL_NAME (current_function_decl))
19129 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19134 default: abi_string = "Unknown"; break;
19135 case ABI_NONE: abi_string = "NONE"; break;
19136 case ABI_AIX: abi_string = "AIX"; break;
19137 case ABI_DARWIN: abi_string = "Darwin"; break;
19138 case ABI_V4: abi_string = "V.4"; break;
19141 fprintf (stderr, "\tABI = %5s\n", abi_string);
19143 if (TARGET_ALTIVEC_ABI)
19144 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19146 if (TARGET_SPE_ABI)
19147 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19149 if (info->first_gp_reg_save != 32)
19150 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19152 if (info->first_fp_reg_save != 64)
19153 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19155 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19156 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19157 info->first_altivec_reg_save);
19159 if (info->lr_save_p)
19160 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19162 if (info->cr_save_p)
19163 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19165 if (info->vrsave_mask)
19166 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19169 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19172 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19174 if (info->gp_save_offset)
19175 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19177 if (info->fp_save_offset)
19178 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19180 if (info->altivec_save_offset)
19181 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19182 info->altivec_save_offset);
19184 if (info->spe_gp_save_offset)
19185 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19186 info->spe_gp_save_offset);
19188 if (info->vrsave_save_offset)
19189 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19190 info->vrsave_save_offset);
19192 if (info->lr_save_offset)
19193 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19195 if (info->cr_save_offset)
19196 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19198 if (info->varargs_save_offset)
19199 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19201 if (info->total_size)
19202 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19205 if (info->vars_size)
19206 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19209 if (info->parm_size)
19210 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19212 if (info->fixed_size)
19213 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19216 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19218 if (info->spe_gp_size)
19219 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19222 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19224 if (info->altivec_size)
19225 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19227 if (info->vrsave_size)
19228 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19230 if (info->altivec_padding_size)
19231 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19232 info->altivec_padding_size);
19234 if (info->spe_padding_size)
19235 fprintf (stderr, "\tspe_padding_size = %5d\n",
19236 info->spe_padding_size);
19239 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19241 if (info->save_size)
19242 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19244 if (info->reg_size != 4)
19245 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19247 fprintf (stderr, "\n");
19251 rs6000_return_addr (int count, rtx frame)
19253 /* Currently we don't optimize very well between prolog and body
19254 code and for PIC code the code can be actually quite bad, so
19255 don't try to be too clever here. */
19256 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19258 cfun->machine->ra_needs_full_frame = 1;
19265 plus_constant (copy_to_reg
19266 (gen_rtx_MEM (Pmode,
19267 memory_address (Pmode, frame))),
19268 RETURN_ADDRESS_OFFSET)));
19271 cfun->machine->ra_need_lr = 1;
19272 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19275 /* Say whether a function is a candidate for sibcall handling or not.
19276 We do not allow indirect calls to be optimized into sibling calls.
19277 Also, we can't do it if there are any vector parameters; there's
19278 nowhere to put the VRsave code so it works; note that functions with
19279 vector parameters are required to have a prototype, so the argument
19280 type info must be available here. (The tail recursion case can work
19281 with vector parameters, but there's no way to distinguish here.) */
19283 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19288 if (TARGET_ALTIVEC_VRSAVE)
19290 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19291 type; type = TREE_CHAIN (type))
19293 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19297 if (DEFAULT_ABI == ABI_DARWIN
19298 || ((*targetm.binds_local_p) (decl)
19299 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19301 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19303 if (!lookup_attribute ("longcall", attr_list)
19304 || lookup_attribute ("shortcall", attr_list))
19311 /* NULL if INSN insn is valid within a low-overhead loop.
19312 Otherwise return why doloop cannot be applied.
19313 PowerPC uses the COUNT register for branch on table instructions. */
19315 static const char *
19316 rs6000_invalid_within_doloop (const_rtx insn)
19319 return "Function call in the loop.";
19322 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19323 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19324 return "Computed branch in the loop.";
19330 rs6000_ra_ever_killed (void)
19336 if (cfun->is_thunk)
19339 if (cfun->machine->lr_save_state)
19340 return cfun->machine->lr_save_state - 1;
19342 /* regs_ever_live has LR marked as used if any sibcalls are present,
19343 but this should not force saving and restoring in the
19344 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19345 clobbers LR, so that is inappropriate. */
19347 /* Also, the prologue can generate a store into LR that
19348 doesn't really count, like this:
19351 bcl to set PIC register
19355 When we're called from the epilogue, we need to avoid counting
19356 this as a store. */
19358 push_topmost_sequence ();
19359 top = get_insns ();
19360 pop_topmost_sequence ();
19361 reg = gen_rtx_REG (Pmode, LR_REGNO);
19363 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19369 if (!SIBLING_CALL_P (insn))
19372 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19374 else if (set_of (reg, insn) != NULL_RTX
19375 && !prologue_epilogue_contains (insn))
19382 /* Emit instructions needed to load the TOC register.
19383 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19384 a constant pool; or for SVR4 -fpic. */
19387 rs6000_emit_load_toc_table (int fromprolog)
19390 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19392 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19395 rtx lab, tmp1, tmp2, got;
19397 lab = gen_label_rtx ();
19398 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19399 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19401 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19403 got = rs6000_got_sym ();
19404 tmp1 = tmp2 = dest;
19407 tmp1 = gen_reg_rtx (Pmode);
19408 tmp2 = gen_reg_rtx (Pmode);
19410 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19411 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19412 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19413 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19415 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19417 emit_insn (gen_load_toc_v4_pic_si ());
19418 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19420 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19423 rtx temp0 = (fromprolog
19424 ? gen_rtx_REG (Pmode, 0)
19425 : gen_reg_rtx (Pmode));
19431 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19432 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19434 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19435 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19437 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19438 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19439 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19445 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19446 lab = gen_label_rtx ();
19447 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19448 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19449 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19451 emit_insn (gen_addsi3 (dest, temp0, dest));
19453 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19455 /* This is for AIX code running in non-PIC ELF32. */
19458 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19459 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19461 emit_insn (gen_elf_high (dest, realsym));
19462 emit_insn (gen_elf_low (dest, dest, realsym));
19466 gcc_assert (DEFAULT_ABI == ABI_AIX);
19469 emit_insn (gen_load_toc_aix_si (dest));
19471 emit_insn (gen_load_toc_aix_di (dest));
19475 /* Emit instructions to restore the link register after determining where
19476 its value has been stored. */
19479 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19481 rs6000_stack_t *info = rs6000_stack_info ();
19484 operands[0] = source;
19485 operands[1] = scratch;
19487 if (info->lr_save_p)
19489 rtx frame_rtx = stack_pointer_rtx;
19490 HOST_WIDE_INT sp_offset = 0;
19493 if (frame_pointer_needed
19494 || cfun->calls_alloca
19495 || info->total_size > 32767)
19497 tmp = gen_frame_mem (Pmode, frame_rtx);
19498 emit_move_insn (operands[1], tmp);
19499 frame_rtx = operands[1];
19501 else if (info->push_p)
19502 sp_offset = info->total_size;
19504 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19505 tmp = gen_frame_mem (Pmode, tmp);
19506 emit_move_insn (tmp, operands[0]);
19509 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19511 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19512 state of lr_save_p so any change from here on would be a bug. In
19513 particular, stop rs6000_ra_ever_killed from considering the SET
19514 of lr we may have added just above. */
19515 cfun->machine->lr_save_state = info->lr_save_p + 1;
19518 static GTY(()) alias_set_type set = -1;
19521 get_TOC_alias_set (void)
19524 set = new_alias_set ();
19528 /* This returns nonzero if the current function uses the TOC. This is
19529 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19530 is generated by the ABI_V4 load_toc_* patterns. */
19537 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19540 rtx pat = PATTERN (insn);
19543 if (GET_CODE (pat) == PARALLEL)
19544 for (i = 0; i < XVECLEN (pat, 0); i++)
19546 rtx sub = XVECEXP (pat, 0, i);
19547 if (GET_CODE (sub) == USE)
19549 sub = XEXP (sub, 0);
19550 if (GET_CODE (sub) == UNSPEC
19551 && XINT (sub, 1) == UNSPEC_TOC)
19561 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19563 rtx tocrel, tocreg;
19565 if (TARGET_DEBUG_ADDR)
19567 if (GET_CODE (symbol) == SYMBOL_REF)
19568 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19572 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19573 GET_RTX_NAME (GET_CODE (symbol)));
19574 debug_rtx (symbol);
19578 if (!can_create_pseudo_p ())
19579 df_set_regs_ever_live (TOC_REGISTER, true);
19581 tocrel = gen_rtx_CONST (Pmode,
19582 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19584 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19585 if (TARGET_CMODEL != CMODEL_SMALL)
19587 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19588 if (largetoc_reg != NULL)
19590 emit_move_insn (largetoc_reg, hi);
19593 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19596 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19599 /* Issue assembly directives that create a reference to the given DWARF
19600 FRAME_TABLE_LABEL from the current function section. */
19602 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19604 fprintf (asm_out_file, "\t.ref %s\n",
19605 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19608 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19609 and the change to the stack pointer. */
19612 rs6000_emit_stack_tie (void)
19614 rtx mem = gen_frame_mem (BLKmode,
19615 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19617 emit_insn (gen_stack_tie (mem));
19620 /* Emit the correct code for allocating stack space, as insns.
19621 If COPY_REG, make sure a copy of the old frame is left there.
19622 The generated code may use hard register 0 as a temporary. */
19625 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19628 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19629 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19630 rtx todec = gen_int_mode (-size, Pmode);
19633 if (INTVAL (todec) != -size)
19635 warning (0, "stack frame too large");
19636 emit_insn (gen_trap ());
19640 if (crtl->limit_stack)
19642 if (REG_P (stack_limit_rtx)
19643 && REGNO (stack_limit_rtx) > 1
19644 && REGNO (stack_limit_rtx) <= 31)
19646 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19647 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19650 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19652 && DEFAULT_ABI == ABI_V4)
19654 rtx toload = gen_rtx_CONST (VOIDmode,
19655 gen_rtx_PLUS (Pmode,
19659 emit_insn (gen_elf_high (tmp_reg, toload));
19660 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19661 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19665 warning (0, "stack limit expression is not supported");
19669 emit_move_insn (copy_reg, stack_reg);
19673 /* Need a note here so that try_split doesn't get confused. */
19674 if (get_last_insn () == NULL_RTX)
19675 emit_note (NOTE_INSN_DELETED);
19676 insn = emit_move_insn (tmp_reg, todec);
19677 try_split (PATTERN (insn), insn, 0);
19681 insn = emit_insn (TARGET_32BIT
19682 ? gen_movsi_update_stack (stack_reg, stack_reg,
19684 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19685 todec, stack_reg));
19686 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19687 it now and set the alias set/attributes. The above gen_*_update
19688 calls will generate a PARALLEL with the MEM set being the first
19690 par = PATTERN (insn);
19691 gcc_assert (GET_CODE (par) == PARALLEL);
19692 set = XVECEXP (par, 0, 0);
19693 gcc_assert (GET_CODE (set) == SET);
19694 mem = SET_DEST (set);
19695 gcc_assert (MEM_P (mem));
19696 MEM_NOTRAP_P (mem) = 1;
19697 set_mem_alias_set (mem, get_frame_alias_set ());
19699 RTX_FRAME_RELATED_P (insn) = 1;
19700 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19701 gen_rtx_SET (VOIDmode, stack_reg,
19702 gen_rtx_PLUS (Pmode, stack_reg,
19703 GEN_INT (-size))));
19706 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19708 #if PROBE_INTERVAL > 32768
19709 #error Cannot use indexed addressing mode for stack probing
19712 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19713 inclusive. These are offsets from the current stack pointer. */
19716 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19718 /* See if we have a constant small number of probes to generate. If so,
19719 that's the easy case. */
19720 if (first + size <= 32768)
19724 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19725 it exceeds SIZE. If only one probe is needed, this will not
19726 generate any code. Then probe at FIRST + SIZE. */
19727 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19728 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19730 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19733 /* Otherwise, do the same as above, but in a loop. Note that we must be
19734 extra careful with variables wrapping around because we might be at
19735 the very top (or the very bottom) of the address space and we have
19736 to be able to handle this case properly; in particular, we use an
19737 equality test for the loop condition. */
19740 HOST_WIDE_INT rounded_size;
19741 rtx r12 = gen_rtx_REG (Pmode, 12);
19742 rtx r0 = gen_rtx_REG (Pmode, 0);
19744 /* Sanity check for the addressing mode we're going to use. */
19745 gcc_assert (first <= 32768);
19747 /* Step 1: round SIZE to the previous multiple of the interval. */
19749 rounded_size = size & -PROBE_INTERVAL;
19752 /* Step 2: compute initial and final value of the loop counter. */
19754 /* TEST_ADDR = SP + FIRST. */
19755 emit_insn (gen_rtx_SET (VOIDmode, r12,
19756 plus_constant (stack_pointer_rtx, -first)));
19758 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19759 if (rounded_size > 32768)
19761 emit_move_insn (r0, GEN_INT (-rounded_size));
19762 emit_insn (gen_rtx_SET (VOIDmode, r0,
19763 gen_rtx_PLUS (Pmode, r12, r0)));
19766 emit_insn (gen_rtx_SET (VOIDmode, r0,
19767 plus_constant (r12, -rounded_size)));
19770 /* Step 3: the loop
19772 while (TEST_ADDR != LAST_ADDR)
19774 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19778 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19779 until it is equal to ROUNDED_SIZE. */
19782 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19784 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19787 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19788 that SIZE is equal to ROUNDED_SIZE. */
19790 if (size != rounded_size)
19791 emit_stack_probe (plus_constant (r12, rounded_size - size));
19795 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19796 absolute addresses. */
19799 output_probe_stack_range (rtx reg1, rtx reg2)
19801 static int labelno = 0;
19802 char loop_lab[32], end_lab[32];
19805 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19806 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19808 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19810 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19814 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19816 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19818 fputs ("\tbeq 0,", asm_out_file);
19819 assemble_name_raw (asm_out_file, end_lab);
19820 fputc ('\n', asm_out_file);
19822 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19823 xops[1] = GEN_INT (-PROBE_INTERVAL);
19824 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19826 /* Probe at TEST_ADDR and branch. */
19827 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19828 fprintf (asm_out_file, "\tb ");
19829 assemble_name_raw (asm_out_file, loop_lab);
19830 fputc ('\n', asm_out_file);
19832 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19837 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19838 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19839 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19840 deduce these equivalences by itself so it wasn't necessary to hold
19841 its hand so much. */
19844 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19845 rtx reg2, rtx rreg)
19849 /* copy_rtx will not make unique copies of registers, so we need to
19850 ensure we don't have unwanted sharing here. */
19852 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19855 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19857 real = copy_rtx (PATTERN (insn));
19859 if (reg2 != NULL_RTX)
19860 real = replace_rtx (real, reg2, rreg);
19862 real = replace_rtx (real, reg,
19863 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19864 STACK_POINTER_REGNUM),
19867 /* We expect that 'real' is either a SET or a PARALLEL containing
19868 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19869 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19871 if (GET_CODE (real) == SET)
19875 temp = simplify_rtx (SET_SRC (set));
19877 SET_SRC (set) = temp;
19878 temp = simplify_rtx (SET_DEST (set));
19880 SET_DEST (set) = temp;
19881 if (GET_CODE (SET_DEST (set)) == MEM)
19883 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19885 XEXP (SET_DEST (set), 0) = temp;
19892 gcc_assert (GET_CODE (real) == PARALLEL);
19893 for (i = 0; i < XVECLEN (real, 0); i++)
19894 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19896 rtx set = XVECEXP (real, 0, i);
19898 temp = simplify_rtx (SET_SRC (set));
19900 SET_SRC (set) = temp;
19901 temp = simplify_rtx (SET_DEST (set));
19903 SET_DEST (set) = temp;
19904 if (GET_CODE (SET_DEST (set)) == MEM)
19906 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19908 XEXP (SET_DEST (set), 0) = temp;
19910 RTX_FRAME_RELATED_P (set) = 1;
19914 RTX_FRAME_RELATED_P (insn) = 1;
19915 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19918 /* Returns an insn that has a vrsave set operation with the
19919 appropriate CLOBBERs. */
19922 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19925 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19926 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19929 = gen_rtx_SET (VOIDmode,
19931 gen_rtx_UNSPEC_VOLATILE (SImode,
19932 gen_rtvec (2, reg, vrsave),
19933 UNSPECV_SET_VRSAVE));
19937 /* We need to clobber the registers in the mask so the scheduler
19938 does not move sets to VRSAVE before sets of AltiVec registers.
19940 However, if the function receives nonlocal gotos, reload will set
19941 all call saved registers live. We will end up with:
19943 (set (reg 999) (mem))
19944 (parallel [ (set (reg vrsave) (unspec blah))
19945 (clobber (reg 999))])
19947 The clobber will cause the store into reg 999 to be dead, and
19948 flow will attempt to delete an epilogue insn. In this case, we
19949 need an unspec use/set of the register. */
19951 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19952 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19954 if (!epiloguep || call_used_regs [i])
19955 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19956 gen_rtx_REG (V4SImode, i));
19959 rtx reg = gen_rtx_REG (V4SImode, i);
19962 = gen_rtx_SET (VOIDmode,
19964 gen_rtx_UNSPEC (V4SImode,
19965 gen_rtvec (1, reg), 27));
19969 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19971 for (i = 0; i < nclobs; ++i)
19972 XVECEXP (insn, 0, i) = clobs[i];
19977 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19978 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19981 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19982 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19984 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19985 rtx replacea, replaceb;
19987 int_rtx = GEN_INT (offset);
19989 /* Some cases that need register indexed addressing. */
19990 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19991 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19992 || (TARGET_E500_DOUBLE && mode == DFmode)
19994 && SPE_VECTOR_MODE (mode)
19995 && !SPE_CONST_OFFSET_OK (offset)))
19997 /* Whomever calls us must make sure r11 is available in the
19998 flow path of instructions in the prologue. */
19999 offset_rtx = gen_rtx_REG (Pmode, 11);
20000 emit_move_insn (offset_rtx, int_rtx);
20002 replacea = offset_rtx;
20003 replaceb = int_rtx;
20007 offset_rtx = int_rtx;
20008 replacea = NULL_RTX;
20009 replaceb = NULL_RTX;
20012 reg = gen_rtx_REG (mode, regno);
20013 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
20014 mem = gen_frame_mem (mode, addr);
20016 insn = emit_move_insn (mem, reg);
20018 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
20021 /* Emit an offset memory reference suitable for a frame store, while
20022 converting to a valid addressing mode. */
20025 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
20027 rtx int_rtx, offset_rtx;
20029 int_rtx = GEN_INT (offset);
20031 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
20032 || (TARGET_E500_DOUBLE && mode == DFmode))
20034 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
20035 emit_move_insn (offset_rtx, int_rtx);
20038 offset_rtx = int_rtx;
20040 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
20043 /* Look for user-defined global regs. We should not save and restore these,
20044 and cannot use stmw/lmw if there are any in its range. */
20047 no_global_regs_above (int first, bool gpr)
20050 int last = gpr ? 32 : 64;
20051 for (i = first; i < last; i++)
20052 if (global_regs[i])
20057 #ifndef TARGET_FIX_AND_CONTINUE
20058 #define TARGET_FIX_AND_CONTINUE 0
20061 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20062 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20063 #define LAST_SAVRES_REGISTER 31
20064 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20066 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
20068 /* Temporary holding space for an out-of-line register save/restore
20070 static char savres_routine_name[30];
20072 /* Return the name for an out-of-line register save/restore routine.
20073 We are saving/restoring GPRs if GPR is true. */
20076 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20077 bool savep, bool gpr, bool lr)
20079 const char *prefix = "";
20080 const char *suffix = "";
20082 /* Different targets are supposed to define
20083 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20084 routine name could be defined with:
20086 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20088 This is a nice idea in practice, but in reality, things are
20089 complicated in several ways:
20091 - ELF targets have save/restore routines for GPRs.
20093 - SPE targets use different prefixes for 32/64-bit registers, and
20094 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20096 - PPC64 ELF targets have routines for save/restore of GPRs that
20097 differ in what they do with the link register, so having a set
20098 prefix doesn't work. (We only use one of the save routines at
20099 the moment, though.)
20101 - PPC32 elf targets have "exit" versions of the restore routines
20102 that restore the link register and can save some extra space.
20103 These require an extra suffix. (There are also "tail" versions
20104 of the restore routines and "GOT" versions of the save routines,
20105 but we don't generate those at present. Same problems apply,
20108 We deal with all this by synthesizing our own prefix/suffix and
20109 using that for the simple sprintf call shown above. */
20112 /* No floating point saves on the SPE. */
20116 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20118 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20123 else if (DEFAULT_ABI == ABI_V4)
20129 prefix = savep ? "_savegpr_" : "_restgpr_";
20131 prefix = savep ? "_savefpr_" : "_restfpr_";
20136 else if (DEFAULT_ABI == ABI_AIX)
20138 #ifndef POWERPC_LINUX
20139 /* No out-of-line save/restore routines for GPRs on AIX. */
20140 gcc_assert (!TARGET_AIX || !gpr);
20146 ? (lr ? "_savegpr0_" : "_savegpr1_")
20147 : (lr ? "_restgpr0_" : "_restgpr1_"));
20148 #ifdef POWERPC_LINUX
20150 prefix = (savep ? "_savefpr_" : "_restfpr_");
20154 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20155 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20158 else if (DEFAULT_ABI == ABI_DARWIN)
20159 sorry ("out-of-line save/restore routines not supported on Darwin");
20161 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20163 return savres_routine_name;
20166 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20167 We are saving/restoring GPRs if GPR is true. */
20170 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20173 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20175 int select = ((savep ? 1 : 0) << 2
20177 /* On the SPE, we never have any FPRs, but we do have
20178 32/64-bit versions of the routines. */
20179 ? (info->spe_64bit_regs_used ? 1 : 0)
20180 : (gpr ? 1 : 0)) << 1)
20183 /* Don't generate bogus routine names. */
20184 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20185 && regno <= LAST_SAVRES_REGISTER);
20187 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20193 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20195 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20196 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20197 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20203 /* Emit a sequence of insns, including a stack tie if needed, for
20204 resetting the stack pointer. If SAVRES is true, then don't reset the
20205 stack pointer, but move the base of the frame into r11 for use by
20206 out-of-line register restore routines. */
20209 rs6000_emit_stack_reset (rs6000_stack_t *info,
20210 rtx sp_reg_rtx, rtx frame_reg_rtx,
20211 int sp_offset, bool savres)
20213 /* This blockage is needed so that sched doesn't decide to move
20214 the sp change before the register restores. */
20215 if (frame_reg_rtx != sp_reg_rtx
20217 && info->spe_64bit_regs_used != 0
20218 && info->first_gp_reg_save != 32))
20219 rs6000_emit_stack_tie ();
20221 if (frame_reg_rtx != sp_reg_rtx)
20223 if (sp_offset != 0)
20225 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20226 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20227 GEN_INT (sp_offset)));
20230 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20232 else if (sp_offset != 0)
20234 /* If we are restoring registers out-of-line, we will be using the
20235 "exit" variants of the restore routines, which will reset the
20236 stack for us. But we do need to point r11 into the right place
20237 for those routines. */
20238 rtx dest_reg = (savres
20239 ? gen_rtx_REG (Pmode, 11)
20242 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20243 GEN_INT (sp_offset)));
20250 /* Construct a parallel rtx describing the effect of a call to an
20251 out-of-line register save/restore routine. */
20254 rs6000_make_savres_rtx (rs6000_stack_t *info,
20255 rtx frame_reg_rtx, int save_area_offset,
20256 enum machine_mode reg_mode,
20257 bool savep, bool gpr, bool lr)
20260 int offset, start_reg, end_reg, n_regs;
20261 int reg_size = GET_MODE_SIZE (reg_mode);
20267 ? info->first_gp_reg_save
20268 : info->first_fp_reg_save);
20269 end_reg = gpr ? 32 : 64;
20270 n_regs = end_reg - start_reg;
20271 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20274 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20276 RTVEC_ELT (p, offset++)
20277 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20279 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20280 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20281 RTVEC_ELT (p, offset++)
20282 = gen_rtx_USE (VOIDmode,
20283 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20287 for (i = 0; i < end_reg - start_reg; i++)
20289 rtx addr, reg, mem;
20290 reg = gen_rtx_REG (reg_mode, start_reg + i);
20291 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20292 GEN_INT (save_area_offset + reg_size*i));
20293 mem = gen_frame_mem (reg_mode, addr);
20295 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20297 savep ? reg : mem);
20302 rtx addr, reg, mem;
20303 reg = gen_rtx_REG (Pmode, 0);
20304 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20305 GEN_INT (info->lr_save_offset));
20306 mem = gen_frame_mem (Pmode, addr);
20307 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20310 return gen_rtx_PARALLEL (VOIDmode, p);
20313 /* Determine whether the gp REG is really used. */
20316 rs6000_reg_live_or_pic_offset_p (int reg)
20318 /* If the function calls eh_return, claim used all the registers that would
20319 be checked for liveness otherwise. This is required for the PIC offset
20320 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20321 register allocation purposes in this case. */
20323 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20324 && (!call_used_regs[reg]
20325 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20326 && !TARGET_SINGLE_PIC_BASE
20327 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20328 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20329 && !TARGET_SINGLE_PIC_BASE
20330 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20331 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20334 /* Emit function prologue as insns. */
20337 rs6000_emit_prologue (void)
20339 rs6000_stack_t *info = rs6000_stack_info ();
20340 enum machine_mode reg_mode = Pmode;
20341 int reg_size = TARGET_32BIT ? 4 : 8;
20342 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20343 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20344 rtx frame_reg_rtx = sp_reg_rtx;
20345 rtx cr_save_rtx = NULL_RTX;
20348 int saving_FPRs_inline;
20349 int saving_GPRs_inline;
20350 int using_store_multiple;
20351 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20352 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20353 && call_used_regs[STATIC_CHAIN_REGNUM]);
20354 HOST_WIDE_INT sp_offset = 0;
20356 if (flag_stack_usage)
20357 current_function_static_stack_size = info->total_size;
20359 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20360 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20362 if (TARGET_FIX_AND_CONTINUE)
20364 /* gdb on darwin arranges to forward a function from the old
20365 address by modifying the first 5 instructions of the function
20366 to branch to the overriding function. This is necessary to
20367 permit function pointers that point to the old function to
20368 actually forward to the new function. */
20369 emit_insn (gen_nop ());
20370 emit_insn (gen_nop ());
20371 emit_insn (gen_nop ());
20372 emit_insn (gen_nop ());
20373 emit_insn (gen_nop ());
20376 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20378 reg_mode = V2SImode;
20382 strategy = info->savres_strategy;
20383 using_store_multiple = strategy & SAVRES_MULTIPLE;
20384 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20385 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20387 /* For V.4, update stack before we do any saving and set back pointer. */
20388 if (! WORLD_SAVE_P (info)
20390 && (DEFAULT_ABI == ABI_V4
20391 || crtl->calls_eh_return))
20393 bool need_r11 = (TARGET_SPE
20394 ? (!saving_GPRs_inline
20395 && info->spe_64bit_regs_used == 0)
20396 : (!saving_FPRs_inline || !saving_GPRs_inline));
20397 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20399 if (info->total_size < 32767)
20400 sp_offset = info->total_size;
20402 frame_reg_rtx = copy_reg;
20403 else if (info->cr_save_p
20405 || info->first_fp_reg_save < 64
20406 || info->first_gp_reg_save < 32
20407 || info->altivec_size != 0
20408 || info->vrsave_mask != 0
20409 || crtl->calls_eh_return)
20411 copy_reg = frame_ptr_rtx;
20412 frame_reg_rtx = copy_reg;
20416 /* The prologue won't be saving any regs so there is no need
20417 to set up a frame register to access any frame save area.
20418 We also won't be using sp_offset anywhere below, but set
20419 the correct value anyway to protect against future
20420 changes to this function. */
20421 sp_offset = info->total_size;
20423 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20424 if (frame_reg_rtx != sp_reg_rtx)
20425 rs6000_emit_stack_tie ();
20428 /* Handle world saves specially here. */
20429 if (WORLD_SAVE_P (info))
20436 /* save_world expects lr in r0. */
20437 reg0 = gen_rtx_REG (Pmode, 0);
20438 if (info->lr_save_p)
20440 insn = emit_move_insn (reg0,
20441 gen_rtx_REG (Pmode, LR_REGNO));
20442 RTX_FRAME_RELATED_P (insn) = 1;
20445 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20446 assumptions about the offsets of various bits of the stack
20448 gcc_assert (info->gp_save_offset == -220
20449 && info->fp_save_offset == -144
20450 && info->lr_save_offset == 8
20451 && info->cr_save_offset == 4
20454 && (!crtl->calls_eh_return
20455 || info->ehrd_offset == -432)
20456 && info->vrsave_save_offset == -224
20457 && info->altivec_save_offset == -416);
20459 treg = gen_rtx_REG (SImode, 11);
20460 emit_move_insn (treg, GEN_INT (-info->total_size));
20462 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20463 in R11. It also clobbers R12, so beware! */
20465 /* Preserve CR2 for save_world prologues */
20467 sz += 32 - info->first_gp_reg_save;
20468 sz += 64 - info->first_fp_reg_save;
20469 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20470 p = rtvec_alloc (sz);
20472 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20473 gen_rtx_REG (SImode,
20475 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20476 gen_rtx_SYMBOL_REF (Pmode,
20478 /* We do floats first so that the instruction pattern matches
20480 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20482 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20483 ? DFmode : SFmode),
20484 info->first_fp_reg_save + i);
20485 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20486 GEN_INT (info->fp_save_offset
20487 + sp_offset + 8 * i));
20488 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20489 ? DFmode : SFmode), addr);
20491 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20493 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20495 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20496 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20497 GEN_INT (info->altivec_save_offset
20498 + sp_offset + 16 * i));
20499 rtx mem = gen_frame_mem (V4SImode, addr);
20501 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20503 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20505 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20506 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20507 GEN_INT (info->gp_save_offset
20508 + sp_offset + reg_size * i));
20509 rtx mem = gen_frame_mem (reg_mode, addr);
20511 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20515 /* CR register traditionally saved as CR2. */
20516 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20517 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20518 GEN_INT (info->cr_save_offset
20520 rtx mem = gen_frame_mem (reg_mode, addr);
20522 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20524 /* Explain about use of R0. */
20525 if (info->lr_save_p)
20527 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20528 GEN_INT (info->lr_save_offset
20530 rtx mem = gen_frame_mem (reg_mode, addr);
20532 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20534 /* Explain what happens to the stack pointer. */
20536 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20537 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20540 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20541 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20542 treg, GEN_INT (-info->total_size));
20543 sp_offset = info->total_size;
20546 /* If we use the link register, get it into r0. */
20547 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20549 rtx addr, reg, mem;
20551 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20552 gen_rtx_REG (Pmode, LR_REGNO));
20553 RTX_FRAME_RELATED_P (insn) = 1;
20555 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20556 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20558 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20559 GEN_INT (info->lr_save_offset + sp_offset));
20560 reg = gen_rtx_REG (Pmode, 0);
20561 mem = gen_rtx_MEM (Pmode, addr);
20562 /* This should not be of rs6000_sr_alias_set, because of
20563 __builtin_return_address. */
20565 insn = emit_move_insn (mem, reg);
20566 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20567 NULL_RTX, NULL_RTX);
20571 /* If we need to save CR, put it into r12 or r11. */
20572 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20577 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20579 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20580 RTX_FRAME_RELATED_P (insn) = 1;
20581 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20582 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20583 But that's OK. All we have to do is specify that _one_ condition
20584 code register is saved in this stack slot. The thrower's epilogue
20585 will then restore all the call-saved registers.
20586 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20587 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20588 gen_rtx_REG (SImode, CR2_REGNO));
20589 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20592 /* Do any required saving of fpr's. If only one or two to save, do
20593 it ourselves. Otherwise, call function. */
20594 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20597 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20598 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20599 && ! call_used_regs[info->first_fp_reg_save+i]))
20600 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20601 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20603 info->first_fp_reg_save + i,
20604 info->fp_save_offset + sp_offset + 8 * i,
20607 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20611 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20612 info->fp_save_offset + sp_offset,
20614 /*savep=*/true, /*gpr=*/false,
20616 & SAVE_NOINLINE_FPRS_SAVES_LR)
20618 insn = emit_insn (par);
20619 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20620 NULL_RTX, NULL_RTX);
20623 /* Save GPRs. This is done as a PARALLEL if we are using
20624 the store-multiple instructions. */
20625 if (!WORLD_SAVE_P (info)
20627 && info->spe_64bit_regs_used != 0
20628 && info->first_gp_reg_save != 32)
20631 rtx spe_save_area_ptr;
20633 /* Determine whether we can address all of the registers that need
20634 to be saved with an offset from the stack pointer that fits in
20635 the small const field for SPE memory instructions. */
20636 int spe_regs_addressable_via_sp
20637 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20638 + (32 - info->first_gp_reg_save - 1) * reg_size)
20639 && saving_GPRs_inline);
20642 if (spe_regs_addressable_via_sp)
20644 spe_save_area_ptr = frame_reg_rtx;
20645 spe_offset = info->spe_gp_save_offset + sp_offset;
20649 /* Make r11 point to the start of the SPE save area. We need
20650 to be careful here if r11 is holding the static chain. If
20651 it is, then temporarily save it in r0. We would use r0 as
20652 our base register here, but using r0 as a base register in
20653 loads and stores means something different from what we
20655 int ool_adjust = (saving_GPRs_inline
20657 : (info->first_gp_reg_save
20658 - (FIRST_SAVRES_REGISTER+1))*8);
20659 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20660 + sp_offset - ool_adjust);
20662 if (using_static_chain_p)
20664 rtx r0 = gen_rtx_REG (Pmode, 0);
20665 gcc_assert (info->first_gp_reg_save > 11);
20667 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20670 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20671 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20673 GEN_INT (offset)));
20674 /* We need to make sure the move to r11 gets noted for
20675 properly outputting unwind information. */
20676 if (!saving_GPRs_inline)
20677 rs6000_frame_related (insn, frame_reg_rtx, offset,
20678 NULL_RTX, NULL_RTX);
20682 if (saving_GPRs_inline)
20684 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20685 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20687 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20688 rtx offset, addr, mem;
20690 /* We're doing all this to ensure that the offset fits into
20691 the immediate offset of 'evstdd'. */
20692 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20694 offset = GEN_INT (reg_size * i + spe_offset);
20695 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20696 mem = gen_rtx_MEM (V2SImode, addr);
20698 insn = emit_move_insn (mem, reg);
20700 rs6000_frame_related (insn, spe_save_area_ptr,
20701 info->spe_gp_save_offset
20702 + sp_offset + reg_size * i,
20703 offset, const0_rtx);
20710 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20712 /*savep=*/true, /*gpr=*/true,
20714 insn = emit_insn (par);
20715 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20716 NULL_RTX, NULL_RTX);
20720 /* Move the static chain pointer back. */
20721 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20722 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20724 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20728 /* Need to adjust r11 (r12) if we saved any FPRs. */
20729 if (info->first_fp_reg_save != 64)
20731 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20733 rtx offset = GEN_INT (sp_offset
20734 + (-8 * (64-info->first_fp_reg_save)));
20735 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20738 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20739 info->gp_save_offset + sp_offset,
20741 /*savep=*/true, /*gpr=*/true,
20743 & SAVE_NOINLINE_GPRS_SAVES_LR)
20745 insn = emit_insn (par);
20746 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20747 NULL_RTX, NULL_RTX);
20749 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20753 p = rtvec_alloc (32 - info->first_gp_reg_save);
20754 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20756 rtx addr, reg, mem;
20757 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20758 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20759 GEN_INT (info->gp_save_offset
20762 mem = gen_frame_mem (reg_mode, addr);
20764 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20766 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20767 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20768 NULL_RTX, NULL_RTX);
20770 else if (!WORLD_SAVE_P (info))
20773 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20774 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20776 rtx addr, reg, mem;
20777 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20779 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20780 GEN_INT (info->gp_save_offset
20783 mem = gen_frame_mem (reg_mode, addr);
20785 insn = emit_move_insn (mem, reg);
20786 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20787 NULL_RTX, NULL_RTX);
20791 /* ??? There's no need to emit actual instructions here, but it's the
20792 easiest way to get the frame unwind information emitted. */
20793 if (crtl->calls_eh_return)
20795 unsigned int i, regno;
20799 regno = EH_RETURN_DATA_REGNO (i);
20800 if (regno == INVALID_REGNUM)
20803 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20804 info->ehrd_offset + sp_offset
20805 + reg_size * (int) i,
20810 /* In AIX ABI we need to make sure r2 is really saved. */
20811 if (TARGET_AIX && crtl->calls_eh_return)
20813 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20814 long toc_restore_insn;
20816 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20817 || frame_reg_rtx == sp_reg_rtx);
20818 tmp_reg = gen_rtx_REG (Pmode, 11);
20819 tmp_reg_si = gen_rtx_REG (SImode, 11);
20820 if (using_static_chain_p)
20821 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20822 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20823 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20824 /* Peek at instruction to which this function returns. If it's
20825 restoring r2, then we know we've already saved r2. We can't
20826 unconditionally save r2 because the value we have will already
20827 be updated if we arrived at this function via a plt call or
20828 toc adjusting stub. */
20829 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20830 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20831 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20832 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20833 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20834 validate_condition_mode (EQ, CCUNSmode);
20835 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20836 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20837 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20838 toc_save_done = gen_label_rtx ();
20839 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20840 gen_rtx_EQ (VOIDmode, compare_result,
20842 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20844 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20845 JUMP_LABEL (jump) = toc_save_done;
20846 LABEL_NUSES (toc_save_done) += 1;
20848 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20849 sp_offset + 5 * reg_size, info->total_size);
20850 emit_label (toc_save_done);
20851 if (using_static_chain_p)
20852 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20855 /* Save CR if we use any that must be preserved. */
20856 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20858 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20859 GEN_INT (info->cr_save_offset + sp_offset));
20860 rtx mem = gen_frame_mem (SImode, addr);
20861 /* See the large comment above about why CR2_REGNO is used. */
20862 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20864 /* If r12 was used to hold the original sp, copy cr into r0 now
20866 if (REGNO (frame_reg_rtx) == 12)
20870 cr_save_rtx = gen_rtx_REG (SImode, 0);
20871 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20872 RTX_FRAME_RELATED_P (insn) = 1;
20873 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20874 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20876 insn = emit_move_insn (mem, cr_save_rtx);
20878 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20879 NULL_RTX, NULL_RTX);
20882 /* Update stack and set back pointer unless this is V.4,
20883 for which it was done previously. */
20884 if (!WORLD_SAVE_P (info) && info->push_p
20885 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20887 rtx copy_reg = NULL;
20889 if (info->total_size < 32767)
20890 sp_offset = info->total_size;
20891 else if (info->altivec_size != 0
20892 || info->vrsave_mask != 0)
20894 copy_reg = frame_ptr_rtx;
20895 frame_reg_rtx = copy_reg;
20898 sp_offset = info->total_size;
20899 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20900 if (frame_reg_rtx != sp_reg_rtx)
20901 rs6000_emit_stack_tie ();
20904 /* Set frame pointer, if needed. */
20905 if (frame_pointer_needed)
20907 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20909 RTX_FRAME_RELATED_P (insn) = 1;
20912 /* Save AltiVec registers if needed. Save here because the red zone does
20913 not include AltiVec registers. */
20914 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20918 /* There should be a non inline version of this, for when we
20919 are saving lots of vector registers. */
20920 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20921 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20923 rtx areg, savereg, mem;
20926 offset = info->altivec_save_offset + sp_offset
20927 + 16 * (i - info->first_altivec_reg_save);
20929 savereg = gen_rtx_REG (V4SImode, i);
20931 areg = gen_rtx_REG (Pmode, 0);
20932 emit_move_insn (areg, GEN_INT (offset));
20934 /* AltiVec addressing mode is [reg+reg]. */
20935 mem = gen_frame_mem (V4SImode,
20936 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20938 insn = emit_move_insn (mem, savereg);
20940 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20941 areg, GEN_INT (offset));
20945 /* VRSAVE is a bit vector representing which AltiVec registers
20946 are used. The OS uses this to determine which vector
20947 registers to save on a context switch. We need to save
20948 VRSAVE on the stack frame, add whatever AltiVec registers we
20949 used in this function, and do the corresponding magic in the
20952 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20953 && info->vrsave_mask != 0)
20955 rtx reg, mem, vrsave;
20958 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20959 as frame_reg_rtx and r11 as the static chain pointer for
20960 nested functions. */
20961 reg = gen_rtx_REG (SImode, 0);
20962 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20964 emit_insn (gen_get_vrsave_internal (reg));
20966 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20968 if (!WORLD_SAVE_P (info))
20971 offset = info->vrsave_save_offset + sp_offset;
20972 mem = gen_frame_mem (SImode,
20973 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20974 GEN_INT (offset)));
20975 insn = emit_move_insn (mem, reg);
20978 /* Include the registers in the mask. */
20979 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20981 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20984 if (TARGET_SINGLE_PIC_BASE)
20985 return; /* Do not set PIC register */
20987 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20988 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20989 || (DEFAULT_ABI == ABI_V4
20990 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20991 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20993 /* If emit_load_toc_table will use the link register, we need to save
20994 it. We use R12 for this purpose because emit_load_toc_table
20995 can use register 0. This allows us to use a plain 'blr' to return
20996 from the procedure more often. */
20997 int save_LR_around_toc_setup = (TARGET_ELF
20998 && DEFAULT_ABI != ABI_AIX
21000 && ! info->lr_save_p
21001 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
21002 if (save_LR_around_toc_setup)
21004 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21006 insn = emit_move_insn (frame_ptr_rtx, lr);
21007 RTX_FRAME_RELATED_P (insn) = 1;
21009 rs6000_emit_load_toc_table (TRUE);
21011 insn = emit_move_insn (lr, frame_ptr_rtx);
21012 RTX_FRAME_RELATED_P (insn) = 1;
21015 rs6000_emit_load_toc_table (TRUE);
21019 if (DEFAULT_ABI == ABI_DARWIN
21020 && flag_pic && crtl->uses_pic_offset_table)
21022 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21023 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
21025 /* Save and restore LR locally around this call (in R0). */
21026 if (!info->lr_save_p)
21027 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
21029 emit_insn (gen_load_macho_picbase (src));
21031 emit_move_insn (gen_rtx_REG (Pmode,
21032 RS6000_PIC_OFFSET_TABLE_REGNUM),
21035 if (!info->lr_save_p)
21036 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
21041 /* Write function prologue. */
21044 rs6000_output_function_prologue (FILE *file,
21045 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21047 rs6000_stack_t *info = rs6000_stack_info ();
21049 if (TARGET_DEBUG_STACK)
21050 debug_stack_info (info);
21052 /* Write .extern for any function we will call to save and restore
21054 if (info->first_fp_reg_save < 64)
21057 int regno = info->first_fp_reg_save - 32;
21059 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
21061 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
21062 /*gpr=*/false, /*lr=*/false);
21063 fprintf (file, "\t.extern %s\n", name);
21065 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
21067 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
21068 /*gpr=*/false, /*lr=*/true);
21069 fprintf (file, "\t.extern %s\n", name);
21073 /* Write .extern for AIX common mode routines, if needed. */
21074 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21076 fputs ("\t.extern __mulh\n", file);
21077 fputs ("\t.extern __mull\n", file);
21078 fputs ("\t.extern __divss\n", file);
21079 fputs ("\t.extern __divus\n", file);
21080 fputs ("\t.extern __quoss\n", file);
21081 fputs ("\t.extern __quous\n", file);
21082 common_mode_defined = 1;
21085 if (! HAVE_prologue)
21091 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21092 the "toplevel" insn chain. */
21093 emit_note (NOTE_INSN_DELETED);
21094 rs6000_emit_prologue ();
21095 emit_note (NOTE_INSN_DELETED);
21097 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21101 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21103 INSN_ADDRESSES_NEW (insn, addr);
21108 prologue = get_insns ();
21111 if (TARGET_DEBUG_STACK)
21112 debug_rtx_list (prologue, 100);
21114 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21118 rs6000_pic_labelno++;
21121 /* Non-zero if vmx regs are restored before the frame pop, zero if
21122 we restore after the pop when possible. */
21123 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21125 /* Reload CR from REG. */
21128 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21133 if (using_mfcr_multiple)
21135 for (i = 0; i < 8; i++)
21136 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21138 gcc_assert (count);
21141 if (using_mfcr_multiple && count > 1)
21146 p = rtvec_alloc (count);
21149 for (i = 0; i < 8; i++)
21150 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21152 rtvec r = rtvec_alloc (2);
21153 RTVEC_ELT (r, 0) = reg;
21154 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21155 RTVEC_ELT (p, ndx) =
21156 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21157 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21160 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21161 gcc_assert (ndx == count);
21164 for (i = 0; i < 8; i++)
21165 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21167 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21173 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21174 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21175 below stack pointer not cloberred by signals. */
21178 offset_below_red_zone_p (HOST_WIDE_INT offset)
21180 return offset < (DEFAULT_ABI == ABI_V4
21182 : TARGET_32BIT ? -220 : -288);
21185 /* Emit function epilogue as insns. */
21188 rs6000_emit_epilogue (int sibcall)
21190 rs6000_stack_t *info;
21191 int restoring_GPRs_inline;
21192 int restoring_FPRs_inline;
21193 int using_load_multiple;
21194 int using_mtcr_multiple;
21195 int use_backchain_to_restore_sp;
21199 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21200 rtx frame_reg_rtx = sp_reg_rtx;
21201 rtx cfa_restores = NULL_RTX;
21203 rtx cr_save_reg = NULL_RTX;
21204 enum machine_mode reg_mode = Pmode;
21205 int reg_size = TARGET_32BIT ? 4 : 8;
21208 info = rs6000_stack_info ();
21210 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21212 reg_mode = V2SImode;
21216 strategy = info->savres_strategy;
21217 using_load_multiple = strategy & SAVRES_MULTIPLE;
21218 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21219 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21220 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21221 || rs6000_cpu == PROCESSOR_PPC603
21222 || rs6000_cpu == PROCESSOR_PPC750
21224 /* Restore via the backchain when we have a large frame, since this
21225 is more efficient than an addis, addi pair. The second condition
21226 here will not trigger at the moment; We don't actually need a
21227 frame pointer for alloca, but the generic parts of the compiler
21228 give us one anyway. */
21229 use_backchain_to_restore_sp = (info->total_size > 32767
21230 || info->total_size
21231 + (info->lr_save_p ? info->lr_save_offset : 0)
21233 || (cfun->calls_alloca
21234 && !frame_pointer_needed));
21235 restore_lr = (info->lr_save_p
21236 && (restoring_FPRs_inline
21237 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21238 && (restoring_GPRs_inline
21239 || info->first_fp_reg_save < 64));
21241 if (WORLD_SAVE_P (info))
21245 const char *alloc_rname;
21248 /* eh_rest_world_r10 will return to the location saved in the LR
21249 stack slot (which is not likely to be our caller.)
21250 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21251 rest_world is similar, except any R10 parameter is ignored.
21252 The exception-handling stuff that was here in 2.95 is no
21253 longer necessary. */
21257 + 32 - info->first_gp_reg_save
21258 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21259 + 63 + 1 - info->first_fp_reg_save);
21261 strcpy (rname, ((crtl->calls_eh_return) ?
21262 "*eh_rest_world_r10" : "*rest_world"));
21263 alloc_rname = ggc_strdup (rname);
21266 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21267 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21268 gen_rtx_REG (Pmode,
21271 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21272 /* The instruction pattern requires a clobber here;
21273 it is shared with the restVEC helper. */
21275 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21278 /* CR register traditionally saved as CR2. */
21279 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21280 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21281 GEN_INT (info->cr_save_offset));
21282 rtx mem = gen_frame_mem (reg_mode, addr);
21284 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21287 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21289 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21290 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21291 GEN_INT (info->gp_save_offset
21293 rtx mem = gen_frame_mem (reg_mode, addr);
21295 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21297 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21299 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21300 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21301 GEN_INT (info->altivec_save_offset
21303 rtx mem = gen_frame_mem (V4SImode, addr);
21305 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21307 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21309 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21310 ? DFmode : SFmode),
21311 info->first_fp_reg_save + i);
21312 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21313 GEN_INT (info->fp_save_offset
21315 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21316 ? DFmode : SFmode), addr);
21318 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21321 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21323 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21325 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21327 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21329 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21330 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21335 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21337 sp_offset = info->total_size;
21339 /* Restore AltiVec registers if we must do so before adjusting the
21341 if (TARGET_ALTIVEC_ABI
21342 && info->altivec_size != 0
21343 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21344 || (DEFAULT_ABI != ABI_V4
21345 && offset_below_red_zone_p (info->altivec_save_offset))))
21349 if (use_backchain_to_restore_sp)
21351 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21352 emit_move_insn (frame_reg_rtx,
21353 gen_rtx_MEM (Pmode, sp_reg_rtx));
21356 else if (frame_pointer_needed)
21357 frame_reg_rtx = hard_frame_pointer_rtx;
21359 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21360 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21362 rtx addr, areg, mem, reg;
21364 areg = gen_rtx_REG (Pmode, 0);
21366 (areg, GEN_INT (info->altivec_save_offset
21368 + 16 * (i - info->first_altivec_reg_save)));
21370 /* AltiVec addressing mode is [reg+reg]. */
21371 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21372 mem = gen_frame_mem (V4SImode, addr);
21374 reg = gen_rtx_REG (V4SImode, i);
21375 emit_move_insn (reg, mem);
21376 if (offset_below_red_zone_p (info->altivec_save_offset
21377 + (i - info->first_altivec_reg_save)
21379 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21384 /* Restore VRSAVE if we must do so before adjusting the stack. */
21386 && TARGET_ALTIVEC_VRSAVE
21387 && info->vrsave_mask != 0
21388 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21389 || (DEFAULT_ABI != ABI_V4
21390 && offset_below_red_zone_p (info->vrsave_save_offset))))
21392 rtx addr, mem, reg;
21394 if (frame_reg_rtx == sp_reg_rtx)
21396 if (use_backchain_to_restore_sp)
21398 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21399 emit_move_insn (frame_reg_rtx,
21400 gen_rtx_MEM (Pmode, sp_reg_rtx));
21403 else if (frame_pointer_needed)
21404 frame_reg_rtx = hard_frame_pointer_rtx;
21407 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21408 GEN_INT (info->vrsave_save_offset + sp_offset));
21409 mem = gen_frame_mem (SImode, addr);
21410 reg = gen_rtx_REG (SImode, 12);
21411 emit_move_insn (reg, mem);
21413 emit_insn (generate_set_vrsave (reg, info, 1));
21417 /* If we have a large stack frame, restore the old stack pointer
21418 using the backchain. */
21419 if (use_backchain_to_restore_sp)
21421 if (frame_reg_rtx == sp_reg_rtx)
21423 /* Under V.4, don't reset the stack pointer until after we're done
21424 loading the saved registers. */
21425 if (DEFAULT_ABI == ABI_V4)
21426 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21428 insn = emit_move_insn (frame_reg_rtx,
21429 gen_rtx_MEM (Pmode, sp_reg_rtx));
21432 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21433 && DEFAULT_ABI == ABI_V4)
21434 /* frame_reg_rtx has been set up by the altivec restore. */
21438 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21439 frame_reg_rtx = sp_reg_rtx;
21442 /* If we have a frame pointer, we can restore the old stack pointer
21444 else if (frame_pointer_needed)
21446 frame_reg_rtx = sp_reg_rtx;
21447 if (DEFAULT_ABI == ABI_V4)
21448 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21449 /* Prevent reordering memory accesses against stack pointer restore. */
21450 else if (cfun->calls_alloca
21451 || offset_below_red_zone_p (-info->total_size))
21453 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21454 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21455 MEM_NOTRAP_P (mem1) = 1;
21456 MEM_NOTRAP_P (mem2) = 1;
21457 emit_insn (gen_frame_tie (mem1, mem2));
21460 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21461 GEN_INT (info->total_size)));
21464 else if (info->push_p
21465 && DEFAULT_ABI != ABI_V4
21466 && !crtl->calls_eh_return)
21468 /* Prevent reordering memory accesses against stack pointer restore. */
21469 if (cfun->calls_alloca
21470 || offset_below_red_zone_p (-info->total_size))
21472 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21473 MEM_NOTRAP_P (mem) = 1;
21474 emit_insn (gen_stack_tie (mem));
21476 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21477 GEN_INT (info->total_size)));
21480 if (insn && frame_reg_rtx == sp_reg_rtx)
21484 REG_NOTES (insn) = cfa_restores;
21485 cfa_restores = NULL_RTX;
21487 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21488 RTX_FRAME_RELATED_P (insn) = 1;
21491 /* Restore AltiVec registers if we have not done so already. */
21492 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21493 && TARGET_ALTIVEC_ABI
21494 && info->altivec_size != 0
21495 && (DEFAULT_ABI == ABI_V4
21496 || !offset_below_red_zone_p (info->altivec_save_offset)))
21500 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21501 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21503 rtx addr, areg, mem, reg;
21505 areg = gen_rtx_REG (Pmode, 0);
21507 (areg, GEN_INT (info->altivec_save_offset
21509 + 16 * (i - info->first_altivec_reg_save)));
21511 /* AltiVec addressing mode is [reg+reg]. */
21512 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21513 mem = gen_frame_mem (V4SImode, addr);
21515 reg = gen_rtx_REG (V4SImode, i);
21516 emit_move_insn (reg, mem);
21517 if (DEFAULT_ABI == ABI_V4)
21518 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21523 /* Restore VRSAVE if we have not done so already. */
21524 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21526 && TARGET_ALTIVEC_VRSAVE
21527 && info->vrsave_mask != 0
21528 && (DEFAULT_ABI == ABI_V4
21529 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21531 rtx addr, mem, reg;
21533 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21534 GEN_INT (info->vrsave_save_offset + sp_offset));
21535 mem = gen_frame_mem (SImode, addr);
21536 reg = gen_rtx_REG (SImode, 12);
21537 emit_move_insn (reg, mem);
21539 emit_insn (generate_set_vrsave (reg, info, 1));
21542 /* Get the old lr if we saved it. If we are restoring registers
21543 out-of-line, then the out-of-line routines can do this for us. */
21544 if (restore_lr && restoring_GPRs_inline)
21546 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21547 info->lr_save_offset + sp_offset);
21549 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21552 /* Get the old cr if we saved it. */
21553 if (info->cr_save_p)
21555 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21556 GEN_INT (info->cr_save_offset + sp_offset));
21557 rtx mem = gen_frame_mem (SImode, addr);
21559 cr_save_reg = gen_rtx_REG (SImode,
21560 DEFAULT_ABI == ABI_AIX
21561 && !restoring_GPRs_inline
21562 && info->first_fp_reg_save < 64
21564 emit_move_insn (cr_save_reg, mem);
21567 /* Set LR here to try to overlap restores below. LR is always saved
21568 above incoming stack, so it never needs REG_CFA_RESTORE. */
21569 if (restore_lr && restoring_GPRs_inline)
21570 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21571 gen_rtx_REG (Pmode, 0));
21573 /* Load exception handler data registers, if needed. */
21574 if (crtl->calls_eh_return)
21576 unsigned int i, regno;
21580 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21581 GEN_INT (sp_offset + 5 * reg_size));
21582 rtx mem = gen_frame_mem (reg_mode, addr);
21584 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21591 regno = EH_RETURN_DATA_REGNO (i);
21592 if (regno == INVALID_REGNUM)
21595 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21596 info->ehrd_offset + sp_offset
21597 + reg_size * (int) i);
21599 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21603 /* Restore GPRs. This is done as a PARALLEL if we are using
21604 the load-multiple instructions. */
21606 && info->spe_64bit_regs_used != 0
21607 && info->first_gp_reg_save != 32)
21609 /* Determine whether we can address all of the registers that need
21610 to be saved with an offset from the stack pointer that fits in
21611 the small const field for SPE memory instructions. */
21612 int spe_regs_addressable_via_sp
21613 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21614 + (32 - info->first_gp_reg_save - 1) * reg_size)
21615 && restoring_GPRs_inline);
21618 if (spe_regs_addressable_via_sp)
21619 spe_offset = info->spe_gp_save_offset + sp_offset;
21622 rtx old_frame_reg_rtx = frame_reg_rtx;
21623 /* Make r11 point to the start of the SPE save area. We worried about
21624 not clobbering it when we were saving registers in the prologue.
21625 There's no need to worry here because the static chain is passed
21626 anew to every function. */
21627 int ool_adjust = (restoring_GPRs_inline
21629 : (info->first_gp_reg_save
21630 - (FIRST_SAVRES_REGISTER+1))*8);
21632 if (frame_reg_rtx == sp_reg_rtx)
21633 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21634 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21635 GEN_INT (info->spe_gp_save_offset
21638 /* Keep the invariant that frame_reg_rtx + sp_offset points
21639 at the top of the stack frame. */
21640 sp_offset = -info->spe_gp_save_offset;
21645 if (restoring_GPRs_inline)
21647 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21648 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21650 rtx offset, addr, mem, reg;
21652 /* We're doing all this to ensure that the immediate offset
21653 fits into the immediate field of 'evldd'. */
21654 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21656 offset = GEN_INT (spe_offset + reg_size * i);
21657 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21658 mem = gen_rtx_MEM (V2SImode, addr);
21659 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21661 insn = emit_move_insn (reg, mem);
21662 if (DEFAULT_ABI == ABI_V4)
21664 if (frame_pointer_needed
21665 && info->first_gp_reg_save + i
21666 == HARD_FRAME_POINTER_REGNUM)
21668 add_reg_note (insn, REG_CFA_DEF_CFA,
21669 plus_constant (frame_reg_rtx,
21671 RTX_FRAME_RELATED_P (insn) = 1;
21674 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21683 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21685 /*savep=*/false, /*gpr=*/true,
21687 emit_jump_insn (par);
21688 /* We don't want anybody else emitting things after we jumped
21693 else if (!restoring_GPRs_inline)
21695 /* We are jumping to an out-of-line function. */
21696 bool can_use_exit = info->first_fp_reg_save == 64;
21699 /* Emit stack reset code if we need it. */
21701 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21702 sp_offset, can_use_exit);
21705 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21708 GEN_INT (sp_offset - info->fp_size)));
21709 if (REGNO (frame_reg_rtx) == 11)
21710 sp_offset += info->fp_size;
21713 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21714 info->gp_save_offset, reg_mode,
21715 /*savep=*/false, /*gpr=*/true,
21716 /*lr=*/can_use_exit);
21720 if (info->cr_save_p)
21722 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21723 if (DEFAULT_ABI == ABI_V4)
21725 = alloc_reg_note (REG_CFA_RESTORE,
21726 gen_rtx_REG (SImode, CR2_REGNO),
21730 emit_jump_insn (par);
21732 /* We don't want anybody else emitting things after we jumped
21737 insn = emit_insn (par);
21738 if (DEFAULT_ABI == ABI_V4)
21740 if (frame_pointer_needed)
21742 add_reg_note (insn, REG_CFA_DEF_CFA,
21743 plus_constant (frame_reg_rtx, sp_offset));
21744 RTX_FRAME_RELATED_P (insn) = 1;
21747 for (i = info->first_gp_reg_save; i < 32; i++)
21749 = alloc_reg_note (REG_CFA_RESTORE,
21750 gen_rtx_REG (reg_mode, i), cfa_restores);
21753 else if (using_load_multiple)
21756 p = rtvec_alloc (32 - info->first_gp_reg_save);
21757 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21759 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21760 GEN_INT (info->gp_save_offset
21763 rtx mem = gen_frame_mem (reg_mode, addr);
21764 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21766 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21767 if (DEFAULT_ABI == ABI_V4)
21768 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21771 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21772 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21774 add_reg_note (insn, REG_CFA_DEF_CFA,
21775 plus_constant (frame_reg_rtx, sp_offset));
21776 RTX_FRAME_RELATED_P (insn) = 1;
21781 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21782 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21784 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21785 GEN_INT (info->gp_save_offset
21788 rtx mem = gen_frame_mem (reg_mode, addr);
21789 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21791 insn = emit_move_insn (reg, mem);
21792 if (DEFAULT_ABI == ABI_V4)
21794 if (frame_pointer_needed
21795 && info->first_gp_reg_save + i
21796 == HARD_FRAME_POINTER_REGNUM)
21798 add_reg_note (insn, REG_CFA_DEF_CFA,
21799 plus_constant (frame_reg_rtx, sp_offset));
21800 RTX_FRAME_RELATED_P (insn) = 1;
21803 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21809 if (restore_lr && !restoring_GPRs_inline)
21811 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21812 info->lr_save_offset + sp_offset);
21814 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21815 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21816 gen_rtx_REG (Pmode, 0));
21819 /* Restore fpr's if we need to do it without calling a function. */
21820 if (restoring_FPRs_inline)
21821 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21822 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21823 && ! call_used_regs[info->first_fp_reg_save+i]))
21825 rtx addr, mem, reg;
21826 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21827 GEN_INT (info->fp_save_offset
21830 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21831 ? DFmode : SFmode), addr);
21832 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21833 ? DFmode : SFmode),
21834 info->first_fp_reg_save + i);
21836 emit_move_insn (reg, mem);
21837 if (DEFAULT_ABI == ABI_V4)
21838 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21842 /* If we saved cr, restore it here. Just those that were used. */
21843 if (info->cr_save_p)
21845 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21846 if (DEFAULT_ABI == ABI_V4)
21848 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21852 /* If this is V.4, unwind the stack pointer after all of the loads
21854 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21855 sp_offset, !restoring_FPRs_inline);
21860 REG_NOTES (insn) = cfa_restores;
21861 cfa_restores = NULL_RTX;
21863 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21864 RTX_FRAME_RELATED_P (insn) = 1;
21867 if (crtl->calls_eh_return)
21869 rtx sa = EH_RETURN_STACKADJ_RTX;
21870 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21876 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21877 if (! restoring_FPRs_inline)
21878 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21880 p = rtvec_alloc (2);
21882 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21883 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21884 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21885 : gen_rtx_CLOBBER (VOIDmode,
21886 gen_rtx_REG (Pmode, 65)));
21888 /* If we have to restore more than two FP registers, branch to the
21889 restore function. It will return to our caller. */
21890 if (! restoring_FPRs_inline)
21895 sym = rs6000_savres_routine_sym (info,
21899 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21900 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21901 gen_rtx_REG (Pmode,
21902 DEFAULT_ABI == ABI_AIX
21904 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21907 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21908 GEN_INT (info->fp_save_offset + 8*i));
21909 mem = gen_frame_mem (DFmode, addr);
21911 RTVEC_ELT (p, i+4) =
21912 gen_rtx_SET (VOIDmode,
21913 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21918 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21922 /* Write function epilogue. */
21925 rs6000_output_function_epilogue (FILE *file,
21926 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21928 if (! HAVE_epilogue)
21930 rtx insn = get_last_insn ();
21931 /* If the last insn was a BARRIER, we don't have to write anything except
21932 the trace table. */
21933 if (GET_CODE (insn) == NOTE)
21934 insn = prev_nonnote_insn (insn);
21935 if (insn == 0 || GET_CODE (insn) != BARRIER)
21937 /* This is slightly ugly, but at least we don't have two
21938 copies of the epilogue-emitting code. */
21941 /* A NOTE_INSN_DELETED is supposed to be at the start
21942 and end of the "toplevel" insn chain. */
21943 emit_note (NOTE_INSN_DELETED);
21944 rs6000_emit_epilogue (FALSE);
21945 emit_note (NOTE_INSN_DELETED);
21947 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21951 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21953 INSN_ADDRESSES_NEW (insn, addr);
21958 if (TARGET_DEBUG_STACK)
21959 debug_rtx_list (get_insns (), 100);
21960 final (get_insns (), file, FALSE);
21966 macho_branch_islands ();
21967 /* Mach-O doesn't support labels at the end of objects, so if
21968 it looks like we might want one, insert a NOP. */
21970 rtx insn = get_last_insn ();
21973 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21974 insn = PREV_INSN (insn);
21978 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21979 fputs ("\tnop\n", file);
21983 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21986 We don't output a traceback table if -finhibit-size-directive was
21987 used. The documentation for -finhibit-size-directive reads
21988 ``don't output a @code{.size} assembler directive, or anything
21989 else that would cause trouble if the function is split in the
21990 middle, and the two halves are placed at locations far apart in
21991 memory.'' The traceback table has this property, since it
21992 includes the offset from the start of the function to the
21993 traceback table itself.
21995 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21996 different traceback table. */
21997 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21998 && rs6000_traceback != traceback_none && !cfun->is_thunk)
22000 const char *fname = NULL;
22001 const char *language_string = lang_hooks.name;
22002 int fixed_parms = 0, float_parms = 0, parm_info = 0;
22004 int optional_tbtab;
22005 rs6000_stack_t *info = rs6000_stack_info ();
22007 if (rs6000_traceback == traceback_full)
22008 optional_tbtab = 1;
22009 else if (rs6000_traceback == traceback_part)
22010 optional_tbtab = 0;
22012 optional_tbtab = !optimize_size && !TARGET_ELF;
22014 if (optional_tbtab)
22016 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
22017 while (*fname == '.') /* V.4 encodes . in the name */
22020 /* Need label immediately before tbtab, so we can compute
22021 its offset from the function start. */
22022 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22023 ASM_OUTPUT_LABEL (file, fname);
22026 /* The .tbtab pseudo-op can only be used for the first eight
22027 expressions, since it can't handle the possibly variable
22028 length fields that follow. However, if you omit the optional
22029 fields, the assembler outputs zeros for all optional fields
22030 anyways, giving each variable length field is minimum length
22031 (as defined in sys/debug.h). Thus we can not use the .tbtab
22032 pseudo-op at all. */
22034 /* An all-zero word flags the start of the tbtab, for debuggers
22035 that have to find it by searching forward from the entry
22036 point or from the current pc. */
22037 fputs ("\t.long 0\n", file);
22039 /* Tbtab format type. Use format type 0. */
22040 fputs ("\t.byte 0,", file);
22042 /* Language type. Unfortunately, there does not seem to be any
22043 official way to discover the language being compiled, so we
22044 use language_string.
22045 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22046 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22047 a number, so for now use 9. LTO isn't assigned a number either,
22048 so for now use 0. */
22049 if (! strcmp (language_string, "GNU C")
22050 || ! strcmp (language_string, "GNU GIMPLE"))
22052 else if (! strcmp (language_string, "GNU F77")
22053 || ! strcmp (language_string, "GNU Fortran"))
22055 else if (! strcmp (language_string, "GNU Pascal"))
22057 else if (! strcmp (language_string, "GNU Ada"))
22059 else if (! strcmp (language_string, "GNU C++")
22060 || ! strcmp (language_string, "GNU Objective-C++"))
22062 else if (! strcmp (language_string, "GNU Java"))
22064 else if (! strcmp (language_string, "GNU Objective-C"))
22067 gcc_unreachable ();
22068 fprintf (file, "%d,", i);
22070 /* 8 single bit fields: global linkage (not set for C extern linkage,
22071 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22072 from start of procedure stored in tbtab, internal function, function
22073 has controlled storage, function has no toc, function uses fp,
22074 function logs/aborts fp operations. */
22075 /* Assume that fp operations are used if any fp reg must be saved. */
22076 fprintf (file, "%d,",
22077 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22079 /* 6 bitfields: function is interrupt handler, name present in
22080 proc table, function calls alloca, on condition directives
22081 (controls stack walks, 3 bits), saves condition reg, saves
22083 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22084 set up as a frame pointer, even when there is no alloca call. */
22085 fprintf (file, "%d,",
22086 ((optional_tbtab << 6)
22087 | ((optional_tbtab & frame_pointer_needed) << 5)
22088 | (info->cr_save_p << 1)
22089 | (info->lr_save_p)));
22091 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22093 fprintf (file, "%d,",
22094 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22096 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22097 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22099 if (optional_tbtab)
22101 /* Compute the parameter info from the function decl argument
22104 int next_parm_info_bit = 31;
22106 for (decl = DECL_ARGUMENTS (current_function_decl);
22107 decl; decl = DECL_CHAIN (decl))
22109 rtx parameter = DECL_INCOMING_RTL (decl);
22110 enum machine_mode mode = GET_MODE (parameter);
22112 if (GET_CODE (parameter) == REG)
22114 if (SCALAR_FLOAT_MODE_P (mode))
22135 gcc_unreachable ();
22138 /* If only one bit will fit, don't or in this entry. */
22139 if (next_parm_info_bit > 0)
22140 parm_info |= (bits << (next_parm_info_bit - 1));
22141 next_parm_info_bit -= 2;
22145 fixed_parms += ((GET_MODE_SIZE (mode)
22146 + (UNITS_PER_WORD - 1))
22148 next_parm_info_bit -= 1;
22154 /* Number of fixed point parameters. */
22155 /* This is actually the number of words of fixed point parameters; thus
22156 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22157 fprintf (file, "%d,", fixed_parms);
22159 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22161 /* This is actually the number of fp registers that hold parameters;
22162 and thus the maximum value is 13. */
22163 /* Set parameters on stack bit if parameters are not in their original
22164 registers, regardless of whether they are on the stack? Xlc
22165 seems to set the bit when not optimizing. */
22166 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22168 if (! optional_tbtab)
22171 /* Optional fields follow. Some are variable length. */
22173 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22174 11 double float. */
22175 /* There is an entry for each parameter in a register, in the order that
22176 they occur in the parameter list. Any intervening arguments on the
22177 stack are ignored. If the list overflows a long (max possible length
22178 34 bits) then completely leave off all elements that don't fit. */
22179 /* Only emit this long if there was at least one parameter. */
22180 if (fixed_parms || float_parms)
22181 fprintf (file, "\t.long %d\n", parm_info);
22183 /* Offset from start of code to tb table. */
22184 fputs ("\t.long ", file);
22185 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22186 RS6000_OUTPUT_BASENAME (file, fname);
22188 rs6000_output_function_entry (file, fname);
22191 /* Interrupt handler mask. */
22192 /* Omit this long, since we never set the interrupt handler bit
22195 /* Number of CTL (controlled storage) anchors. */
22196 /* Omit this long, since the has_ctl bit is never set above. */
22198 /* Displacement into stack of each CTL anchor. */
22199 /* Omit this list of longs, because there are no CTL anchors. */
22201 /* Length of function name. */
22204 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22206 /* Function name. */
22207 assemble_string (fname, strlen (fname));
22209 /* Register for alloca automatic storage; this is always reg 31.
22210 Only emit this if the alloca bit was set above. */
22211 if (frame_pointer_needed)
22212 fputs ("\t.byte 31\n", file);
22214 fputs ("\t.align 2\n", file);
22218 /* A C compound statement that outputs the assembler code for a thunk
22219 function, used to implement C++ virtual function calls with
22220 multiple inheritance. The thunk acts as a wrapper around a virtual
22221 function, adjusting the implicit object parameter before handing
22222 control off to the real function.
22224 First, emit code to add the integer DELTA to the location that
22225 contains the incoming first argument. Assume that this argument
22226 contains a pointer, and is the one used to pass the `this' pointer
22227 in C++. This is the incoming argument *before* the function
22228 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22229 values of all other incoming arguments.
22231 After the addition, emit code to jump to FUNCTION, which is a
22232 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22233 not touch the return address. Hence returning from FUNCTION will
22234 return to whoever called the current `thunk'.
22236 The effect must be as if FUNCTION had been called directly with the
22237 adjusted first argument. This macro is responsible for emitting
22238 all of the code for a thunk function; output_function_prologue()
22239 and output_function_epilogue() are not invoked.
22241 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22242 been extracted from it.) It might possibly be useful on some
22243 targets, but probably not.
22245 If you do not define this macro, the target-independent code in the
22246 C++ frontend will generate a less efficient heavyweight thunk that
22247 calls FUNCTION instead of jumping to it. The generic approach does
22248 not support varargs. */
22251 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22252 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22255 rtx this_rtx, insn, funexp;
22257 reload_completed = 1;
22258 epilogue_completed = 1;
22260 /* Mark the end of the (empty) prologue. */
22261 emit_note (NOTE_INSN_PROLOGUE_END);
22263 /* Find the "this" pointer. If the function returns a structure,
22264 the structure return pointer is in r3. */
22265 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22266 this_rtx = gen_rtx_REG (Pmode, 4);
22268 this_rtx = gen_rtx_REG (Pmode, 3);
22270 /* Apply the constant offset, if required. */
22272 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22274 /* Apply the offset from the vtable, if required. */
22277 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22278 rtx tmp = gen_rtx_REG (Pmode, 12);
22280 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22281 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22283 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22284 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22288 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22290 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22292 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22295 /* Generate a tail call to the target function. */
22296 if (!TREE_USED (function))
22298 assemble_external (function);
22299 TREE_USED (function) = 1;
22301 funexp = XEXP (DECL_RTL (function), 0);
22302 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22305 if (MACHOPIC_INDIRECT)
22306 funexp = machopic_indirect_call_target (funexp);
22309 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22310 generate sibcall RTL explicitly. */
22311 insn = emit_call_insn (
22312 gen_rtx_PARALLEL (VOIDmode,
22314 gen_rtx_CALL (VOIDmode,
22315 funexp, const0_rtx),
22316 gen_rtx_USE (VOIDmode, const0_rtx),
22317 gen_rtx_USE (VOIDmode,
22318 gen_rtx_REG (SImode,
22320 gen_rtx_RETURN (VOIDmode))));
22321 SIBLING_CALL_P (insn) = 1;
22324 /* Run just enough of rest_of_compilation to get the insns emitted.
22325 There's not really enough bulk here to make other passes such as
22326 instruction scheduling worth while. Note that use_thunk calls
22327 assemble_start_function and assemble_end_function. */
22328 insn = get_insns ();
22329 insn_locators_alloc ();
22330 shorten_branches (insn);
22331 final_start_function (insn, file, 1);
22332 final (insn, file, 1);
22333 final_end_function ();
22335 reload_completed = 0;
22336 epilogue_completed = 0;
22339 /* A quick summary of the various types of 'constant-pool tables'
22342 Target Flags Name One table per
22343 AIX (none) AIX TOC object file
22344 AIX -mfull-toc AIX TOC object file
22345 AIX -mminimal-toc AIX minimal TOC translation unit
22346 SVR4/EABI (none) SVR4 SDATA object file
22347 SVR4/EABI -fpic SVR4 pic object file
22348 SVR4/EABI -fPIC SVR4 PIC translation unit
22349 SVR4/EABI -mrelocatable EABI TOC function
22350 SVR4/EABI -maix AIX TOC object file
22351 SVR4/EABI -maix -mminimal-toc
22352 AIX minimal TOC translation unit
22354 Name Reg. Set by entries contains:
22355 made by addrs? fp? sum?
22357 AIX TOC 2 crt0 as Y option option
22358 AIX minimal TOC 30 prolog gcc Y Y option
22359 SVR4 SDATA 13 crt0 gcc N Y N
22360 SVR4 pic 30 prolog ld Y not yet N
22361 SVR4 PIC 30 prolog gcc Y option option
22362 EABI TOC 30 prolog gcc Y option option
22366 /* Hash functions for the hash table. */
22369 rs6000_hash_constant (rtx k)
22371 enum rtx_code code = GET_CODE (k);
22372 enum machine_mode mode = GET_MODE (k);
22373 unsigned result = (code << 3) ^ mode;
22374 const char *format;
22377 format = GET_RTX_FORMAT (code);
22378 flen = strlen (format);
22384 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22387 if (mode != VOIDmode)
22388 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22400 for (; fidx < flen; fidx++)
22401 switch (format[fidx])
22406 const char *str = XSTR (k, fidx);
22407 len = strlen (str);
22408 result = result * 613 + len;
22409 for (i = 0; i < len; i++)
22410 result = result * 613 + (unsigned) str[i];
22415 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22419 result = result * 613 + (unsigned) XINT (k, fidx);
22422 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22423 result = result * 613 + (unsigned) XWINT (k, fidx);
22427 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22428 result = result * 613 + (unsigned) (XWINT (k, fidx)
22435 gcc_unreachable ();
22442 toc_hash_function (const void *hash_entry)
22444 const struct toc_hash_struct *thc =
22445 (const struct toc_hash_struct *) hash_entry;
22446 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22449 /* Compare H1 and H2 for equivalence. */
22452 toc_hash_eq (const void *h1, const void *h2)
22454 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22455 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22457 if (((const struct toc_hash_struct *) h1)->key_mode
22458 != ((const struct toc_hash_struct *) h2)->key_mode)
22461 return rtx_equal_p (r1, r2);
22464 /* These are the names given by the C++ front-end to vtables, and
22465 vtable-like objects. Ideally, this logic should not be here;
22466 instead, there should be some programmatic way of inquiring as
22467 to whether or not an object is a vtable. */
22469 #define VTABLE_NAME_P(NAME) \
22470 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22471 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22472 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22473 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22474 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22476 #ifdef NO_DOLLAR_IN_LABEL
22477 /* Return a GGC-allocated character string translating dollar signs in
22478 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22481 rs6000_xcoff_strip_dollar (const char *name)
22486 p = strchr (name, '$');
22488 if (p == 0 || p == name)
22491 len = strlen (name);
22492 strip = (char *) alloca (len + 1);
22493 strcpy (strip, name);
22494 p = strchr (strip, '$');
22498 p = strchr (p + 1, '$');
22501 return ggc_alloc_string (strip, len);
22506 rs6000_output_symbol_ref (FILE *file, rtx x)
22508 /* Currently C++ toc references to vtables can be emitted before it
22509 is decided whether the vtable is public or private. If this is
22510 the case, then the linker will eventually complain that there is
22511 a reference to an unknown section. Thus, for vtables only,
22512 we emit the TOC reference to reference the symbol and not the
22514 const char *name = XSTR (x, 0);
22516 if (VTABLE_NAME_P (name))
22518 RS6000_OUTPUT_BASENAME (file, name);
22521 assemble_name (file, name);
22524 /* Output a TOC entry. We derive the entry name from what is being
22528 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22531 const char *name = buf;
22533 HOST_WIDE_INT offset = 0;
22535 gcc_assert (!TARGET_NO_TOC);
22537 /* When the linker won't eliminate them, don't output duplicate
22538 TOC entries (this happens on AIX if there is any kind of TOC,
22539 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22541 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22543 struct toc_hash_struct *h;
22546 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22547 time because GGC is not initialized at that point. */
22548 if (toc_hash_table == NULL)
22549 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22550 toc_hash_eq, NULL);
22552 h = ggc_alloc_toc_hash_struct ();
22554 h->key_mode = mode;
22555 h->labelno = labelno;
22557 found = htab_find_slot (toc_hash_table, h, INSERT);
22558 if (*found == NULL)
22560 else /* This is indeed a duplicate.
22561 Set this label equal to that label. */
22563 fputs ("\t.set ", file);
22564 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22565 fprintf (file, "%d,", labelno);
22566 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22567 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22573 /* If we're going to put a double constant in the TOC, make sure it's
22574 aligned properly when strict alignment is on. */
22575 if (GET_CODE (x) == CONST_DOUBLE
22576 && STRICT_ALIGNMENT
22577 && GET_MODE_BITSIZE (mode) >= 64
22578 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22579 ASM_OUTPUT_ALIGN (file, 3);
22582 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22584 /* Handle FP constants specially. Note that if we have a minimal
22585 TOC, things we put here aren't actually in the TOC, so we can allow
22587 if (GET_CODE (x) == CONST_DOUBLE &&
22588 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22590 REAL_VALUE_TYPE rv;
22593 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22594 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22595 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22597 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22601 if (TARGET_MINIMAL_TOC)
22602 fputs (DOUBLE_INT_ASM_OP, file);
22604 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22605 k[0] & 0xffffffff, k[1] & 0xffffffff,
22606 k[2] & 0xffffffff, k[3] & 0xffffffff);
22607 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22608 k[0] & 0xffffffff, k[1] & 0xffffffff,
22609 k[2] & 0xffffffff, k[3] & 0xffffffff);
22614 if (TARGET_MINIMAL_TOC)
22615 fputs ("\t.long ", file);
22617 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22618 k[0] & 0xffffffff, k[1] & 0xffffffff,
22619 k[2] & 0xffffffff, k[3] & 0xffffffff);
22620 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22621 k[0] & 0xffffffff, k[1] & 0xffffffff,
22622 k[2] & 0xffffffff, k[3] & 0xffffffff);
22626 else if (GET_CODE (x) == CONST_DOUBLE &&
22627 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22629 REAL_VALUE_TYPE rv;
22632 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22634 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22635 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22637 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22641 if (TARGET_MINIMAL_TOC)
22642 fputs (DOUBLE_INT_ASM_OP, file);
22644 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22645 k[0] & 0xffffffff, k[1] & 0xffffffff);
22646 fprintf (file, "0x%lx%08lx\n",
22647 k[0] & 0xffffffff, k[1] & 0xffffffff);
22652 if (TARGET_MINIMAL_TOC)
22653 fputs ("\t.long ", file);
22655 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22656 k[0] & 0xffffffff, k[1] & 0xffffffff);
22657 fprintf (file, "0x%lx,0x%lx\n",
22658 k[0] & 0xffffffff, k[1] & 0xffffffff);
22662 else if (GET_CODE (x) == CONST_DOUBLE &&
22663 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22665 REAL_VALUE_TYPE rv;
22668 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22669 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22670 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22672 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22676 if (TARGET_MINIMAL_TOC)
22677 fputs (DOUBLE_INT_ASM_OP, file);
22679 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22680 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22685 if (TARGET_MINIMAL_TOC)
22686 fputs ("\t.long ", file);
22688 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22689 fprintf (file, "0x%lx\n", l & 0xffffffff);
22693 else if (GET_MODE (x) == VOIDmode
22694 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22696 unsigned HOST_WIDE_INT low;
22697 HOST_WIDE_INT high;
22699 if (GET_CODE (x) == CONST_DOUBLE)
22701 low = CONST_DOUBLE_LOW (x);
22702 high = CONST_DOUBLE_HIGH (x);
22705 #if HOST_BITS_PER_WIDE_INT == 32
22708 high = (low & 0x80000000) ? ~0 : 0;
22712 low = INTVAL (x) & 0xffffffff;
22713 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22717 /* TOC entries are always Pmode-sized, but since this
22718 is a bigendian machine then if we're putting smaller
22719 integer constants in the TOC we have to pad them.
22720 (This is still a win over putting the constants in
22721 a separate constant pool, because then we'd have
22722 to have both a TOC entry _and_ the actual constant.)
22724 For a 32-bit target, CONST_INT values are loaded and shifted
22725 entirely within `low' and can be stored in one TOC entry. */
22727 /* It would be easy to make this work, but it doesn't now. */
22728 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22730 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22732 #if HOST_BITS_PER_WIDE_INT == 32
22733 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22734 POINTER_SIZE, &low, &high, 0);
22737 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22738 high = (HOST_WIDE_INT) low >> 32;
22745 if (TARGET_MINIMAL_TOC)
22746 fputs (DOUBLE_INT_ASM_OP, file);
22748 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22749 (long) high & 0xffffffff, (long) low & 0xffffffff);
22750 fprintf (file, "0x%lx%08lx\n",
22751 (long) high & 0xffffffff, (long) low & 0xffffffff);
22756 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22758 if (TARGET_MINIMAL_TOC)
22759 fputs ("\t.long ", file);
22761 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22762 (long) high & 0xffffffff, (long) low & 0xffffffff);
22763 fprintf (file, "0x%lx,0x%lx\n",
22764 (long) high & 0xffffffff, (long) low & 0xffffffff);
22768 if (TARGET_MINIMAL_TOC)
22769 fputs ("\t.long ", file);
22771 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22772 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22778 if (GET_CODE (x) == CONST)
22780 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22781 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22783 base = XEXP (XEXP (x, 0), 0);
22784 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22787 switch (GET_CODE (base))
22790 name = XSTR (base, 0);
22794 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22795 CODE_LABEL_NUMBER (XEXP (base, 0)));
22799 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22803 gcc_unreachable ();
22806 if (TARGET_MINIMAL_TOC)
22807 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22810 fputs ("\t.tc ", file);
22811 RS6000_OUTPUT_BASENAME (file, name);
22814 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22816 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22818 fputs ("[TC],", file);
22821 /* Currently C++ toc references to vtables can be emitted before it
22822 is decided whether the vtable is public or private. If this is
22823 the case, then the linker will eventually complain that there is
22824 a TOC reference to an unknown section. Thus, for vtables only,
22825 we emit the TOC reference to reference the symbol and not the
22827 if (VTABLE_NAME_P (name))
22829 RS6000_OUTPUT_BASENAME (file, name);
22831 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22832 else if (offset > 0)
22833 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22836 output_addr_const (file, x);
22840 /* Output an assembler pseudo-op to write an ASCII string of N characters
22841 starting at P to FILE.
22843 On the RS/6000, we have to do this using the .byte operation and
22844 write out special characters outside the quoted string.
22845 Also, the assembler is broken; very long strings are truncated,
22846 so we must artificially break them up early. */
22849 output_ascii (FILE *file, const char *p, int n)
22852 int i, count_string;
22853 const char *for_string = "\t.byte \"";
22854 const char *for_decimal = "\t.byte ";
22855 const char *to_close = NULL;
22858 for (i = 0; i < n; i++)
22861 if (c >= ' ' && c < 0177)
22864 fputs (for_string, file);
22867 /* Write two quotes to get one. */
22875 for_decimal = "\"\n\t.byte ";
22879 if (count_string >= 512)
22881 fputs (to_close, file);
22883 for_string = "\t.byte \"";
22884 for_decimal = "\t.byte ";
22892 fputs (for_decimal, file);
22893 fprintf (file, "%d", c);
22895 for_string = "\n\t.byte \"";
22896 for_decimal = ", ";
22902 /* Now close the string if we have written one. Then end the line. */
22904 fputs (to_close, file);
22907 /* Generate a unique section name for FILENAME for a section type
22908 represented by SECTION_DESC. Output goes into BUF.
22910 SECTION_DESC can be any string, as long as it is different for each
22911 possible section type.
22913 We name the section in the same manner as xlc. The name begins with an
22914 underscore followed by the filename (after stripping any leading directory
22915 names) with the last period replaced by the string SECTION_DESC. If
22916 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22920 rs6000_gen_section_name (char **buf, const char *filename,
22921 const char *section_desc)
22923 const char *q, *after_last_slash, *last_period = 0;
22927 after_last_slash = filename;
22928 for (q = filename; *q; q++)
22931 after_last_slash = q + 1;
22932 else if (*q == '.')
22936 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22937 *buf = (char *) xmalloc (len);
22942 for (q = after_last_slash; *q; q++)
22944 if (q == last_period)
22946 strcpy (p, section_desc);
22947 p += strlen (section_desc);
22951 else if (ISALNUM (*q))
22955 if (last_period == 0)
22956 strcpy (p, section_desc);
22961 /* Emit profile function. */
22964 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22966 /* Non-standard profiling for kernels, which just saves LR then calls
22967 _mcount without worrying about arg saves. The idea is to change
22968 the function prologue as little as possible as it isn't easy to
22969 account for arg save/restore code added just for _mcount. */
22970 if (TARGET_PROFILE_KERNEL)
22973 if (DEFAULT_ABI == ABI_AIX)
22975 #ifndef NO_PROFILE_COUNTERS
22976 # define NO_PROFILE_COUNTERS 0
22978 if (NO_PROFILE_COUNTERS)
22979 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22980 LCT_NORMAL, VOIDmode, 0);
22984 const char *label_name;
22987 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22988 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22989 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22991 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22992 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22995 else if (DEFAULT_ABI == ABI_DARWIN)
22997 const char *mcount_name = RS6000_MCOUNT;
22998 int caller_addr_regno = LR_REGNO;
23000 /* Be conservative and always set this, at least for now. */
23001 crtl->uses_pic_offset_table = 1;
23004 /* For PIC code, set up a stub and collect the caller's address
23005 from r0, which is where the prologue puts it. */
23006 if (MACHOPIC_INDIRECT
23007 && crtl->uses_pic_offset_table)
23008 caller_addr_regno = 0;
23010 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
23011 LCT_NORMAL, VOIDmode, 1,
23012 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
23016 /* Write function profiler code. */
23019 output_function_profiler (FILE *file, int labelno)
23023 switch (DEFAULT_ABI)
23026 gcc_unreachable ();
23031 warning (0, "no profiling of 64-bit code for this ABI");
23034 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23035 fprintf (file, "\tmflr %s\n", reg_names[0]);
23036 if (NO_PROFILE_COUNTERS)
23038 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23039 reg_names[0], reg_names[1]);
23041 else if (TARGET_SECURE_PLT && flag_pic)
23043 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23044 reg_names[0], reg_names[1]);
23045 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23046 asm_fprintf (file, "\t{cau|addis} %s,%s,",
23047 reg_names[12], reg_names[12]);
23048 assemble_name (file, buf);
23049 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
23050 assemble_name (file, buf);
23051 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
23053 else if (flag_pic == 1)
23055 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
23056 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23057 reg_names[0], reg_names[1]);
23058 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23059 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
23060 assemble_name (file, buf);
23061 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
23063 else if (flag_pic > 1)
23065 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23066 reg_names[0], reg_names[1]);
23067 /* Now, we need to get the address of the label. */
23068 fputs ("\tbcl 20,31,1f\n\t.long ", file);
23069 assemble_name (file, buf);
23070 fputs ("-.\n1:", file);
23071 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
23072 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
23073 reg_names[0], reg_names[11]);
23074 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23075 reg_names[0], reg_names[0], reg_names[11]);
23079 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23080 assemble_name (file, buf);
23081 fputs ("@ha\n", file);
23082 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23083 reg_names[0], reg_names[1]);
23084 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23085 assemble_name (file, buf);
23086 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23089 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23090 fprintf (file, "\tbl %s%s\n",
23091 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23096 if (!TARGET_PROFILE_KERNEL)
23098 /* Don't do anything, done in output_profile_hook (). */
23102 gcc_assert (!TARGET_32BIT);
23104 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23105 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23107 if (cfun->static_chain_decl != NULL)
23109 asm_fprintf (file, "\tstd %s,24(%s)\n",
23110 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23111 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23112 asm_fprintf (file, "\tld %s,24(%s)\n",
23113 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23116 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23124 /* The following variable value is the last issued insn. */
23126 static rtx last_scheduled_insn;
23128 /* The following variable helps to balance issuing of load and
23129 store instructions */
23131 static int load_store_pendulum;
23133 /* Power4 load update and store update instructions are cracked into a
23134 load or store and an integer insn which are executed in the same cycle.
23135 Branches have their own dispatch slot which does not count against the
23136 GCC issue rate, but it changes the program flow so there are no other
23137 instructions to issue in this cycle. */
23140 rs6000_variable_issue_1 (rtx insn, int more)
23142 last_scheduled_insn = insn;
23143 if (GET_CODE (PATTERN (insn)) == USE
23144 || GET_CODE (PATTERN (insn)) == CLOBBER)
23146 cached_can_issue_more = more;
23147 return cached_can_issue_more;
23150 if (insn_terminates_group_p (insn, current_group))
23152 cached_can_issue_more = 0;
23153 return cached_can_issue_more;
23156 /* If no reservation, but reach here */
23157 if (recog_memoized (insn) < 0)
23160 if (rs6000_sched_groups)
23162 if (is_microcoded_insn (insn))
23163 cached_can_issue_more = 0;
23164 else if (is_cracked_insn (insn))
23165 cached_can_issue_more = more > 2 ? more - 2 : 0;
23167 cached_can_issue_more = more - 1;
23169 return cached_can_issue_more;
23172 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23175 cached_can_issue_more = more - 1;
23176 return cached_can_issue_more;
23180 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23182 int r = rs6000_variable_issue_1 (insn, more);
23184 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23188 /* Adjust the cost of a scheduling dependency. Return the new cost of
23189 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23192 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23194 enum attr_type attr_type;
23196 if (! recog_memoized (insn))
23199 switch (REG_NOTE_KIND (link))
23203 /* Data dependency; DEP_INSN writes a register that INSN reads
23204 some cycles later. */
23206 /* Separate a load from a narrower, dependent store. */
23207 if (rs6000_sched_groups
23208 && GET_CODE (PATTERN (insn)) == SET
23209 && GET_CODE (PATTERN (dep_insn)) == SET
23210 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23211 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23212 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23213 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23216 attr_type = get_attr_type (insn);
23221 /* Tell the first scheduling pass about the latency between
23222 a mtctr and bctr (and mtlr and br/blr). The first
23223 scheduling pass will not know about this latency since
23224 the mtctr instruction, which has the latency associated
23225 to it, will be generated by reload. */
23226 return TARGET_POWER ? 5 : 4;
23228 /* Leave some extra cycles between a compare and its
23229 dependent branch, to inhibit expensive mispredicts. */
23230 if ((rs6000_cpu_attr == CPU_PPC603
23231 || rs6000_cpu_attr == CPU_PPC604
23232 || rs6000_cpu_attr == CPU_PPC604E
23233 || rs6000_cpu_attr == CPU_PPC620
23234 || rs6000_cpu_attr == CPU_PPC630
23235 || rs6000_cpu_attr == CPU_PPC750
23236 || rs6000_cpu_attr == CPU_PPC7400
23237 || rs6000_cpu_attr == CPU_PPC7450
23238 || rs6000_cpu_attr == CPU_POWER4
23239 || rs6000_cpu_attr == CPU_POWER5
23240 || rs6000_cpu_attr == CPU_POWER7
23241 || rs6000_cpu_attr == CPU_CELL)
23242 && recog_memoized (dep_insn)
23243 && (INSN_CODE (dep_insn) >= 0))
23245 switch (get_attr_type (dep_insn))
23249 case TYPE_DELAYED_COMPARE:
23250 case TYPE_IMUL_COMPARE:
23251 case TYPE_LMUL_COMPARE:
23252 case TYPE_FPCOMPARE:
23253 case TYPE_CR_LOGICAL:
23254 case TYPE_DELAYED_CR:
23263 case TYPE_STORE_UX:
23265 case TYPE_FPSTORE_U:
23266 case TYPE_FPSTORE_UX:
23267 if ((rs6000_cpu == PROCESSOR_POWER6)
23268 && recog_memoized (dep_insn)
23269 && (INSN_CODE (dep_insn) >= 0))
23272 if (GET_CODE (PATTERN (insn)) != SET)
23273 /* If this happens, we have to extend this to schedule
23274 optimally. Return default for now. */
23277 /* Adjust the cost for the case where the value written
23278 by a fixed point operation is used as the address
23279 gen value on a store. */
23280 switch (get_attr_type (dep_insn))
23287 if (! store_data_bypass_p (dep_insn, insn))
23291 case TYPE_LOAD_EXT:
23292 case TYPE_LOAD_EXT_U:
23293 case TYPE_LOAD_EXT_UX:
23294 case TYPE_VAR_SHIFT_ROTATE:
23295 case TYPE_VAR_DELAYED_COMPARE:
23297 if (! store_data_bypass_p (dep_insn, insn))
23303 case TYPE_FAST_COMPARE:
23306 case TYPE_INSERT_WORD:
23307 case TYPE_INSERT_DWORD:
23308 case TYPE_FPLOAD_U:
23309 case TYPE_FPLOAD_UX:
23311 case TYPE_STORE_UX:
23312 case TYPE_FPSTORE_U:
23313 case TYPE_FPSTORE_UX:
23315 if (! store_data_bypass_p (dep_insn, insn))
23323 case TYPE_IMUL_COMPARE:
23324 case TYPE_LMUL_COMPARE:
23326 if (! store_data_bypass_p (dep_insn, insn))
23332 if (! store_data_bypass_p (dep_insn, insn))
23338 if (! store_data_bypass_p (dep_insn, insn))
23351 case TYPE_LOAD_EXT:
23352 case TYPE_LOAD_EXT_U:
23353 case TYPE_LOAD_EXT_UX:
23354 if ((rs6000_cpu == PROCESSOR_POWER6)
23355 && recog_memoized (dep_insn)
23356 && (INSN_CODE (dep_insn) >= 0))
23359 /* Adjust the cost for the case where the value written
23360 by a fixed point instruction is used within the address
23361 gen portion of a subsequent load(u)(x) */
23362 switch (get_attr_type (dep_insn))
23369 if (set_to_load_agen (dep_insn, insn))
23373 case TYPE_LOAD_EXT:
23374 case TYPE_LOAD_EXT_U:
23375 case TYPE_LOAD_EXT_UX:
23376 case TYPE_VAR_SHIFT_ROTATE:
23377 case TYPE_VAR_DELAYED_COMPARE:
23379 if (set_to_load_agen (dep_insn, insn))
23385 case TYPE_FAST_COMPARE:
23388 case TYPE_INSERT_WORD:
23389 case TYPE_INSERT_DWORD:
23390 case TYPE_FPLOAD_U:
23391 case TYPE_FPLOAD_UX:
23393 case TYPE_STORE_UX:
23394 case TYPE_FPSTORE_U:
23395 case TYPE_FPSTORE_UX:
23397 if (set_to_load_agen (dep_insn, insn))
23405 case TYPE_IMUL_COMPARE:
23406 case TYPE_LMUL_COMPARE:
23408 if (set_to_load_agen (dep_insn, insn))
23414 if (set_to_load_agen (dep_insn, insn))
23420 if (set_to_load_agen (dep_insn, insn))
23431 if ((rs6000_cpu == PROCESSOR_POWER6)
23432 && recog_memoized (dep_insn)
23433 && (INSN_CODE (dep_insn) >= 0)
23434 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23441 /* Fall out to return default cost. */
23445 case REG_DEP_OUTPUT:
23446 /* Output dependency; DEP_INSN writes a register that INSN writes some
23448 if ((rs6000_cpu == PROCESSOR_POWER6)
23449 && recog_memoized (dep_insn)
23450 && (INSN_CODE (dep_insn) >= 0))
23452 attr_type = get_attr_type (insn);
23457 if (get_attr_type (dep_insn) == TYPE_FP)
23461 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23469 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23474 gcc_unreachable ();
23480 /* Debug version of rs6000_adjust_cost. */
23483 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23485 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23491 switch (REG_NOTE_KIND (link))
23493 default: dep = "unknown depencency"; break;
23494 case REG_DEP_TRUE: dep = "data dependency"; break;
23495 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23496 case REG_DEP_ANTI: dep = "anti depencency"; break;
23500 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23501 "%s, insn:\n", ret, cost, dep);
23509 /* The function returns a true if INSN is microcoded.
23510 Return false otherwise. */
23513 is_microcoded_insn (rtx insn)
23515 if (!insn || !NONDEBUG_INSN_P (insn)
23516 || GET_CODE (PATTERN (insn)) == USE
23517 || GET_CODE (PATTERN (insn)) == CLOBBER)
23520 if (rs6000_cpu_attr == CPU_CELL)
23521 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23523 if (rs6000_sched_groups)
23525 enum attr_type type = get_attr_type (insn);
23526 if (type == TYPE_LOAD_EXT_U
23527 || type == TYPE_LOAD_EXT_UX
23528 || type == TYPE_LOAD_UX
23529 || type == TYPE_STORE_UX
23530 || type == TYPE_MFCR)
23537 /* The function returns true if INSN is cracked into 2 instructions
23538 by the processor (and therefore occupies 2 issue slots). */
23541 is_cracked_insn (rtx insn)
23543 if (!insn || !NONDEBUG_INSN_P (insn)
23544 || GET_CODE (PATTERN (insn)) == USE
23545 || GET_CODE (PATTERN (insn)) == CLOBBER)
23548 if (rs6000_sched_groups)
23550 enum attr_type type = get_attr_type (insn);
23551 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23552 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23553 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23554 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23555 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23556 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23557 || type == TYPE_IDIV || type == TYPE_LDIV
23558 || type == TYPE_INSERT_WORD)
23565 /* The function returns true if INSN can be issued only from
23566 the branch slot. */
23569 is_branch_slot_insn (rtx insn)
23571 if (!insn || !NONDEBUG_INSN_P (insn)
23572 || GET_CODE (PATTERN (insn)) == USE
23573 || GET_CODE (PATTERN (insn)) == CLOBBER)
23576 if (rs6000_sched_groups)
23578 enum attr_type type = get_attr_type (insn);
23579 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23587 /* The function returns true if out_inst sets a value that is
23588 used in the address generation computation of in_insn */
23590 set_to_load_agen (rtx out_insn, rtx in_insn)
23592 rtx out_set, in_set;
23594 /* For performance reasons, only handle the simple case where
23595 both loads are a single_set. */
23596 out_set = single_set (out_insn);
23599 in_set = single_set (in_insn);
23601 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23607 /* The function returns true if the target storage location of
23608 out_insn is adjacent to the target storage location of in_insn */
23609 /* Return 1 if memory locations are adjacent. */
23612 adjacent_mem_locations (rtx insn1, rtx insn2)
23615 rtx a = get_store_dest (PATTERN (insn1));
23616 rtx b = get_store_dest (PATTERN (insn2));
23618 if ((GET_CODE (XEXP (a, 0)) == REG
23619 || (GET_CODE (XEXP (a, 0)) == PLUS
23620 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23621 && (GET_CODE (XEXP (b, 0)) == REG
23622 || (GET_CODE (XEXP (b, 0)) == PLUS
23623 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23625 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23628 if (GET_CODE (XEXP (a, 0)) == PLUS)
23630 reg0 = XEXP (XEXP (a, 0), 0);
23631 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23634 reg0 = XEXP (a, 0);
23636 if (GET_CODE (XEXP (b, 0)) == PLUS)
23638 reg1 = XEXP (XEXP (b, 0), 0);
23639 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23642 reg1 = XEXP (b, 0);
23644 val_diff = val1 - val0;
23646 return ((REGNO (reg0) == REGNO (reg1))
23647 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23648 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23654 /* A C statement (sans semicolon) to update the integer scheduling
23655 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23656 INSN earlier, reduce the priority to execute INSN later. Do not
23657 define this macro if you do not need to adjust the scheduling
23658 priorities of insns. */
23661 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23663 /* On machines (like the 750) which have asymmetric integer units,
23664 where one integer unit can do multiply and divides and the other
23665 can't, reduce the priority of multiply/divide so it is scheduled
23666 before other integer operations. */
23669 if (! INSN_P (insn))
23672 if (GET_CODE (PATTERN (insn)) == USE)
23675 switch (rs6000_cpu_attr) {
23677 switch (get_attr_type (insn))
23684 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23685 priority, priority);
23686 if (priority >= 0 && priority < 0x01000000)
23693 if (insn_must_be_first_in_group (insn)
23694 && reload_completed
23695 && current_sched_info->sched_max_insns_priority
23696 && rs6000_sched_restricted_insns_priority)
23699 /* Prioritize insns that can be dispatched only in the first
23701 if (rs6000_sched_restricted_insns_priority == 1)
23702 /* Attach highest priority to insn. This means that in
23703 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23704 precede 'priority' (critical path) considerations. */
23705 return current_sched_info->sched_max_insns_priority;
23706 else if (rs6000_sched_restricted_insns_priority == 2)
23707 /* Increase priority of insn by a minimal amount. This means that in
23708 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23709 considerations precede dispatch-slot restriction considerations. */
23710 return (priority + 1);
23713 if (rs6000_cpu == PROCESSOR_POWER6
23714 && ((load_store_pendulum == -2 && is_load_insn (insn))
23715 || (load_store_pendulum == 2 && is_store_insn (insn))))
23716 /* Attach highest priority to insn if the scheduler has just issued two
23717 stores and this instruction is a load, or two loads and this instruction
23718 is a store. Power6 wants loads and stores scheduled alternately
23720 return current_sched_info->sched_max_insns_priority;
23725 /* Return true if the instruction is nonpipelined on the Cell. */
23727 is_nonpipeline_insn (rtx insn)
23729 enum attr_type type;
23730 if (!insn || !NONDEBUG_INSN_P (insn)
23731 || GET_CODE (PATTERN (insn)) == USE
23732 || GET_CODE (PATTERN (insn)) == CLOBBER)
23735 type = get_attr_type (insn);
23736 if (type == TYPE_IMUL
23737 || type == TYPE_IMUL2
23738 || type == TYPE_IMUL3
23739 || type == TYPE_LMUL
23740 || type == TYPE_IDIV
23741 || type == TYPE_LDIV
23742 || type == TYPE_SDIV
23743 || type == TYPE_DDIV
23744 || type == TYPE_SSQRT
23745 || type == TYPE_DSQRT
23746 || type == TYPE_MFCR
23747 || type == TYPE_MFCRF
23748 || type == TYPE_MFJMPR)
23756 /* Return how many instructions the machine can issue per cycle. */
23759 rs6000_issue_rate (void)
23761 /* Unless scheduling for register pressure, use issue rate of 1 for
23762 first scheduling pass to decrease degradation. */
23763 if (!reload_completed && !flag_sched_pressure)
23766 switch (rs6000_cpu_attr) {
23767 case CPU_RIOS1: /* ? */
23769 case CPU_PPC601: /* ? */
23778 case CPU_PPCE300C2:
23779 case CPU_PPCE300C3:
23780 case CPU_PPCE500MC:
23781 case CPU_PPCE500MC64:
23801 /* Return how many instructions to look ahead for better insn
23805 rs6000_use_sched_lookahead (void)
23807 if (rs6000_cpu_attr == CPU_PPC8540)
23809 if (rs6000_cpu_attr == CPU_CELL)
23810 return (reload_completed ? 8 : 0);
23814 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23816 rs6000_use_sched_lookahead_guard (rtx insn)
23818 if (rs6000_cpu_attr != CPU_CELL)
23821 if (insn == NULL_RTX || !INSN_P (insn))
23824 if (!reload_completed
23825 || is_nonpipeline_insn (insn)
23826 || is_microcoded_insn (insn))
23832 /* Determine is PAT refers to memory. */
23835 is_mem_ref (rtx pat)
23841 /* stack_tie does not produce any real memory traffic. */
23842 if (GET_CODE (pat) == UNSPEC
23843 && XINT (pat, 1) == UNSPEC_TIE)
23846 if (GET_CODE (pat) == MEM)
23849 /* Recursively process the pattern. */
23850 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23852 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23855 ret |= is_mem_ref (XEXP (pat, i));
23856 else if (fmt[i] == 'E')
23857 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23858 ret |= is_mem_ref (XVECEXP (pat, i, j));
23864 /* Determine if PAT is a PATTERN of a load insn. */
23867 is_load_insn1 (rtx pat)
23869 if (!pat || pat == NULL_RTX)
23872 if (GET_CODE (pat) == SET)
23873 return is_mem_ref (SET_SRC (pat));
23875 if (GET_CODE (pat) == PARALLEL)
23879 for (i = 0; i < XVECLEN (pat, 0); i++)
23880 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23887 /* Determine if INSN loads from memory. */
23890 is_load_insn (rtx insn)
23892 if (!insn || !INSN_P (insn))
23895 if (GET_CODE (insn) == CALL_INSN)
23898 return is_load_insn1 (PATTERN (insn));
23901 /* Determine if PAT is a PATTERN of a store insn. */
23904 is_store_insn1 (rtx pat)
23906 if (!pat || pat == NULL_RTX)
23909 if (GET_CODE (pat) == SET)
23910 return is_mem_ref (SET_DEST (pat));
23912 if (GET_CODE (pat) == PARALLEL)
23916 for (i = 0; i < XVECLEN (pat, 0); i++)
23917 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23924 /* Determine if INSN stores to memory. */
23927 is_store_insn (rtx insn)
23929 if (!insn || !INSN_P (insn))
23932 return is_store_insn1 (PATTERN (insn));
23935 /* Return the dest of a store insn. */
23938 get_store_dest (rtx pat)
23940 gcc_assert (is_store_insn1 (pat));
23942 if (GET_CODE (pat) == SET)
23943 return SET_DEST (pat);
23944 else if (GET_CODE (pat) == PARALLEL)
23948 for (i = 0; i < XVECLEN (pat, 0); i++)
23950 rtx inner_pat = XVECEXP (pat, 0, i);
23951 if (GET_CODE (inner_pat) == SET
23952 && is_mem_ref (SET_DEST (inner_pat)))
23956 /* We shouldn't get here, because we should have either a simple
23957 store insn or a store with update which are covered above. */
23961 /* Returns whether the dependence between INSN and NEXT is considered
23962 costly by the given target. */
23965 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23970 /* If the flag is not enabled - no dependence is considered costly;
23971 allow all dependent insns in the same group.
23972 This is the most aggressive option. */
23973 if (rs6000_sched_costly_dep == no_dep_costly)
23976 /* If the flag is set to 1 - a dependence is always considered costly;
23977 do not allow dependent instructions in the same group.
23978 This is the most conservative option. */
23979 if (rs6000_sched_costly_dep == all_deps_costly)
23982 insn = DEP_PRO (dep);
23983 next = DEP_CON (dep);
23985 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23986 && is_load_insn (next)
23987 && is_store_insn (insn))
23988 /* Prevent load after store in the same group. */
23991 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23992 && is_load_insn (next)
23993 && is_store_insn (insn)
23994 && DEP_TYPE (dep) == REG_DEP_TRUE)
23995 /* Prevent load after store in the same group if it is a true
23999 /* The flag is set to X; dependences with latency >= X are considered costly,
24000 and will not be scheduled in the same group. */
24001 if (rs6000_sched_costly_dep <= max_dep_latency
24002 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
24008 /* Return the next insn after INSN that is found before TAIL is reached,
24009 skipping any "non-active" insns - insns that will not actually occupy
24010 an issue slot. Return NULL_RTX if such an insn is not found. */
24013 get_next_active_insn (rtx insn, rtx tail)
24015 if (insn == NULL_RTX || insn == tail)
24020 insn = NEXT_INSN (insn);
24021 if (insn == NULL_RTX || insn == tail)
24026 || (NONJUMP_INSN_P (insn)
24027 && GET_CODE (PATTERN (insn)) != USE
24028 && GET_CODE (PATTERN (insn)) != CLOBBER
24029 && INSN_CODE (insn) != CODE_FOR_stack_tie))
24035 /* We are about to begin issuing insns for this clock cycle. */
24038 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
24039 rtx *ready ATTRIBUTE_UNUSED,
24040 int *pn_ready ATTRIBUTE_UNUSED,
24041 int clock_var ATTRIBUTE_UNUSED)
24043 int n_ready = *pn_ready;
24046 fprintf (dump, "// rs6000_sched_reorder :\n");
24048 /* Reorder the ready list, if the second to last ready insn
24049 is a nonepipeline insn. */
24050 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
24052 if (is_nonpipeline_insn (ready[n_ready - 1])
24053 && (recog_memoized (ready[n_ready - 2]) > 0))
24054 /* Simply swap first two insns. */
24056 rtx tmp = ready[n_ready - 1];
24057 ready[n_ready - 1] = ready[n_ready - 2];
24058 ready[n_ready - 2] = tmp;
24062 if (rs6000_cpu == PROCESSOR_POWER6)
24063 load_store_pendulum = 0;
24065 return rs6000_issue_rate ();
24068 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24071 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
24072 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24075 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24077 /* For Power6, we need to handle some special cases to try and keep the
24078 store queue from overflowing and triggering expensive flushes.
24080 This code monitors how load and store instructions are being issued
24081 and skews the ready list one way or the other to increase the likelihood
24082 that a desired instruction is issued at the proper time.
24084 A couple of things are done. First, we maintain a "load_store_pendulum"
24085 to track the current state of load/store issue.
24087 - If the pendulum is at zero, then no loads or stores have been
24088 issued in the current cycle so we do nothing.
24090 - If the pendulum is 1, then a single load has been issued in this
24091 cycle and we attempt to locate another load in the ready list to
24094 - If the pendulum is -2, then two stores have already been
24095 issued in this cycle, so we increase the priority of the first load
24096 in the ready list to increase it's likelihood of being chosen first
24099 - If the pendulum is -1, then a single store has been issued in this
24100 cycle and we attempt to locate another store in the ready list to
24101 issue with it, preferring a store to an adjacent memory location to
24102 facilitate store pairing in the store queue.
24104 - If the pendulum is 2, then two loads have already been
24105 issued in this cycle, so we increase the priority of the first store
24106 in the ready list to increase it's likelihood of being chosen first
24109 - If the pendulum < -2 or > 2, then do nothing.
24111 Note: This code covers the most common scenarios. There exist non
24112 load/store instructions which make use of the LSU and which
24113 would need to be accounted for to strictly model the behavior
24114 of the machine. Those instructions are currently unaccounted
24115 for to help minimize compile time overhead of this code.
24117 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24123 if (is_store_insn (last_scheduled_insn))
24124 /* Issuing a store, swing the load_store_pendulum to the left */
24125 load_store_pendulum--;
24126 else if (is_load_insn (last_scheduled_insn))
24127 /* Issuing a load, swing the load_store_pendulum to the right */
24128 load_store_pendulum++;
24130 return cached_can_issue_more;
24132 /* If the pendulum is balanced, or there is only one instruction on
24133 the ready list, then all is well, so return. */
24134 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24135 return cached_can_issue_more;
24137 if (load_store_pendulum == 1)
24139 /* A load has been issued in this cycle. Scan the ready list
24140 for another load to issue with it */
24145 if (is_load_insn (ready[pos]))
24147 /* Found a load. Move it to the head of the ready list,
24148 and adjust it's priority so that it is more likely to
24151 for (i=pos; i<*pn_ready-1; i++)
24152 ready[i] = ready[i + 1];
24153 ready[*pn_ready-1] = tmp;
24155 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24156 INSN_PRIORITY (tmp)++;
24162 else if (load_store_pendulum == -2)
24164 /* Two stores have been issued in this cycle. Increase the
24165 priority of the first load in the ready list to favor it for
24166 issuing in the next cycle. */
24171 if (is_load_insn (ready[pos])
24173 && INSN_PRIORITY_KNOWN (ready[pos]))
24175 INSN_PRIORITY (ready[pos])++;
24177 /* Adjust the pendulum to account for the fact that a load
24178 was found and increased in priority. This is to prevent
24179 increasing the priority of multiple loads */
24180 load_store_pendulum--;
24187 else if (load_store_pendulum == -1)
24189 /* A store has been issued in this cycle. Scan the ready list for
24190 another store to issue with it, preferring a store to an adjacent
24192 int first_store_pos = -1;
24198 if (is_store_insn (ready[pos]))
24200 /* Maintain the index of the first store found on the
24202 if (first_store_pos == -1)
24203 first_store_pos = pos;
24205 if (is_store_insn (last_scheduled_insn)
24206 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24208 /* Found an adjacent store. Move it to the head of the
24209 ready list, and adjust it's priority so that it is
24210 more likely to stay there */
24212 for (i=pos; i<*pn_ready-1; i++)
24213 ready[i] = ready[i + 1];
24214 ready[*pn_ready-1] = tmp;
24216 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24217 INSN_PRIORITY (tmp)++;
24219 first_store_pos = -1;
24227 if (first_store_pos >= 0)
24229 /* An adjacent store wasn't found, but a non-adjacent store was,
24230 so move the non-adjacent store to the front of the ready
24231 list, and adjust its priority so that it is more likely to
24233 tmp = ready[first_store_pos];
24234 for (i=first_store_pos; i<*pn_ready-1; i++)
24235 ready[i] = ready[i + 1];
24236 ready[*pn_ready-1] = tmp;
24237 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24238 INSN_PRIORITY (tmp)++;
24241 else if (load_store_pendulum == 2)
24243 /* Two loads have been issued in this cycle. Increase the priority
24244 of the first store in the ready list to favor it for issuing in
24250 if (is_store_insn (ready[pos])
24252 && INSN_PRIORITY_KNOWN (ready[pos]))
24254 INSN_PRIORITY (ready[pos])++;
24256 /* Adjust the pendulum to account for the fact that a store
24257 was found and increased in priority. This is to prevent
24258 increasing the priority of multiple stores */
24259 load_store_pendulum++;
24268 return cached_can_issue_more;
24271 /* Return whether the presence of INSN causes a dispatch group termination
24272 of group WHICH_GROUP.
24274 If WHICH_GROUP == current_group, this function will return true if INSN
24275 causes the termination of the current group (i.e, the dispatch group to
24276 which INSN belongs). This means that INSN will be the last insn in the
24277 group it belongs to.
24279 If WHICH_GROUP == previous_group, this function will return true if INSN
24280 causes the termination of the previous group (i.e, the dispatch group that
24281 precedes the group to which INSN belongs). This means that INSN will be
24282 the first insn in the group it belongs to). */
24285 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24292 first = insn_must_be_first_in_group (insn);
24293 last = insn_must_be_last_in_group (insn);
24298 if (which_group == current_group)
24300 else if (which_group == previous_group)
24308 insn_must_be_first_in_group (rtx insn)
24310 enum attr_type type;
24313 || GET_CODE (insn) == NOTE
24314 || DEBUG_INSN_P (insn)
24315 || GET_CODE (PATTERN (insn)) == USE
24316 || GET_CODE (PATTERN (insn)) == CLOBBER)
24319 switch (rs6000_cpu)
24321 case PROCESSOR_POWER5:
24322 if (is_cracked_insn (insn))
24324 case PROCESSOR_POWER4:
24325 if (is_microcoded_insn (insn))
24328 if (!rs6000_sched_groups)
24331 type = get_attr_type (insn);
24338 case TYPE_DELAYED_CR:
24339 case TYPE_CR_LOGICAL:
24353 case PROCESSOR_POWER6:
24354 type = get_attr_type (insn);
24358 case TYPE_INSERT_DWORD:
24362 case TYPE_VAR_SHIFT_ROTATE:
24369 case TYPE_INSERT_WORD:
24370 case TYPE_DELAYED_COMPARE:
24371 case TYPE_IMUL_COMPARE:
24372 case TYPE_LMUL_COMPARE:
24373 case TYPE_FPCOMPARE:
24384 case TYPE_LOAD_EXT_UX:
24386 case TYPE_STORE_UX:
24387 case TYPE_FPLOAD_U:
24388 case TYPE_FPLOAD_UX:
24389 case TYPE_FPSTORE_U:
24390 case TYPE_FPSTORE_UX:
24396 case PROCESSOR_POWER7:
24397 type = get_attr_type (insn);
24401 case TYPE_CR_LOGICAL:
24408 case TYPE_DELAYED_COMPARE:
24409 case TYPE_VAR_DELAYED_COMPARE:
24415 case TYPE_LOAD_EXT:
24416 case TYPE_LOAD_EXT_U:
24417 case TYPE_LOAD_EXT_UX:
24419 case TYPE_STORE_UX:
24420 case TYPE_FPLOAD_U:
24421 case TYPE_FPLOAD_UX:
24422 case TYPE_FPSTORE_U:
24423 case TYPE_FPSTORE_UX:
24439 insn_must_be_last_in_group (rtx insn)
24441 enum attr_type type;
24444 || GET_CODE (insn) == NOTE
24445 || DEBUG_INSN_P (insn)
24446 || GET_CODE (PATTERN (insn)) == USE
24447 || GET_CODE (PATTERN (insn)) == CLOBBER)
24450 switch (rs6000_cpu) {
24451 case PROCESSOR_POWER4:
24452 case PROCESSOR_POWER5:
24453 if (is_microcoded_insn (insn))
24456 if (is_branch_slot_insn (insn))
24460 case PROCESSOR_POWER6:
24461 type = get_attr_type (insn);
24468 case TYPE_VAR_SHIFT_ROTATE:
24475 case TYPE_DELAYED_COMPARE:
24476 case TYPE_IMUL_COMPARE:
24477 case TYPE_LMUL_COMPARE:
24478 case TYPE_FPCOMPARE:
24492 case PROCESSOR_POWER7:
24493 type = get_attr_type (insn);
24501 case TYPE_LOAD_EXT_U:
24502 case TYPE_LOAD_EXT_UX:
24503 case TYPE_STORE_UX:
24516 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24517 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24520 is_costly_group (rtx *group_insns, rtx next_insn)
24523 int issue_rate = rs6000_issue_rate ();
24525 for (i = 0; i < issue_rate; i++)
24527 sd_iterator_def sd_it;
24529 rtx insn = group_insns[i];
24534 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24536 rtx next = DEP_CON (dep);
24538 if (next == next_insn
24539 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24547 /* Utility of the function redefine_groups.
24548 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24549 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24550 to keep it "far" (in a separate group) from GROUP_INSNS, following
24551 one of the following schemes, depending on the value of the flag
24552 -minsert_sched_nops = X:
24553 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24554 in order to force NEXT_INSN into a separate group.
24555 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24556 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24557 insertion (has a group just ended, how many vacant issue slots remain in the
24558 last group, and how many dispatch groups were encountered so far). */
24561 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24562 rtx next_insn, bool *group_end, int can_issue_more,
24567 int issue_rate = rs6000_issue_rate ();
24568 bool end = *group_end;
24571 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24572 return can_issue_more;
24574 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24575 return can_issue_more;
24577 force = is_costly_group (group_insns, next_insn);
24579 return can_issue_more;
24581 if (sched_verbose > 6)
24582 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24583 *group_count ,can_issue_more);
24585 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24588 can_issue_more = 0;
24590 /* Since only a branch can be issued in the last issue_slot, it is
24591 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24592 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24593 in this case the last nop will start a new group and the branch
24594 will be forced to the new group. */
24595 if (can_issue_more && !is_branch_slot_insn (next_insn))
24598 while (can_issue_more > 0)
24601 emit_insn_before (nop, next_insn);
24609 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24611 int n_nops = rs6000_sched_insert_nops;
24613 /* Nops can't be issued from the branch slot, so the effective
24614 issue_rate for nops is 'issue_rate - 1'. */
24615 if (can_issue_more == 0)
24616 can_issue_more = issue_rate;
24618 if (can_issue_more == 0)
24620 can_issue_more = issue_rate - 1;
24623 for (i = 0; i < issue_rate; i++)
24625 group_insns[i] = 0;
24632 emit_insn_before (nop, next_insn);
24633 if (can_issue_more == issue_rate - 1) /* new group begins */
24636 if (can_issue_more == 0)
24638 can_issue_more = issue_rate - 1;
24641 for (i = 0; i < issue_rate; i++)
24643 group_insns[i] = 0;
24649 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24652 /* Is next_insn going to start a new group? */
24655 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24656 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24657 || (can_issue_more < issue_rate &&
24658 insn_terminates_group_p (next_insn, previous_group)));
24659 if (*group_end && end)
24662 if (sched_verbose > 6)
24663 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24664 *group_count, can_issue_more);
24665 return can_issue_more;
24668 return can_issue_more;
24671 /* This function tries to synch the dispatch groups that the compiler "sees"
24672 with the dispatch groups that the processor dispatcher is expected to
24673 form in practice. It tries to achieve this synchronization by forcing the
24674 estimated processor grouping on the compiler (as opposed to the function
24675 'pad_goups' which tries to force the scheduler's grouping on the processor).
24677 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24678 examines the (estimated) dispatch groups that will be formed by the processor
24679 dispatcher. It marks these group boundaries to reflect the estimated
24680 processor grouping, overriding the grouping that the scheduler had marked.
24681 Depending on the value of the flag '-minsert-sched-nops' this function can
24682 force certain insns into separate groups or force a certain distance between
24683 them by inserting nops, for example, if there exists a "costly dependence"
24686 The function estimates the group boundaries that the processor will form as
24687 follows: It keeps track of how many vacant issue slots are available after
24688 each insn. A subsequent insn will start a new group if one of the following
24690 - no more vacant issue slots remain in the current dispatch group.
24691 - only the last issue slot, which is the branch slot, is vacant, but the next
24692 insn is not a branch.
24693 - only the last 2 or less issue slots, including the branch slot, are vacant,
24694 which means that a cracked insn (which occupies two issue slots) can't be
24695 issued in this group.
24696 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24697 start a new group. */
24700 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24702 rtx insn, next_insn;
24704 int can_issue_more;
24707 int group_count = 0;
24711 issue_rate = rs6000_issue_rate ();
24712 group_insns = XALLOCAVEC (rtx, issue_rate);
24713 for (i = 0; i < issue_rate; i++)
24715 group_insns[i] = 0;
24717 can_issue_more = issue_rate;
24719 insn = get_next_active_insn (prev_head_insn, tail);
24722 while (insn != NULL_RTX)
24724 slot = (issue_rate - can_issue_more);
24725 group_insns[slot] = insn;
24727 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24728 if (insn_terminates_group_p (insn, current_group))
24729 can_issue_more = 0;
24731 next_insn = get_next_active_insn (insn, tail);
24732 if (next_insn == NULL_RTX)
24733 return group_count + 1;
24735 /* Is next_insn going to start a new group? */
24737 = (can_issue_more == 0
24738 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24739 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24740 || (can_issue_more < issue_rate &&
24741 insn_terminates_group_p (next_insn, previous_group)));
24743 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24744 next_insn, &group_end, can_issue_more,
24750 can_issue_more = 0;
24751 for (i = 0; i < issue_rate; i++)
24753 group_insns[i] = 0;
24757 if (GET_MODE (next_insn) == TImode && can_issue_more)
24758 PUT_MODE (next_insn, VOIDmode);
24759 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24760 PUT_MODE (next_insn, TImode);
24763 if (can_issue_more == 0)
24764 can_issue_more = issue_rate;
24767 return group_count;
24770 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24771 dispatch group boundaries that the scheduler had marked. Pad with nops
24772 any dispatch groups which have vacant issue slots, in order to force the
24773 scheduler's grouping on the processor dispatcher. The function
24774 returns the number of dispatch groups found. */
24777 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24779 rtx insn, next_insn;
24782 int can_issue_more;
24784 int group_count = 0;
24786 /* Initialize issue_rate. */
24787 issue_rate = rs6000_issue_rate ();
24788 can_issue_more = issue_rate;
24790 insn = get_next_active_insn (prev_head_insn, tail);
24791 next_insn = get_next_active_insn (insn, tail);
24793 while (insn != NULL_RTX)
24796 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24798 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24800 if (next_insn == NULL_RTX)
24805 /* If the scheduler had marked group termination at this location
24806 (between insn and next_insn), and neither insn nor next_insn will
24807 force group termination, pad the group with nops to force group
24810 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24811 && !insn_terminates_group_p (insn, current_group)
24812 && !insn_terminates_group_p (next_insn, previous_group))
24814 if (!is_branch_slot_insn (next_insn))
24817 while (can_issue_more)
24820 emit_insn_before (nop, next_insn);
24825 can_issue_more = issue_rate;
24830 next_insn = get_next_active_insn (insn, tail);
24833 return group_count;
24836 /* We're beginning a new block. Initialize data structures as necessary. */
24839 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24840 int sched_verbose ATTRIBUTE_UNUSED,
24841 int max_ready ATTRIBUTE_UNUSED)
24843 last_scheduled_insn = NULL_RTX;
24844 load_store_pendulum = 0;
24847 /* The following function is called at the end of scheduling BB.
24848 After reload, it inserts nops at insn group bundling. */
24851 rs6000_sched_finish (FILE *dump, int sched_verbose)
24856 fprintf (dump, "=== Finishing schedule.\n");
24858 if (reload_completed && rs6000_sched_groups)
24860 /* Do not run sched_finish hook when selective scheduling enabled. */
24861 if (sel_sched_p ())
24864 if (rs6000_sched_insert_nops == sched_finish_none)
24867 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24868 n_groups = pad_groups (dump, sched_verbose,
24869 current_sched_info->prev_head,
24870 current_sched_info->next_tail);
24872 n_groups = redefine_groups (dump, sched_verbose,
24873 current_sched_info->prev_head,
24874 current_sched_info->next_tail);
24876 if (sched_verbose >= 6)
24878 fprintf (dump, "ngroups = %d\n", n_groups);
24879 print_rtl (dump, current_sched_info->prev_head);
24880 fprintf (dump, "Done finish_sched\n");
24885 struct _rs6000_sched_context
24887 short cached_can_issue_more;
24888 rtx last_scheduled_insn;
24889 int load_store_pendulum;
24892 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24893 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24895 /* Allocate store for new scheduling context. */
24897 rs6000_alloc_sched_context (void)
24899 return xmalloc (sizeof (rs6000_sched_context_def));
24902 /* If CLEAN_P is true then initializes _SC with clean data,
24903 and from the global context otherwise. */
24905 rs6000_init_sched_context (void *_sc, bool clean_p)
24907 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24911 sc->cached_can_issue_more = 0;
24912 sc->last_scheduled_insn = NULL_RTX;
24913 sc->load_store_pendulum = 0;
24917 sc->cached_can_issue_more = cached_can_issue_more;
24918 sc->last_scheduled_insn = last_scheduled_insn;
24919 sc->load_store_pendulum = load_store_pendulum;
24923 /* Sets the global scheduling context to the one pointed to by _SC. */
24925 rs6000_set_sched_context (void *_sc)
24927 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24929 gcc_assert (sc != NULL);
24931 cached_can_issue_more = sc->cached_can_issue_more;
24932 last_scheduled_insn = sc->last_scheduled_insn;
24933 load_store_pendulum = sc->load_store_pendulum;
24938 rs6000_free_sched_context (void *_sc)
24940 gcc_assert (_sc != NULL);
24946 /* Length in units of the trampoline for entering a nested function. */
24949 rs6000_trampoline_size (void)
24953 switch (DEFAULT_ABI)
24956 gcc_unreachable ();
24959 ret = (TARGET_32BIT) ? 12 : 24;
24964 ret = (TARGET_32BIT) ? 40 : 48;
24971 /* Emit RTL insns to initialize the variable parts of a trampoline.
24972 FNADDR is an RTX for the address of the function's pure code.
24973 CXT is an RTX for the static chain value for the function. */
24976 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24978 int regsize = (TARGET_32BIT) ? 4 : 8;
24979 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24980 rtx ctx_reg = force_reg (Pmode, cxt);
24981 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24983 switch (DEFAULT_ABI)
24986 gcc_unreachable ();
24988 /* Under AIX, just build the 3 word function descriptor */
24991 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24992 rtx fn_reg = gen_reg_rtx (Pmode);
24993 rtx toc_reg = gen_reg_rtx (Pmode);
24995 /* Macro to shorten the code expansions below. */
24996 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24998 m_tramp = replace_equiv_address (m_tramp, addr);
25000 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
25001 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
25002 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
25003 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
25004 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
25010 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25013 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
25014 LCT_NORMAL, VOIDmode, 4,
25016 GEN_INT (rs6000_trampoline_size ()), SImode,
25024 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25025 identifier as an argument, so the front end shouldn't look it up. */
25028 rs6000_attribute_takes_identifier_p (const_tree attr_id)
25030 return is_attribute_p ("altivec", attr_id);
25033 /* Handle the "altivec" attribute. The attribute may have
25034 arguments as follows:
25036 __attribute__((altivec(vector__)))
25037 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25038 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25040 and may appear more than once (e.g., 'vector bool char') in a
25041 given declaration. */
25044 rs6000_handle_altivec_attribute (tree *node,
25045 tree name ATTRIBUTE_UNUSED,
25047 int flags ATTRIBUTE_UNUSED,
25048 bool *no_add_attrs)
25050 tree type = *node, result = NULL_TREE;
25051 enum machine_mode mode;
25054 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
25055 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
25056 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
25059 while (POINTER_TYPE_P (type)
25060 || TREE_CODE (type) == FUNCTION_TYPE
25061 || TREE_CODE (type) == METHOD_TYPE
25062 || TREE_CODE (type) == ARRAY_TYPE)
25063 type = TREE_TYPE (type);
25065 mode = TYPE_MODE (type);
25067 /* Check for invalid AltiVec type qualifiers. */
25068 if (type == long_double_type_node)
25069 error ("use of %<long double%> in AltiVec types is invalid");
25070 else if (type == boolean_type_node)
25071 error ("use of boolean types in AltiVec types is invalid");
25072 else if (TREE_CODE (type) == COMPLEX_TYPE)
25073 error ("use of %<complex%> in AltiVec types is invalid");
25074 else if (DECIMAL_FLOAT_MODE_P (mode))
25075 error ("use of decimal floating point types in AltiVec types is invalid");
25076 else if (!TARGET_VSX)
25078 if (type == long_unsigned_type_node || type == long_integer_type_node)
25081 error ("use of %<long%> in AltiVec types is invalid for "
25082 "64-bit code without -mvsx");
25083 else if (rs6000_warn_altivec_long)
25084 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25087 else if (type == long_long_unsigned_type_node
25088 || type == long_long_integer_type_node)
25089 error ("use of %<long long%> in AltiVec types is invalid without "
25091 else if (type == double_type_node)
25092 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25095 switch (altivec_type)
25098 unsigned_p = TYPE_UNSIGNED (type);
25102 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25105 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25108 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25111 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25113 case SFmode: result = V4SF_type_node; break;
25114 case DFmode: result = V2DF_type_node; break;
25115 /* If the user says 'vector int bool', we may be handed the 'bool'
25116 attribute _before_ the 'vector' attribute, and so select the
25117 proper type in the 'b' case below. */
25118 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25119 case V2DImode: case V2DFmode:
25127 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25128 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25129 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25130 case QImode: case V16QImode: result = bool_V16QI_type_node;
25137 case V8HImode: result = pixel_V8HI_type_node;
25143 /* Propagate qualifiers attached to the element type
25144 onto the vector type. */
25145 if (result && result != type && TYPE_QUALS (type))
25146 result = build_qualified_type (result, TYPE_QUALS (type));
25148 *no_add_attrs = true; /* No need to hang on to the attribute. */
25151 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25156 /* AltiVec defines four built-in scalar types that serve as vector
25157 elements; we must teach the compiler how to mangle them. */
25159 static const char *
25160 rs6000_mangle_type (const_tree type)
25162 type = TYPE_MAIN_VARIANT (type);
25164 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25165 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25168 if (type == bool_char_type_node) return "U6__boolc";
25169 if (type == bool_short_type_node) return "U6__bools";
25170 if (type == pixel_type_node) return "u7__pixel";
25171 if (type == bool_int_type_node) return "U6__booli";
25172 if (type == bool_long_type_node) return "U6__booll";
25174 /* Mangle IBM extended float long double as `g' (__float128) on
25175 powerpc*-linux where long-double-64 previously was the default. */
25176 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25178 && TARGET_LONG_DOUBLE_128
25179 && !TARGET_IEEEQUAD)
25182 /* For all other types, use normal C++ mangling. */
25186 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25187 struct attribute_spec.handler. */
25190 rs6000_handle_longcall_attribute (tree *node, tree name,
25191 tree args ATTRIBUTE_UNUSED,
25192 int flags ATTRIBUTE_UNUSED,
25193 bool *no_add_attrs)
25195 if (TREE_CODE (*node) != FUNCTION_TYPE
25196 && TREE_CODE (*node) != FIELD_DECL
25197 && TREE_CODE (*node) != TYPE_DECL)
25199 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25201 *no_add_attrs = true;
25207 /* Set longcall attributes on all functions declared when
25208 rs6000_default_long_calls is true. */
25210 rs6000_set_default_type_attributes (tree type)
25212 if (rs6000_default_long_calls
25213 && (TREE_CODE (type) == FUNCTION_TYPE
25214 || TREE_CODE (type) == METHOD_TYPE))
25215 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25217 TYPE_ATTRIBUTES (type));
25220 darwin_set_default_type_attributes (type);
25224 /* Return a reference suitable for calling a function with the
25225 longcall attribute. */
25228 rs6000_longcall_ref (rtx call_ref)
25230 const char *call_name;
25233 if (GET_CODE (call_ref) != SYMBOL_REF)
25236 /* System V adds '.' to the internal name, so skip them. */
25237 call_name = XSTR (call_ref, 0);
25238 if (*call_name == '.')
25240 while (*call_name == '.')
25243 node = get_identifier (call_name);
25244 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25247 return force_reg (Pmode, call_ref);
25250 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25251 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25254 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25255 struct attribute_spec.handler. */
25257 rs6000_handle_struct_attribute (tree *node, tree name,
25258 tree args ATTRIBUTE_UNUSED,
25259 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25262 if (DECL_P (*node))
25264 if (TREE_CODE (*node) == TYPE_DECL)
25265 type = &TREE_TYPE (*node);
25270 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25271 || TREE_CODE (*type) == UNION_TYPE)))
25273 warning (OPT_Wattributes, "%qE attribute ignored", name);
25274 *no_add_attrs = true;
25277 else if ((is_attribute_p ("ms_struct", name)
25278 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25279 || ((is_attribute_p ("gcc_struct", name)
25280 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25282 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25284 *no_add_attrs = true;
25291 rs6000_ms_bitfield_layout_p (const_tree record_type)
25293 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25294 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25295 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25298 #ifdef USING_ELFOS_H
25300 /* A get_unnamed_section callback, used for switching to toc_section. */
25303 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25305 if (DEFAULT_ABI == ABI_AIX
25306 && TARGET_MINIMAL_TOC
25307 && !TARGET_RELOCATABLE)
25309 if (!toc_initialized)
25311 toc_initialized = 1;
25312 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25313 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25314 fprintf (asm_out_file, "\t.tc ");
25315 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25316 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25317 fprintf (asm_out_file, "\n");
25319 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25320 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25321 fprintf (asm_out_file, " = .+32768\n");
25324 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25326 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25327 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25330 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25331 if (!toc_initialized)
25333 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25334 fprintf (asm_out_file, " = .+32768\n");
25335 toc_initialized = 1;
25340 /* Implement TARGET_ASM_INIT_SECTIONS. */
25343 rs6000_elf_asm_init_sections (void)
25346 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25349 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25350 SDATA2_SECTION_ASM_OP);
25353 /* Implement TARGET_SELECT_RTX_SECTION. */
25356 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25357 unsigned HOST_WIDE_INT align)
25359 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25360 return toc_section;
25362 return default_elf_select_rtx_section (mode, x, align);
25365 /* For a SYMBOL_REF, set generic flags and then perform some
25366 target-specific processing.
25368 When the AIX ABI is requested on a non-AIX system, replace the
25369 function name with the real name (with a leading .) rather than the
25370 function descriptor name. This saves a lot of overriding code to
25371 read the prefixes. */
25374 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25376 default_encode_section_info (decl, rtl, first);
25379 && TREE_CODE (decl) == FUNCTION_DECL
25381 && DEFAULT_ABI == ABI_AIX)
25383 rtx sym_ref = XEXP (rtl, 0);
25384 size_t len = strlen (XSTR (sym_ref, 0));
25385 char *str = XALLOCAVEC (char, len + 2);
25387 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25388 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25393 compare_section_name (const char *section, const char *templ)
25397 len = strlen (templ);
25398 return (strncmp (section, templ, len) == 0
25399 && (section[len] == 0 || section[len] == '.'));
25403 rs6000_elf_in_small_data_p (const_tree decl)
25405 if (rs6000_sdata == SDATA_NONE)
25408 /* We want to merge strings, so we never consider them small data. */
25409 if (TREE_CODE (decl) == STRING_CST)
25412 /* Functions are never in the small data area. */
25413 if (TREE_CODE (decl) == FUNCTION_DECL)
25416 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25418 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25419 if (compare_section_name (section, ".sdata")
25420 || compare_section_name (section, ".sdata2")
25421 || compare_section_name (section, ".gnu.linkonce.s")
25422 || compare_section_name (section, ".sbss")
25423 || compare_section_name (section, ".sbss2")
25424 || compare_section_name (section, ".gnu.linkonce.sb")
25425 || strcmp (section, ".PPC.EMB.sdata0") == 0
25426 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25431 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25434 && size <= g_switch_value
25435 /* If it's not public, and we're not going to reference it there,
25436 there's no need to put it in the small data section. */
25437 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25444 #endif /* USING_ELFOS_H */
25446 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25449 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25451 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25454 /* Return a REG that occurs in ADDR with coefficient 1.
25455 ADDR can be effectively incremented by incrementing REG.
25457 r0 is special and we must not select it as an address
25458 register by this routine since our caller will try to
25459 increment the returned register via an "la" instruction. */
25462 find_addr_reg (rtx addr)
25464 while (GET_CODE (addr) == PLUS)
25466 if (GET_CODE (XEXP (addr, 0)) == REG
25467 && REGNO (XEXP (addr, 0)) != 0)
25468 addr = XEXP (addr, 0);
25469 else if (GET_CODE (XEXP (addr, 1)) == REG
25470 && REGNO (XEXP (addr, 1)) != 0)
25471 addr = XEXP (addr, 1);
25472 else if (CONSTANT_P (XEXP (addr, 0)))
25473 addr = XEXP (addr, 1);
25474 else if (CONSTANT_P (XEXP (addr, 1)))
25475 addr = XEXP (addr, 0);
25477 gcc_unreachable ();
25479 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25484 rs6000_fatal_bad_address (rtx op)
25486 fatal_insn ("bad address", op);
25491 typedef struct branch_island_d {
25492 tree function_name;
25497 DEF_VEC_O(branch_island);
25498 DEF_VEC_ALLOC_O(branch_island,gc);
25500 static VEC(branch_island,gc) *branch_islands;
25502 /* Remember to generate a branch island for far calls to the given
25506 add_compiler_branch_island (tree label_name, tree function_name,
25509 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25511 bi->function_name = function_name;
25512 bi->label_name = label_name;
25513 bi->line_number = line_number;
25516 /* Generate far-jump branch islands for everything recorded in
25517 branch_islands. Invoked immediately after the last instruction of
25518 the epilogue has been emitted; the branch islands must be appended
25519 to, and contiguous with, the function body. Mach-O stubs are
25520 generated in machopic_output_stub(). */
25523 macho_branch_islands (void)
25527 while (!VEC_empty (branch_island, branch_islands))
25529 branch_island *bi = VEC_last (branch_island, branch_islands);
25530 const char *label = IDENTIFIER_POINTER (bi->label_name);
25531 const char *name = IDENTIFIER_POINTER (bi->function_name);
25532 char name_buf[512];
25533 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25534 if (name[0] == '*' || name[0] == '&')
25535 strcpy (name_buf, name+1);
25539 strcpy (name_buf+1, name);
25541 strcpy (tmp_buf, "\n");
25542 strcat (tmp_buf, label);
25543 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25544 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25545 dbxout_stabd (N_SLINE, bi->line_number);
25546 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25549 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25550 strcat (tmp_buf, label);
25551 strcat (tmp_buf, "_pic\n");
25552 strcat (tmp_buf, label);
25553 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25555 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25556 strcat (tmp_buf, name_buf);
25557 strcat (tmp_buf, " - ");
25558 strcat (tmp_buf, label);
25559 strcat (tmp_buf, "_pic)\n");
25561 strcat (tmp_buf, "\tmtlr r0\n");
25563 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25564 strcat (tmp_buf, name_buf);
25565 strcat (tmp_buf, " - ");
25566 strcat (tmp_buf, label);
25567 strcat (tmp_buf, "_pic)\n");
25569 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25573 strcat (tmp_buf, ":\nlis r12,hi16(");
25574 strcat (tmp_buf, name_buf);
25575 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25576 strcat (tmp_buf, name_buf);
25577 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25579 output_asm_insn (tmp_buf, 0);
25580 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25581 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25582 dbxout_stabd (N_SLINE, bi->line_number);
25583 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25584 VEC_pop (branch_island, branch_islands);
25588 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25589 already there or not. */
25592 no_previous_def (tree function_name)
25597 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25598 if (function_name == bi->function_name)
25603 /* GET_PREV_LABEL gets the label name from the previous definition of
25607 get_prev_label (tree function_name)
25612 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25613 if (function_name == bi->function_name)
25614 return bi->label_name;
25618 /* INSN is either a function call or a millicode call. It may have an
25619 unconditional jump in its delay slot.
25621 CALL_DEST is the routine we are calling. */
25624 output_call (rtx insn, rtx *operands, int dest_operand_number,
25625 int cookie_operand_number)
25627 static char buf[256];
25628 if (darwin_emit_branch_islands
25629 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25630 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25633 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25635 if (no_previous_def (funname))
25637 rtx label_rtx = gen_label_rtx ();
25638 char *label_buf, temp_buf[256];
25639 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25640 CODE_LABEL_NUMBER (label_rtx));
25641 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25642 labelname = get_identifier (label_buf);
25643 add_compiler_branch_island (labelname, funname, insn_line (insn));
25646 labelname = get_prev_label (funname);
25648 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25649 instruction will reach 'foo', otherwise link as 'bl L42'".
25650 "L42" should be a 'branch island', that will do a far jump to
25651 'foo'. Branch islands are generated in
25652 macho_branch_islands(). */
25653 sprintf (buf, "jbsr %%z%d,%.246s",
25654 dest_operand_number, IDENTIFIER_POINTER (labelname));
25657 sprintf (buf, "bl %%z%d", dest_operand_number);
25661 /* Generate PIC and indirect symbol stubs. */
25664 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25666 unsigned int length;
25667 char *symbol_name, *lazy_ptr_name;
25668 char *local_label_0;
25669 static int label = 0;
25671 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25672 symb = (*targetm.strip_name_encoding) (symb);
25675 length = strlen (symb);
25676 symbol_name = XALLOCAVEC (char, length + 32);
25677 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25679 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25680 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25683 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25685 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25689 fprintf (file, "\t.align 5\n");
25691 fprintf (file, "%s:\n", stub);
25692 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25695 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25696 sprintf (local_label_0, "\"L%011d$spb\"", label);
25698 fprintf (file, "\tmflr r0\n");
25699 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25700 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25701 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25702 lazy_ptr_name, local_label_0);
25703 fprintf (file, "\tmtlr r0\n");
25704 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25705 (TARGET_64BIT ? "ldu" : "lwzu"),
25706 lazy_ptr_name, local_label_0);
25707 fprintf (file, "\tmtctr r12\n");
25708 fprintf (file, "\tbctr\n");
25712 fprintf (file, "\t.align 4\n");
25714 fprintf (file, "%s:\n", stub);
25715 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25717 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25718 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25719 (TARGET_64BIT ? "ldu" : "lwzu"),
25721 fprintf (file, "\tmtctr r12\n");
25722 fprintf (file, "\tbctr\n");
25725 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25726 fprintf (file, "%s:\n", lazy_ptr_name);
25727 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25728 fprintf (file, "%sdyld_stub_binding_helper\n",
25729 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25732 /* Legitimize PIC addresses. If the address is already
25733 position-independent, we return ORIG. Newly generated
25734 position-independent addresses go into a reg. This is REG if non
25735 zero, otherwise we allocate register(s) as necessary. */
25737 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25740 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25745 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25746 reg = gen_reg_rtx (Pmode);
25748 if (GET_CODE (orig) == CONST)
25752 if (GET_CODE (XEXP (orig, 0)) == PLUS
25753 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25756 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25758 /* Use a different reg for the intermediate value, as
25759 it will be marked UNCHANGING. */
25760 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25761 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25764 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25767 if (GET_CODE (offset) == CONST_INT)
25769 if (SMALL_INT (offset))
25770 return plus_constant (base, INTVAL (offset));
25771 else if (! reload_in_progress && ! reload_completed)
25772 offset = force_reg (Pmode, offset);
25775 rtx mem = force_const_mem (Pmode, orig);
25776 return machopic_legitimize_pic_address (mem, Pmode, reg);
25779 return gen_rtx_PLUS (Pmode, base, offset);
25782 /* Fall back on generic machopic code. */
25783 return machopic_legitimize_pic_address (orig, mode, reg);
25786 /* Output a .machine directive for the Darwin assembler, and call
25787 the generic start_file routine. */
25790 rs6000_darwin_file_start (void)
25792 static const struct
25798 { "ppc64", "ppc64", MASK_64BIT },
25799 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25800 { "power4", "ppc970", 0 },
25801 { "G5", "ppc970", 0 },
25802 { "7450", "ppc7450", 0 },
25803 { "7400", "ppc7400", MASK_ALTIVEC },
25804 { "G4", "ppc7400", 0 },
25805 { "750", "ppc750", 0 },
25806 { "740", "ppc750", 0 },
25807 { "G3", "ppc750", 0 },
25808 { "604e", "ppc604e", 0 },
25809 { "604", "ppc604", 0 },
25810 { "603e", "ppc603", 0 },
25811 { "603", "ppc603", 0 },
25812 { "601", "ppc601", 0 },
25813 { NULL, "ppc", 0 } };
25814 const char *cpu_id = "";
25817 rs6000_file_start ();
25818 darwin_file_start ();
25820 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25821 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25822 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25823 && rs6000_select[i].string[0] != '\0')
25824 cpu_id = rs6000_select[i].string;
25826 /* Look through the mapping array. Pick the first name that either
25827 matches the argument, has a bit set in IF_SET that is also set
25828 in the target flags, or has a NULL name. */
25831 while (mapping[i].arg != NULL
25832 && strcmp (mapping[i].arg, cpu_id) != 0
25833 && (mapping[i].if_set & target_flags) == 0)
25836 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25839 #endif /* TARGET_MACHO */
25843 rs6000_elf_reloc_rw_mask (void)
25847 else if (DEFAULT_ABI == ABI_AIX)
25853 /* Record an element in the table of global constructors. SYMBOL is
25854 a SYMBOL_REF of the function to be called; PRIORITY is a number
25855 between 0 and MAX_INIT_PRIORITY.
25857 This differs from default_named_section_asm_out_constructor in
25858 that we have special handling for -mrelocatable. */
25861 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25863 const char *section = ".ctors";
25866 if (priority != DEFAULT_INIT_PRIORITY)
25868 sprintf (buf, ".ctors.%.5u",
25869 /* Invert the numbering so the linker puts us in the proper
25870 order; constructors are run from right to left, and the
25871 linker sorts in increasing order. */
25872 MAX_INIT_PRIORITY - priority);
25876 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25877 assemble_align (POINTER_SIZE);
25879 if (TARGET_RELOCATABLE)
25881 fputs ("\t.long (", asm_out_file);
25882 output_addr_const (asm_out_file, symbol);
25883 fputs (")@fixup\n", asm_out_file);
25886 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25890 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25892 const char *section = ".dtors";
25895 if (priority != DEFAULT_INIT_PRIORITY)
25897 sprintf (buf, ".dtors.%.5u",
25898 /* Invert the numbering so the linker puts us in the proper
25899 order; constructors are run from right to left, and the
25900 linker sorts in increasing order. */
25901 MAX_INIT_PRIORITY - priority);
25905 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25906 assemble_align (POINTER_SIZE);
25908 if (TARGET_RELOCATABLE)
25910 fputs ("\t.long (", asm_out_file);
25911 output_addr_const (asm_out_file, symbol);
25912 fputs (")@fixup\n", asm_out_file);
25915 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25919 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25923 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25924 ASM_OUTPUT_LABEL (file, name);
25925 fputs (DOUBLE_INT_ASM_OP, file);
25926 rs6000_output_function_entry (file, name);
25927 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25930 fputs ("\t.size\t", file);
25931 assemble_name (file, name);
25932 fputs (",24\n\t.type\t.", file);
25933 assemble_name (file, name);
25934 fputs (",@function\n", file);
25935 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25937 fputs ("\t.globl\t.", file);
25938 assemble_name (file, name);
25943 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25944 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25945 rs6000_output_function_entry (file, name);
25946 fputs (":\n", file);
25950 if (TARGET_RELOCATABLE
25951 && !TARGET_SECURE_PLT
25952 && (get_pool_size () != 0 || crtl->profile)
25957 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25959 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25960 fprintf (file, "\t.long ");
25961 assemble_name (file, buf);
25963 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25964 assemble_name (file, buf);
25968 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25969 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25971 if (DEFAULT_ABI == ABI_AIX)
25973 const char *desc_name, *orig_name;
25975 orig_name = (*targetm.strip_name_encoding) (name);
25976 desc_name = orig_name;
25977 while (*desc_name == '.')
25980 if (TREE_PUBLIC (decl))
25981 fprintf (file, "\t.globl %s\n", desc_name);
25983 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25984 fprintf (file, "%s:\n", desc_name);
25985 fprintf (file, "\t.long %s\n", orig_name);
25986 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25987 if (DEFAULT_ABI == ABI_AIX)
25988 fputs ("\t.long 0\n", file);
25989 fprintf (file, "\t.previous\n");
25991 ASM_OUTPUT_LABEL (file, name);
25995 rs6000_elf_file_end (void)
25997 #ifdef HAVE_AS_GNU_ATTRIBUTE
25998 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
26000 if (rs6000_passes_float)
26001 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
26002 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
26003 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
26005 if (rs6000_passes_vector)
26006 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
26007 (TARGET_ALTIVEC_ABI ? 2
26008 : TARGET_SPE_ABI ? 3
26010 if (rs6000_returns_struct)
26011 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
26012 aix_struct_return ? 2 : 1);
26015 #ifdef POWERPC_LINUX
26017 file_end_indicate_exec_stack ();
26024 rs6000_xcoff_asm_output_anchor (rtx symbol)
26028 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
26029 SYMBOL_REF_BLOCK_OFFSET (symbol));
26030 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
26034 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
26036 fputs (GLOBAL_ASM_OP, stream);
26037 RS6000_OUTPUT_BASENAME (stream, name);
26038 putc ('\n', stream);
26041 /* A get_unnamed_decl callback, used for read-only sections. PTR
26042 points to the section string variable. */
26045 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
26047 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
26048 *(const char *const *) directive,
26049 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26052 /* Likewise for read-write sections. */
26055 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
26057 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
26058 *(const char *const *) directive,
26059 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26062 /* A get_unnamed_section callback, used for switching to toc_section. */
26065 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
26067 if (TARGET_MINIMAL_TOC)
26069 /* toc_section is always selected at least once from
26070 rs6000_xcoff_file_start, so this is guaranteed to
26071 always be defined once and only once in each file. */
26072 if (!toc_initialized)
26074 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26075 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26076 toc_initialized = 1;
26078 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26079 (TARGET_32BIT ? "" : ",3"));
26082 fputs ("\t.toc\n", asm_out_file);
26085 /* Implement TARGET_ASM_INIT_SECTIONS. */
26088 rs6000_xcoff_asm_init_sections (void)
26090 read_only_data_section
26091 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26092 &xcoff_read_only_section_name);
26094 private_data_section
26095 = get_unnamed_section (SECTION_WRITE,
26096 rs6000_xcoff_output_readwrite_section_asm_op,
26097 &xcoff_private_data_section_name);
26099 read_only_private_data_section
26100 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26101 &xcoff_private_data_section_name);
26104 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26106 readonly_data_section = read_only_data_section;
26107 exception_section = data_section;
26111 rs6000_xcoff_reloc_rw_mask (void)
26117 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26118 tree decl ATTRIBUTE_UNUSED)
26121 static const char * const suffix[3] = { "PR", "RO", "RW" };
26123 if (flags & SECTION_CODE)
26125 else if (flags & SECTION_WRITE)
26130 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26131 (flags & SECTION_CODE) ? "." : "",
26132 name, suffix[smclass], flags & SECTION_ENTSIZE);
26136 rs6000_xcoff_select_section (tree decl, int reloc,
26137 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26139 if (decl_readonly_section (decl, reloc))
26141 if (TREE_PUBLIC (decl))
26142 return read_only_data_section;
26144 return read_only_private_data_section;
26148 if (TREE_PUBLIC (decl))
26149 return data_section;
26151 return private_data_section;
26156 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26160 /* Use select_section for private and uninitialized data. */
26161 if (!TREE_PUBLIC (decl)
26162 || DECL_COMMON (decl)
26163 || DECL_INITIAL (decl) == NULL_TREE
26164 || DECL_INITIAL (decl) == error_mark_node
26165 || (flag_zero_initialized_in_bss
26166 && initializer_zerop (DECL_INITIAL (decl))))
26169 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26170 name = (*targetm.strip_name_encoding) (name);
26171 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26174 /* Select section for constant in constant pool.
26176 On RS/6000, all constants are in the private read-only data area.
26177 However, if this is being placed in the TOC it must be output as a
26181 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26182 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26184 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26185 return toc_section;
26187 return read_only_private_data_section;
26190 /* Remove any trailing [DS] or the like from the symbol name. */
26192 static const char *
26193 rs6000_xcoff_strip_name_encoding (const char *name)
26198 len = strlen (name);
26199 if (name[len - 1] == ']')
26200 return ggc_alloc_string (name, len - 4);
26205 /* Section attributes. AIX is always PIC. */
26207 static unsigned int
26208 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26210 unsigned int align;
26211 unsigned int flags = default_section_type_flags (decl, name, reloc);
26213 /* Align to at least UNIT size. */
26214 if (flags & SECTION_CODE)
26215 align = MIN_UNITS_PER_WORD;
26217 /* Increase alignment of large objects if not already stricter. */
26218 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26219 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26220 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26222 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26225 /* Output at beginning of assembler file.
26227 Initialize the section names for the RS/6000 at this point.
26229 Specify filename, including full path, to assembler.
26231 We want to go into the TOC section so at least one .toc will be emitted.
26232 Also, in order to output proper .bs/.es pairs, we need at least one static
26233 [RW] section emitted.
26235 Finally, declare mcount when profiling to make the assembler happy. */
26238 rs6000_xcoff_file_start (void)
26240 rs6000_gen_section_name (&xcoff_bss_section_name,
26241 main_input_filename, ".bss_");
26242 rs6000_gen_section_name (&xcoff_private_data_section_name,
26243 main_input_filename, ".rw_");
26244 rs6000_gen_section_name (&xcoff_read_only_section_name,
26245 main_input_filename, ".ro_");
26247 fputs ("\t.file\t", asm_out_file);
26248 output_quoted_string (asm_out_file, main_input_filename);
26249 fputc ('\n', asm_out_file);
26250 if (write_symbols != NO_DEBUG)
26251 switch_to_section (private_data_section);
26252 switch_to_section (text_section);
26254 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26255 rs6000_file_start ();
26258 /* Output at end of assembler file.
26259 On the RS/6000, referencing data should automatically pull in text. */
26262 rs6000_xcoff_file_end (void)
26264 switch_to_section (text_section);
26265 fputs ("_section_.text:\n", asm_out_file);
26266 switch_to_section (data_section);
26267 fputs (TARGET_32BIT
26268 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26271 #endif /* TARGET_XCOFF */
26273 /* Compute a (partial) cost for rtx X. Return true if the complete
26274 cost has been computed, and false if subexpressions should be
26275 scanned. In either case, *TOTAL contains the cost result. */
26278 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26281 enum machine_mode mode = GET_MODE (x);
26285 /* On the RS/6000, if it is valid in the insn, it is free. */
26287 if (((outer_code == SET
26288 || outer_code == PLUS
26289 || outer_code == MINUS)
26290 && (satisfies_constraint_I (x)
26291 || satisfies_constraint_L (x)))
26292 || (outer_code == AND
26293 && (satisfies_constraint_K (x)
26295 ? satisfies_constraint_L (x)
26296 : satisfies_constraint_J (x))
26297 || mask_operand (x, mode)
26299 && mask64_operand (x, DImode))))
26300 || ((outer_code == IOR || outer_code == XOR)
26301 && (satisfies_constraint_K (x)
26303 ? satisfies_constraint_L (x)
26304 : satisfies_constraint_J (x))))
26305 || outer_code == ASHIFT
26306 || outer_code == ASHIFTRT
26307 || outer_code == LSHIFTRT
26308 || outer_code == ROTATE
26309 || outer_code == ROTATERT
26310 || outer_code == ZERO_EXTRACT
26311 || (outer_code == MULT
26312 && satisfies_constraint_I (x))
26313 || ((outer_code == DIV || outer_code == UDIV
26314 || outer_code == MOD || outer_code == UMOD)
26315 && exact_log2 (INTVAL (x)) >= 0)
26316 || (outer_code == COMPARE
26317 && (satisfies_constraint_I (x)
26318 || satisfies_constraint_K (x)))
26319 || ((outer_code == EQ || outer_code == NE)
26320 && (satisfies_constraint_I (x)
26321 || satisfies_constraint_K (x)
26323 ? satisfies_constraint_L (x)
26324 : satisfies_constraint_J (x))))
26325 || (outer_code == GTU
26326 && satisfies_constraint_I (x))
26327 || (outer_code == LTU
26328 && satisfies_constraint_P (x)))
26333 else if ((outer_code == PLUS
26334 && reg_or_add_cint_operand (x, VOIDmode))
26335 || (outer_code == MINUS
26336 && reg_or_sub_cint_operand (x, VOIDmode))
26337 || ((outer_code == SET
26338 || outer_code == IOR
26339 || outer_code == XOR)
26341 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26343 *total = COSTS_N_INSNS (1);
26349 if (mode == DImode && code == CONST_DOUBLE)
26351 if ((outer_code == IOR || outer_code == XOR)
26352 && CONST_DOUBLE_HIGH (x) == 0
26353 && (CONST_DOUBLE_LOW (x)
26354 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26359 else if ((outer_code == AND && and64_2_operand (x, DImode))
26360 || ((outer_code == SET
26361 || outer_code == IOR
26362 || outer_code == XOR)
26363 && CONST_DOUBLE_HIGH (x) == 0))
26365 *total = COSTS_N_INSNS (1);
26375 /* When optimizing for size, MEM should be slightly more expensive
26376 than generating address, e.g., (plus (reg) (const)).
26377 L1 cache latency is about two instructions. */
26378 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26387 if (FLOAT_MODE_P (mode))
26388 *total = rs6000_cost->fp;
26390 *total = COSTS_N_INSNS (1);
26394 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26395 && satisfies_constraint_I (XEXP (x, 1)))
26397 if (INTVAL (XEXP (x, 1)) >= -256
26398 && INTVAL (XEXP (x, 1)) <= 255)
26399 *total = rs6000_cost->mulsi_const9;
26401 *total = rs6000_cost->mulsi_const;
26403 else if (mode == SFmode)
26404 *total = rs6000_cost->fp;
26405 else if (FLOAT_MODE_P (mode))
26406 *total = rs6000_cost->dmul;
26407 else if (mode == DImode)
26408 *total = rs6000_cost->muldi;
26410 *total = rs6000_cost->mulsi;
26414 if (mode == SFmode)
26415 *total = rs6000_cost->fp;
26417 *total = rs6000_cost->dmul;
26422 if (FLOAT_MODE_P (mode))
26424 *total = mode == DFmode ? rs6000_cost->ddiv
26425 : rs6000_cost->sdiv;
26432 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26433 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26435 if (code == DIV || code == MOD)
26437 *total = COSTS_N_INSNS (2);
26440 *total = COSTS_N_INSNS (1);
26444 if (GET_MODE (XEXP (x, 1)) == DImode)
26445 *total = rs6000_cost->divdi;
26447 *total = rs6000_cost->divsi;
26449 /* Add in shift and subtract for MOD. */
26450 if (code == MOD || code == UMOD)
26451 *total += COSTS_N_INSNS (2);
26456 *total = COSTS_N_INSNS (4);
26460 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26464 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26468 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26480 *total = COSTS_N_INSNS (1);
26488 /* Handle mul_highpart. */
26489 if (outer_code == TRUNCATE
26490 && GET_CODE (XEXP (x, 0)) == MULT)
26492 if (mode == DImode)
26493 *total = rs6000_cost->muldi;
26495 *total = rs6000_cost->mulsi;
26498 else if (outer_code == AND)
26501 *total = COSTS_N_INSNS (1);
26506 if (GET_CODE (XEXP (x, 0)) == MEM)
26509 *total = COSTS_N_INSNS (1);
26515 if (!FLOAT_MODE_P (mode))
26517 *total = COSTS_N_INSNS (1);
26523 case UNSIGNED_FLOAT:
26526 case FLOAT_TRUNCATE:
26527 *total = rs6000_cost->fp;
26531 if (mode == DFmode)
26534 *total = rs6000_cost->fp;
26538 switch (XINT (x, 1))
26541 *total = rs6000_cost->fp;
26553 *total = COSTS_N_INSNS (1);
26556 else if (FLOAT_MODE_P (mode)
26557 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26559 *total = rs6000_cost->fp;
26567 /* Carry bit requires mode == Pmode.
26568 NEG or PLUS already counted so only add one. */
26570 && (outer_code == NEG || outer_code == PLUS))
26572 *total = COSTS_N_INSNS (1);
26575 if (outer_code == SET)
26577 if (XEXP (x, 1) == const0_rtx)
26579 if (TARGET_ISEL && !TARGET_MFCRF)
26580 *total = COSTS_N_INSNS (8);
26582 *total = COSTS_N_INSNS (2);
26585 else if (mode == Pmode)
26587 *total = COSTS_N_INSNS (3);
26596 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26598 if (TARGET_ISEL && !TARGET_MFCRF)
26599 *total = COSTS_N_INSNS (8);
26601 *total = COSTS_N_INSNS (2);
26605 if (outer_code == COMPARE)
26619 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26622 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26625 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26628 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26629 "total = %d, speed = %s, x:\n",
26630 ret ? "complete" : "scan inner",
26631 GET_RTX_NAME (code),
26632 GET_RTX_NAME (outer_code),
26634 speed ? "true" : "false");
26641 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26644 rs6000_debug_address_cost (rtx x, bool speed)
26646 int ret = TARGET_ADDRESS_COST (x, speed);
26648 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26649 ret, speed ? "true" : "false");
26656 /* A C expression returning the cost of moving data from a register of class
26657 CLASS1 to one of CLASS2. */
26660 rs6000_register_move_cost (enum machine_mode mode,
26661 reg_class_t from, reg_class_t to)
26665 /* Moves from/to GENERAL_REGS. */
26666 if (reg_classes_intersect_p (to, GENERAL_REGS)
26667 || reg_classes_intersect_p (from, GENERAL_REGS))
26669 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26672 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26673 ret = (rs6000_memory_move_cost (mode, from, false)
26674 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26676 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26678 else if (from == CR_REGS)
26681 /* Power6 has slower LR/CTR moves so make them more expensive than
26682 memory in order to bias spills to memory .*/
26683 else if (rs6000_cpu == PROCESSOR_POWER6
26684 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26685 ret = 6 * hard_regno_nregs[0][mode];
26688 /* A move will cost one instruction per GPR moved. */
26689 ret = 2 * hard_regno_nregs[0][mode];
26692 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26693 else if (VECTOR_UNIT_VSX_P (mode)
26694 && reg_classes_intersect_p (to, VSX_REGS)
26695 && reg_classes_intersect_p (from, VSX_REGS))
26696 ret = 2 * hard_regno_nregs[32][mode];
26698 /* Moving between two similar registers is just one instruction. */
26699 else if (reg_classes_intersect_p (to, from))
26700 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26702 /* Everything else has to go through GENERAL_REGS. */
26704 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26705 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26707 if (TARGET_DEBUG_COST)
26709 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26710 ret, GET_MODE_NAME (mode), reg_class_names[from],
26711 reg_class_names[to]);
26716 /* A C expressions returning the cost of moving data of MODE from a register to
26720 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26721 bool in ATTRIBUTE_UNUSED)
26725 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26726 ret = 4 * hard_regno_nregs[0][mode];
26727 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26728 ret = 4 * hard_regno_nregs[32][mode];
26729 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26730 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26732 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26734 if (TARGET_DEBUG_COST)
26736 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26737 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26742 /* Returns a code for a target-specific builtin that implements
26743 reciprocal of the function, or NULL_TREE if not available. */
26746 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26747 bool sqrt ATTRIBUTE_UNUSED)
26749 if (optimize_insn_for_size_p ())
26755 case VSX_BUILTIN_XVSQRTDP:
26756 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26759 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26761 case VSX_BUILTIN_XVSQRTSP:
26762 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26765 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26774 case BUILT_IN_SQRT:
26775 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26778 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26780 case BUILT_IN_SQRTF:
26781 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26784 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26791 /* Load up a constant. If the mode is a vector mode, splat the value across
26792 all of the vector elements. */
26795 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26799 if (mode == SFmode || mode == DFmode)
26801 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26802 reg = force_reg (mode, d);
26804 else if (mode == V4SFmode)
26806 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26807 rtvec v = gen_rtvec (4, d, d, d, d);
26808 reg = gen_reg_rtx (mode);
26809 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26811 else if (mode == V2DFmode)
26813 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26814 rtvec v = gen_rtvec (2, d, d);
26815 reg = gen_reg_rtx (mode);
26816 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26819 gcc_unreachable ();
26824 /* Generate an FMA instruction. */
26827 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26829 enum machine_mode mode = GET_MODE (target);
26832 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26833 gcc_assert (dst != NULL);
26836 emit_move_insn (target, dst);
26839 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26842 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26844 enum machine_mode mode = GET_MODE (target);
26847 /* Altivec does not support fms directly;
26848 generate in terms of fma in that case. */
26849 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26850 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26853 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26854 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26856 gcc_assert (dst != NULL);
26859 emit_move_insn (target, dst);
26862 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26865 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26867 enum machine_mode mode = GET_MODE (dst);
26870 /* This is a tad more complicated, since the fnma_optab is for
26871 a different expression: fma(-m1, m2, a), which is the same
26872 thing except in the case of signed zeros.
26874 Fortunately we know that if FMA is supported that FNMSUB is
26875 also supported in the ISA. Just expand it directly. */
26877 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26879 r = gen_rtx_NEG (mode, a);
26880 r = gen_rtx_FMA (mode, m1, m2, r);
26881 r = gen_rtx_NEG (mode, r);
26882 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26885 /* Newton-Raphson approximation of floating point divide with just 2 passes
26886 (either single precision floating point, or newer machines with higher
26887 accuracy estimates). Support both scalar and vector divide. Assumes no
26888 trapping math and finite arguments. */
26891 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26893 enum machine_mode mode = GET_MODE (dst);
26894 rtx x0, e0, e1, y1, u0, v0;
26895 enum insn_code code = optab_handler (smul_optab, mode);
26896 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26897 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26899 gcc_assert (code != CODE_FOR_nothing);
26901 /* x0 = 1./d estimate */
26902 x0 = gen_reg_rtx (mode);
26903 emit_insn (gen_rtx_SET (VOIDmode, x0,
26904 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26907 e0 = gen_reg_rtx (mode);
26908 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26910 e1 = gen_reg_rtx (mode);
26911 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26913 y1 = gen_reg_rtx (mode);
26914 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26916 u0 = gen_reg_rtx (mode);
26917 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26919 v0 = gen_reg_rtx (mode);
26920 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26922 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26925 /* Newton-Raphson approximation of floating point divide that has a low
26926 precision estimate. Assumes no trapping math and finite arguments. */
26929 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26931 enum machine_mode mode = GET_MODE (dst);
26932 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26933 enum insn_code code = optab_handler (smul_optab, mode);
26934 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26936 gcc_assert (code != CODE_FOR_nothing);
26938 one = rs6000_load_constant_and_splat (mode, dconst1);
26940 /* x0 = 1./d estimate */
26941 x0 = gen_reg_rtx (mode);
26942 emit_insn (gen_rtx_SET (VOIDmode, x0,
26943 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26946 e0 = gen_reg_rtx (mode);
26947 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26949 y1 = gen_reg_rtx (mode);
26950 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26952 e1 = gen_reg_rtx (mode);
26953 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26955 y2 = gen_reg_rtx (mode);
26956 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26958 e2 = gen_reg_rtx (mode);
26959 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26961 y3 = gen_reg_rtx (mode);
26962 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26964 u0 = gen_reg_rtx (mode);
26965 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26967 v0 = gen_reg_rtx (mode);
26968 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26970 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26973 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26974 add a reg_note saying that this was a division. Support both scalar and
26975 vector divide. Assumes no trapping math and finite arguments. */
26978 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26980 enum machine_mode mode = GET_MODE (dst);
26982 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26983 rs6000_emit_swdiv_high_precision (dst, n, d);
26985 rs6000_emit_swdiv_low_precision (dst, n, d);
26988 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26991 /* Newton-Raphson approximation of single/double-precision floating point
26992 rsqrt. Assumes no trapping math and finite arguments. */
26995 rs6000_emit_swrsqrt (rtx dst, rtx src)
26997 enum machine_mode mode = GET_MODE (src);
26998 rtx x0 = gen_reg_rtx (mode);
26999 rtx y = gen_reg_rtx (mode);
27000 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
27001 REAL_VALUE_TYPE dconst3_2;
27004 enum insn_code code = optab_handler (smul_optab, mode);
27005 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27007 gcc_assert (code != CODE_FOR_nothing);
27009 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27010 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
27011 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
27013 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
27015 /* x0 = rsqrt estimate */
27016 emit_insn (gen_rtx_SET (VOIDmode, x0,
27017 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
27020 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27021 rs6000_emit_msub (y, src, halfthree, src);
27023 for (i = 0; i < passes; i++)
27025 rtx x1 = gen_reg_rtx (mode);
27026 rtx u = gen_reg_rtx (mode);
27027 rtx v = gen_reg_rtx (mode);
27029 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27030 emit_insn (gen_mul (u, x0, x0));
27031 rs6000_emit_nmsub (v, y, u, halfthree);
27032 emit_insn (gen_mul (x1, x0, v));
27036 emit_move_insn (dst, x0);
27040 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27041 (Power7) targets. DST is the target, and SRC is the argument operand. */
27044 rs6000_emit_popcount (rtx dst, rtx src)
27046 enum machine_mode mode = GET_MODE (dst);
27049 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27050 if (TARGET_POPCNTD)
27052 if (mode == SImode)
27053 emit_insn (gen_popcntdsi2 (dst, src));
27055 emit_insn (gen_popcntddi2 (dst, src));
27059 tmp1 = gen_reg_rtx (mode);
27061 if (mode == SImode)
27063 emit_insn (gen_popcntbsi2 (tmp1, src));
27064 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
27066 tmp2 = force_reg (SImode, tmp2);
27067 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
27071 emit_insn (gen_popcntbdi2 (tmp1, src));
27072 tmp2 = expand_mult (DImode, tmp1,
27073 GEN_INT ((HOST_WIDE_INT)
27074 0x01010101 << 32 | 0x01010101),
27076 tmp2 = force_reg (DImode, tmp2);
27077 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27082 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27083 target, and SRC is the argument operand. */
27086 rs6000_emit_parity (rtx dst, rtx src)
27088 enum machine_mode mode = GET_MODE (dst);
27091 tmp = gen_reg_rtx (mode);
27093 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27096 if (mode == SImode)
27098 emit_insn (gen_popcntbsi2 (tmp, src));
27099 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27103 emit_insn (gen_popcntbdi2 (tmp, src));
27104 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27109 if (mode == SImode)
27111 /* Is mult+shift >= shift+xor+shift+xor? */
27112 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27114 rtx tmp1, tmp2, tmp3, tmp4;
27116 tmp1 = gen_reg_rtx (SImode);
27117 emit_insn (gen_popcntbsi2 (tmp1, src));
27119 tmp2 = gen_reg_rtx (SImode);
27120 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27121 tmp3 = gen_reg_rtx (SImode);
27122 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27124 tmp4 = gen_reg_rtx (SImode);
27125 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27126 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27129 rs6000_emit_popcount (tmp, src);
27130 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27134 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27135 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27137 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27139 tmp1 = gen_reg_rtx (DImode);
27140 emit_insn (gen_popcntbdi2 (tmp1, src));
27142 tmp2 = gen_reg_rtx (DImode);
27143 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27144 tmp3 = gen_reg_rtx (DImode);
27145 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27147 tmp4 = gen_reg_rtx (DImode);
27148 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27149 tmp5 = gen_reg_rtx (DImode);
27150 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27152 tmp6 = gen_reg_rtx (DImode);
27153 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27154 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27157 rs6000_emit_popcount (tmp, src);
27158 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27162 /* Return an RTX representing where to find the function value of a
27163 function returning MODE. */
27165 rs6000_complex_function_value (enum machine_mode mode)
27167 unsigned int regno;
27169 enum machine_mode inner = GET_MODE_INNER (mode);
27170 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27172 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27173 regno = FP_ARG_RETURN;
27176 regno = GP_ARG_RETURN;
27178 /* 32-bit is OK since it'll go in r3/r4. */
27179 if (TARGET_32BIT && inner_bytes >= 4)
27180 return gen_rtx_REG (mode, regno);
27183 if (inner_bytes >= 8)
27184 return gen_rtx_REG (mode, regno);
27186 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27188 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27189 GEN_INT (inner_bytes));
27190 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27193 /* Target hook for TARGET_FUNCTION_VALUE.
27195 On the SPE, both FPs and vectors are returned in r3.
27197 On RS/6000 an integer value is in r3 and a floating-point value is in
27198 fp1, unless -msoft-float. */
27201 rs6000_function_value (const_tree valtype,
27202 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27203 bool outgoing ATTRIBUTE_UNUSED)
27205 enum machine_mode mode;
27206 unsigned int regno;
27208 /* Special handling for structs in darwin64. */
27210 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27212 CUMULATIVE_ARGS valcum;
27216 valcum.fregno = FP_ARG_MIN_REG;
27217 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27218 /* Do a trial code generation as if this were going to be passed as
27219 an argument; if any part goes in memory, we return NULL. */
27220 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27223 /* Otherwise fall through to standard ABI rules. */
27226 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27228 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27229 return gen_rtx_PARALLEL (DImode,
27231 gen_rtx_EXPR_LIST (VOIDmode,
27232 gen_rtx_REG (SImode, GP_ARG_RETURN),
27234 gen_rtx_EXPR_LIST (VOIDmode,
27235 gen_rtx_REG (SImode,
27236 GP_ARG_RETURN + 1),
27239 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27241 return gen_rtx_PARALLEL (DCmode,
27243 gen_rtx_EXPR_LIST (VOIDmode,
27244 gen_rtx_REG (SImode, GP_ARG_RETURN),
27246 gen_rtx_EXPR_LIST (VOIDmode,
27247 gen_rtx_REG (SImode,
27248 GP_ARG_RETURN + 1),
27250 gen_rtx_EXPR_LIST (VOIDmode,
27251 gen_rtx_REG (SImode,
27252 GP_ARG_RETURN + 2),
27254 gen_rtx_EXPR_LIST (VOIDmode,
27255 gen_rtx_REG (SImode,
27256 GP_ARG_RETURN + 3),
27260 mode = TYPE_MODE (valtype);
27261 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27262 || POINTER_TYPE_P (valtype))
27263 mode = TARGET_32BIT ? SImode : DImode;
27265 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27266 /* _Decimal128 must use an even/odd register pair. */
27267 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27268 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27269 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27270 regno = FP_ARG_RETURN;
27271 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27272 && targetm.calls.split_complex_arg)
27273 return rs6000_complex_function_value (mode);
27274 else if (TREE_CODE (valtype) == VECTOR_TYPE
27275 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27276 && ALTIVEC_VECTOR_MODE (mode))
27277 regno = ALTIVEC_ARG_RETURN;
27278 else if (TREE_CODE (valtype) == VECTOR_TYPE
27279 && TARGET_VSX && TARGET_ALTIVEC_ABI
27280 && VSX_VECTOR_MODE (mode))
27281 regno = ALTIVEC_ARG_RETURN;
27282 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27283 && (mode == DFmode || mode == DCmode
27284 || mode == TFmode || mode == TCmode))
27285 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27287 regno = GP_ARG_RETURN;
27289 return gen_rtx_REG (mode, regno);
27292 /* Define how to find the value returned by a library function
27293 assuming the value has mode MODE. */
27295 rs6000_libcall_value (enum machine_mode mode)
27297 unsigned int regno;
27299 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27301 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27302 return gen_rtx_PARALLEL (DImode,
27304 gen_rtx_EXPR_LIST (VOIDmode,
27305 gen_rtx_REG (SImode, GP_ARG_RETURN),
27307 gen_rtx_EXPR_LIST (VOIDmode,
27308 gen_rtx_REG (SImode,
27309 GP_ARG_RETURN + 1),
27313 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27314 /* _Decimal128 must use an even/odd register pair. */
27315 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27316 else if (SCALAR_FLOAT_MODE_P (mode)
27317 && TARGET_HARD_FLOAT && TARGET_FPRS
27318 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27319 regno = FP_ARG_RETURN;
27320 else if (ALTIVEC_VECTOR_MODE (mode)
27321 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27322 regno = ALTIVEC_ARG_RETURN;
27323 else if (VSX_VECTOR_MODE (mode)
27324 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27325 regno = ALTIVEC_ARG_RETURN;
27326 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27327 return rs6000_complex_function_value (mode);
27328 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27329 && (mode == DFmode || mode == DCmode
27330 || mode == TFmode || mode == TCmode))
27331 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27333 regno = GP_ARG_RETURN;
27335 return gen_rtx_REG (mode, regno);
27339 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27340 Frame pointer elimination is automatically handled.
27342 For the RS/6000, if frame pointer elimination is being done, we would like
27343 to convert ap into fp, not sp.
27345 We need r30 if -mminimal-toc was specified, and there are constant pool
27349 rs6000_can_eliminate (const int from, const int to)
27351 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27352 ? ! frame_pointer_needed
27353 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27354 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27358 /* Define the offset between two registers, FROM to be eliminated and its
27359 replacement TO, at the start of a routine. */
27361 rs6000_initial_elimination_offset (int from, int to)
27363 rs6000_stack_t *info = rs6000_stack_info ();
27364 HOST_WIDE_INT offset;
27366 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27367 offset = info->push_p ? 0 : -info->total_size;
27368 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27370 offset = info->push_p ? 0 : -info->total_size;
27371 if (FRAME_GROWS_DOWNWARD)
27372 offset += info->fixed_size + info->vars_size + info->parm_size;
27374 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27375 offset = FRAME_GROWS_DOWNWARD
27376 ? info->fixed_size + info->vars_size + info->parm_size
27378 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27379 offset = info->total_size;
27380 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27381 offset = info->push_p ? info->total_size : 0;
27382 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27385 gcc_unreachable ();
27391 rs6000_dwarf_register_span (rtx reg)
27395 unsigned regno = REGNO (reg);
27396 enum machine_mode mode = GET_MODE (reg);
27400 && (SPE_VECTOR_MODE (GET_MODE (reg))
27401 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27402 && mode != SFmode && mode != SDmode && mode != SCmode)))
27407 regno = REGNO (reg);
27409 /* The duality of the SPE register size wreaks all kinds of havoc.
27410 This is a way of distinguishing r0 in 32-bits from r0 in
27412 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27413 gcc_assert (words <= 4);
27414 for (i = 0; i < words; i++, regno++)
27416 if (BYTES_BIG_ENDIAN)
27418 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27419 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27423 parts[2 * i] = gen_rtx_REG (SImode, regno);
27424 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27428 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27431 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27434 rs6000_init_dwarf_reg_sizes_extra (tree address)
27439 enum machine_mode mode = TYPE_MODE (char_type_node);
27440 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27441 rtx mem = gen_rtx_MEM (BLKmode, addr);
27442 rtx value = gen_int_mode (4, mode);
27444 for (i = 1201; i < 1232; i++)
27446 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27447 HOST_WIDE_INT offset
27448 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27450 emit_move_insn (adjust_address (mem, mode, offset), value);
27455 /* Map internal gcc register numbers to DWARF2 register numbers. */
27458 rs6000_dbx_register_number (unsigned int regno)
27460 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27462 if (regno == MQ_REGNO)
27464 if (regno == LR_REGNO)
27466 if (regno == CTR_REGNO)
27468 if (CR_REGNO_P (regno))
27469 return regno - CR0_REGNO + 86;
27470 if (regno == CA_REGNO)
27471 return 101; /* XER */
27472 if (ALTIVEC_REGNO_P (regno))
27473 return regno - FIRST_ALTIVEC_REGNO + 1124;
27474 if (regno == VRSAVE_REGNO)
27476 if (regno == VSCR_REGNO)
27478 if (regno == SPE_ACC_REGNO)
27480 if (regno == SPEFSCR_REGNO)
27482 /* SPE high reg number. We get these values of regno from
27483 rs6000_dwarf_register_span. */
27484 gcc_assert (regno >= 1200 && regno < 1232);
27488 /* target hook eh_return_filter_mode */
27489 static enum machine_mode
27490 rs6000_eh_return_filter_mode (void)
27492 return TARGET_32BIT ? SImode : word_mode;
27495 /* Target hook for scalar_mode_supported_p. */
27497 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27499 if (DECIMAL_FLOAT_MODE_P (mode))
27500 return default_decimal_float_supported_p ();
27502 return default_scalar_mode_supported_p (mode);
27505 /* Target hook for vector_mode_supported_p. */
27507 rs6000_vector_mode_supported_p (enum machine_mode mode)
27510 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27513 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27516 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27523 /* Target hook for invalid_arg_for_unprototyped_fn. */
27524 static const char *
27525 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27527 return (!rs6000_darwin64_abi
27529 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27530 && (funcdecl == NULL_TREE
27531 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27532 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27533 ? N_("AltiVec argument passed to unprototyped function")
27537 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27538 setup by using __stack_chk_fail_local hidden function instead of
27539 calling __stack_chk_fail directly. Otherwise it is better to call
27540 __stack_chk_fail directly. */
27543 rs6000_stack_protect_fail (void)
27545 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27546 ? default_hidden_stack_protect_fail ()
27547 : default_external_stack_protect_fail ();
27551 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27552 int num_operands ATTRIBUTE_UNUSED)
27554 if (rs6000_warn_cell_microcode)
27557 int insn_code_number = recog_memoized (insn);
27558 location_t location = locator_location (INSN_LOCATOR (insn));
27560 /* Punt on insns we cannot recognize. */
27561 if (insn_code_number < 0)
27564 temp = get_insn_template (insn_code_number, insn);
27566 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27567 warning_at (location, OPT_mwarn_cell_microcode,
27568 "emitting microcode insn %s\t[%s] #%d",
27569 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27570 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27571 warning_at (location, OPT_mwarn_cell_microcode,
27572 "emitting conditional microcode insn %s\t[%s] #%d",
27573 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27578 /* Mask options that we want to support inside of attribute((target)) and
27579 #pragma GCC target operations. Note, we do not include things like
27580 64/32-bit, endianess, hard/soft floating point, etc. that would have
27581 different calling sequences. */
27583 struct rs6000_opt_mask {
27584 const char *name; /* option name */
27585 int mask; /* mask to set */
27586 bool invert; /* invert sense of mask */
27587 bool valid_target; /* option is a target option */
27590 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27592 { "altivec", MASK_ALTIVEC, false, true },
27593 { "cmpb", MASK_CMPB, false, true },
27594 { "dlmzb", MASK_DLMZB, false, true },
27595 { "fprnd", MASK_FPRND, false, true },
27596 { "hard-dfp", MASK_DFP, false, true },
27597 { "isel", MASK_ISEL, false, true },
27598 { "mfcrf", MASK_MFCRF, false, true },
27599 { "mfpgpr", MASK_MFPGPR, false, true },
27600 { "mulhw", MASK_MULHW, false, true },
27601 { "multiple", MASK_MULTIPLE, false, true },
27602 { "update", MASK_NO_UPDATE, true , true },
27603 { "popcntb", MASK_POPCNTB, false, true },
27604 { "popcntd", MASK_POPCNTD, false, true },
27605 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27606 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27607 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27608 { "string", MASK_STRING, false, true },
27609 { "vsx", MASK_VSX, false, true },
27612 { "aix64", MASK_64BIT, false, false },
27613 { "aix32", MASK_64BIT, true, false },
27615 { "64", MASK_64BIT, false, false },
27616 { "32", MASK_64BIT, true, false },
27620 { "eabi", MASK_EABI, false, false },
27622 #ifdef MASK_LITTLE_ENDIAN
27623 { "little", MASK_LITTLE_ENDIAN, false, false },
27624 { "big", MASK_LITTLE_ENDIAN, true, false },
27626 #ifdef MASK_RELOCATABLE
27627 { "relocatable", MASK_RELOCATABLE, false, false },
27629 #ifdef MASK_STRICT_ALIGN
27630 { "strict-align", MASK_STRICT_ALIGN, false, false },
27632 { "power", MASK_POWER, false, false },
27633 { "power2", MASK_POWER2, false, false },
27634 { "powerpc", MASK_POWERPC, false, false },
27635 { "soft-float", MASK_SOFT_FLOAT, false, false },
27636 { "string", MASK_STRING, false, false },
27639 /* Option variables that we want to support inside attribute((target)) and
27640 #pragma GCC target operations. */
27642 struct rs6000_opt_var {
27643 const char *name; /* option name */
27644 size_t global_offset; /* offset of the option in global_options. */
27645 size_t target_offset; /* offset of the option in target optiosn. */
27648 static struct rs6000_opt_var const rs6000_opt_vars[] =
27651 offsetof (struct gcc_options, x_TARGET_FRIZ),
27652 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27653 { "avoid-indexed-addresses",
27654 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27655 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27657 offsetof (struct gcc_options, x_rs6000_paired_float),
27658 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27660 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27661 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27664 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27665 parsing. Return true if there were no errors. */
27668 rs6000_inner_target_options (tree args, bool attr_p)
27672 if (args == NULL_TREE)
27675 else if (TREE_CODE (args) == STRING_CST)
27677 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27680 while ((q = strtok (p, ",")) != NULL)
27682 bool error_p = false;
27683 bool not_valid_p = false;
27684 const char *cpu_opt = NULL;
27687 if (strncmp (q, "cpu=", 4) == 0)
27689 int cpu_index = rs6000_cpu_name_lookup (q+4);
27690 if (cpu_index >= 0)
27691 rs6000_cpu_index = cpu_index;
27698 else if (strncmp (q, "tune=", 5) == 0)
27700 int tune_index = rs6000_cpu_name_lookup (q+5);
27701 if (tune_index >= 0)
27702 rs6000_tune_index = tune_index;
27712 bool invert = false;
27716 if (strncmp (r, "no-", 3) == 0)
27722 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27723 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27725 int mask = rs6000_opt_masks[i].mask;
27727 if (!rs6000_opt_masks[i].valid_target)
27728 not_valid_p = true;
27732 target_flags_explicit |= mask;
27734 if (rs6000_opt_masks[i].invert)
27738 target_flags &= ~mask;
27740 target_flags |= mask;
27745 if (error_p && !not_valid_p)
27747 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27748 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27750 size_t j = rs6000_opt_vars[i].global_offset;
27751 ((int *) &global_options)[j] = !invert;
27760 const char *eprefix, *esuffix;
27765 eprefix = "__attribute__((__target__(";
27770 eprefix = "#pragma GCC target ";
27775 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27777 else if (not_valid_p)
27778 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27780 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27785 else if (TREE_CODE (args) == TREE_LIST)
27789 tree value = TREE_VALUE (args);
27792 bool ret2 = rs6000_inner_target_options (value, attr_p);
27796 args = TREE_CHAIN (args);
27798 while (args != NULL_TREE);
27802 gcc_unreachable ();
27807 /* Print out the target options as a list for -mdebug=target. */
27810 rs6000_debug_target_options (tree args, const char *prefix)
27812 if (args == NULL_TREE)
27813 fprintf (stderr, "%s<NULL>", prefix);
27815 else if (TREE_CODE (args) == STRING_CST)
27817 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27820 while ((q = strtok (p, ",")) != NULL)
27823 fprintf (stderr, "%s\"%s\"", prefix, q);
27828 else if (TREE_CODE (args) == TREE_LIST)
27832 tree value = TREE_VALUE (args);
27835 rs6000_debug_target_options (value, prefix);
27838 args = TREE_CHAIN (args);
27840 while (args != NULL_TREE);
27844 gcc_unreachable ();
27850 /* Hook to validate attribute((target("..."))). */
27853 rs6000_valid_attribute_p (tree fndecl,
27854 tree ARG_UNUSED (name),
27858 struct cl_target_option cur_target;
27860 tree old_optimize = build_optimization_node ();
27861 tree new_target, new_optimize;
27862 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27864 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27866 if (TARGET_DEBUG_TARGET)
27868 tree tname = DECL_NAME (fndecl);
27869 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27871 fprintf (stderr, "function: %.*s\n",
27872 (int) IDENTIFIER_LENGTH (tname),
27873 IDENTIFIER_POINTER (tname));
27875 fprintf (stderr, "function: unknown\n");
27877 fprintf (stderr, "args:");
27878 rs6000_debug_target_options (args, " ");
27879 fprintf (stderr, "\n");
27882 fprintf (stderr, "flags: 0x%x\n", flags);
27884 fprintf (stderr, "--------------------\n");
27887 old_optimize = build_optimization_node ();
27888 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27890 /* If the function changed the optimization levels as well as setting target
27891 options, start with the optimizations specified. */
27892 if (func_optimize && func_optimize != old_optimize)
27893 cl_optimization_restore (&global_options,
27894 TREE_OPTIMIZATION (func_optimize));
27896 /* The target attributes may also change some optimization flags, so update
27897 the optimization options if necessary. */
27898 cl_target_option_save (&cur_target, &global_options);
27899 rs6000_cpu_index = rs6000_tune_index = -1;
27900 ret = rs6000_inner_target_options (args, true);
27902 /* Set up any additional state. */
27905 ret = rs6000_option_override_internal (false);
27906 new_target = build_target_option_node ();
27911 new_optimize = build_optimization_node ();
27918 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27920 if (old_optimize != new_optimize)
27921 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27924 cl_target_option_restore (&global_options, &cur_target);
27926 if (old_optimize != new_optimize)
27927 cl_optimization_restore (&global_options,
27928 TREE_OPTIMIZATION (old_optimize));
27934 /* Hook to validate the current #pragma GCC target and set the state, and
27935 update the macros based on what was changed. If ARGS is NULL, then
27936 POP_TARGET is used to reset the options. */
27939 rs6000_pragma_target_parse (tree args, tree pop_target)
27944 if (TARGET_DEBUG_TARGET)
27946 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27947 fprintf (stderr, "args:");
27948 rs6000_debug_target_options (args, " ");
27949 fprintf (stderr, "\n");
27953 fprintf (stderr, "pop_target:\n");
27954 debug_tree (pop_target);
27957 fprintf (stderr, "pop_target: <NULL>\n");
27959 fprintf (stderr, "--------------------\n");
27965 cur_tree = ((pop_target)
27967 : target_option_default_node);
27968 cl_target_option_restore (&global_options,
27969 TREE_TARGET_OPTION (cur_tree));
27973 rs6000_cpu_index = rs6000_tune_index = -1;
27974 ret = rs6000_inner_target_options (args, false);
27975 cur_tree = build_target_option_node ();
27982 target_option_current_node = cur_tree;
27988 /* Remember the last target of rs6000_set_current_function. */
27989 static GTY(()) tree rs6000_previous_fndecl;
27991 /* Establish appropriate back-end context for processing the function
27992 FNDECL. The argument might be NULL to indicate processing at top
27993 level, outside of any function scope. */
27995 rs6000_set_current_function (tree fndecl)
27997 tree old_tree = (rs6000_previous_fndecl
27998 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
28001 tree new_tree = (fndecl
28002 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
28005 if (TARGET_DEBUG_TARGET)
28007 bool print_final = false;
28008 fprintf (stderr, "\n==================== rs6000_set_current_function");
28011 fprintf (stderr, ", fndecl %s (%p)",
28012 (DECL_NAME (fndecl)
28013 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
28014 : "<unknown>"), (void *)fndecl);
28016 if (rs6000_previous_fndecl)
28017 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
28019 fprintf (stderr, "\n");
28022 fprintf (stderr, "\nnew fndecl target specific options:\n");
28023 debug_tree (new_tree);
28024 print_final = true;
28029 fprintf (stderr, "\nold fndecl target specific options:\n");
28030 debug_tree (old_tree);
28031 print_final = true;
28035 fprintf (stderr, "--------------------\n");
28038 /* Only change the context if the function changes. This hook is called
28039 several times in the course of compiling a function, and we don't want to
28040 slow things down too much or call target_reinit when it isn't safe. */
28041 if (fndecl && fndecl != rs6000_previous_fndecl)
28043 rs6000_previous_fndecl = fndecl;
28044 if (old_tree == new_tree)
28049 cl_target_option_restore (&global_options,
28050 TREE_TARGET_OPTION (new_tree));
28056 struct cl_target_option *def
28057 = TREE_TARGET_OPTION (target_option_current_node);
28059 cl_target_option_restore (&global_options, def);
28066 /* Save the current options */
28069 rs6000_function_specific_save (struct cl_target_option *ptr)
28071 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28074 /* Restore the current options */
28077 rs6000_function_specific_restore (struct cl_target_option *ptr)
28079 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28080 (void) rs6000_option_override_internal (false);
28083 /* Print the current options */
28086 rs6000_function_specific_print (FILE *file, int indent,
28087 struct cl_target_option *ptr)
28090 int flags = ptr->x_target_flags;
28092 /* Print the various mask options. */
28093 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28094 if ((flags & rs6000_opt_masks[i].mask) != 0)
28096 flags &= ~ rs6000_opt_masks[i].mask;
28097 fprintf (file, "%*s-m%s%s\n", indent, "",
28098 rs6000_opt_masks[i].invert ? "no-" : "",
28099 rs6000_opt_masks[i].name);
28102 /* Print the various options that are variables. */
28103 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28105 size_t j = rs6000_opt_vars[i].target_offset;
28106 if (((signed char *) ptr)[j])
28107 fprintf (file, "%*s-m%s\n", indent, "",
28108 rs6000_opt_vars[i].name);
28113 /* Hook to determine if one function can safely inline another. */
28116 rs6000_can_inline_p (tree caller, tree callee)
28119 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28120 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28122 /* If callee has no option attributes, then it is ok to inline. */
28126 /* If caller has no option attributes, but callee does then it is not ok to
28128 else if (!caller_tree)
28133 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28134 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28136 /* Callee's options should a subset of the caller's, i.e. a vsx function
28137 can inline an altivec function but a non-vsx function can't inline a
28139 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28140 == callee_opts->x_target_flags)
28144 if (TARGET_DEBUG_TARGET)
28145 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28146 (DECL_NAME (caller)
28147 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28149 (DECL_NAME (callee)
28150 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28152 (ret ? "can" : "cannot"));
28157 /* Allocate a stack temp and fixup the address so it meets the particular
28158 memory requirements (either offetable or REG+REG addressing). */
28161 rs6000_allocate_stack_temp (enum machine_mode mode,
28162 bool offsettable_p,
28165 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28166 rtx addr = XEXP (stack, 0);
28167 int strict_p = (reload_in_progress || reload_completed);
28169 if (!legitimate_indirect_address_p (addr, strict_p))
28172 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28173 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28175 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28176 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28182 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28183 to such a form to deal with memory reference instructions like STFIWX that
28184 only take reg+reg addressing. */
28187 rs6000_address_for_fpconvert (rtx x)
28189 int strict_p = (reload_in_progress || reload_completed);
28192 gcc_assert (MEM_P (x));
28193 addr = XEXP (x, 0);
28194 if (! legitimate_indirect_address_p (addr, strict_p)
28195 && ! legitimate_indexed_address_p (addr, strict_p))
28197 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28199 rtx reg = XEXP (addr, 0);
28200 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28201 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28202 gcc_assert (REG_P (reg));
28203 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28206 else if (GET_CODE (addr) == PRE_MODIFY)
28208 rtx reg = XEXP (addr, 0);
28209 rtx expr = XEXP (addr, 1);
28210 gcc_assert (REG_P (reg));
28211 gcc_assert (GET_CODE (expr) == PLUS);
28212 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28216 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28222 /* Given a memory reference, if it is not in the form for altivec memory
28223 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28224 convert to the altivec format. */
28227 rs6000_address_for_altivec (rtx x)
28229 gcc_assert (MEM_P (x));
28230 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28232 rtx addr = XEXP (x, 0);
28233 int strict_p = (reload_in_progress || reload_completed);
28235 if (!legitimate_indexed_address_p (addr, strict_p)
28236 && !legitimate_indirect_address_p (addr, strict_p))
28237 addr = copy_to_mode_reg (Pmode, addr);
28239 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28240 x = change_address (x, GET_MODE (x), addr);
28247 #include "gt-rs6000.h"