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);
1215 static bool rs6000_cannot_force_const_mem (rtx);
1217 /* Hash table stuff for keeping track of TOC entries. */
1219 struct GTY(()) toc_hash_struct
1221 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1222 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1224 enum machine_mode key_mode;
1228 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1230 /* Hash table to keep track of the argument types for builtin functions. */
1232 struct GTY(()) builtin_hash_struct
1235 enum machine_mode mode[4]; /* return value + 3 arguments. */
1236 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1239 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1241 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1242 static void rs6000_function_specific_save (struct cl_target_option *);
1243 static void rs6000_function_specific_restore (struct cl_target_option *);
1244 static void rs6000_function_specific_print (FILE *, int,
1245 struct cl_target_option *);
1246 static bool rs6000_can_inline_p (tree, tree);
1247 static void rs6000_set_current_function (tree);
1250 /* Default register names. */
1251 char rs6000_reg_names[][8] =
1253 "0", "1", "2", "3", "4", "5", "6", "7",
1254 "8", "9", "10", "11", "12", "13", "14", "15",
1255 "16", "17", "18", "19", "20", "21", "22", "23",
1256 "24", "25", "26", "27", "28", "29", "30", "31",
1257 "0", "1", "2", "3", "4", "5", "6", "7",
1258 "8", "9", "10", "11", "12", "13", "14", "15",
1259 "16", "17", "18", "19", "20", "21", "22", "23",
1260 "24", "25", "26", "27", "28", "29", "30", "31",
1261 "mq", "lr", "ctr","ap",
1262 "0", "1", "2", "3", "4", "5", "6", "7",
1264 /* AltiVec registers. */
1265 "0", "1", "2", "3", "4", "5", "6", "7",
1266 "8", "9", "10", "11", "12", "13", "14", "15",
1267 "16", "17", "18", "19", "20", "21", "22", "23",
1268 "24", "25", "26", "27", "28", "29", "30", "31",
1270 /* SPE registers. */
1271 "spe_acc", "spefscr",
1272 /* Soft frame pointer. */
1276 #ifdef TARGET_REGNAMES
1277 static const char alt_reg_names[][8] =
1279 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1280 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1281 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1282 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1283 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1284 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1285 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1286 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1287 "mq", "lr", "ctr", "ap",
1288 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1290 /* AltiVec registers. */
1291 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1292 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1293 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1294 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1296 /* SPE registers. */
1297 "spe_acc", "spefscr",
1298 /* Soft frame pointer. */
1303 /* Table of valid machine attributes. */
1305 static const struct attribute_spec rs6000_attribute_table[] =
1307 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1308 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1309 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1310 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1311 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1312 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1313 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1314 SUBTARGET_ATTRIBUTE_TABLE,
1316 { NULL, 0, 0, false, false, false, NULL }
1319 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1320 static const struct default_options rs6000_option_optimization_table[] =
1322 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1323 { OPT_LEVELS_NONE, 0, NULL, 0 }
1326 #ifndef MASK_STRICT_ALIGN
1327 #define MASK_STRICT_ALIGN 0
1329 #ifndef TARGET_PROFILE_KERNEL
1330 #define TARGET_PROFILE_KERNEL 0
1333 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1334 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1336 /* Initialize the GCC target structure. */
1337 #undef TARGET_ATTRIBUTE_TABLE
1338 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1339 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1340 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1341 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1342 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1344 #undef TARGET_ASM_ALIGNED_DI_OP
1345 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1347 /* Default unaligned ops are only provided for ELF. Find the ops needed
1348 for non-ELF systems. */
1349 #ifndef OBJECT_FORMAT_ELF
1351 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1353 #undef TARGET_ASM_UNALIGNED_HI_OP
1354 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1355 #undef TARGET_ASM_UNALIGNED_SI_OP
1356 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1357 #undef TARGET_ASM_UNALIGNED_DI_OP
1358 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1361 #undef TARGET_ASM_UNALIGNED_HI_OP
1362 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1363 #undef TARGET_ASM_UNALIGNED_SI_OP
1364 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1365 #undef TARGET_ASM_UNALIGNED_DI_OP
1366 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1367 #undef TARGET_ASM_ALIGNED_DI_OP
1368 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1372 /* This hook deals with fixups for relocatable code and DI-mode objects
1374 #undef TARGET_ASM_INTEGER
1375 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1377 #ifdef HAVE_GAS_HIDDEN
1378 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1379 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1382 #undef TARGET_HAVE_TLS
1383 #define TARGET_HAVE_TLS HAVE_AS_TLS
1385 #undef TARGET_CANNOT_FORCE_CONST_MEM
1386 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1388 #undef TARGET_DELEGITIMIZE_ADDRESS
1389 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1391 #undef TARGET_ASM_FUNCTION_PROLOGUE
1392 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1393 #undef TARGET_ASM_FUNCTION_EPILOGUE
1394 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1396 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1397 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1399 #undef TARGET_LEGITIMIZE_ADDRESS
1400 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1402 #undef TARGET_SCHED_VARIABLE_ISSUE
1403 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1405 #undef TARGET_SCHED_ISSUE_RATE
1406 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1407 #undef TARGET_SCHED_ADJUST_COST
1408 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1409 #undef TARGET_SCHED_ADJUST_PRIORITY
1410 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1411 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1412 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1413 #undef TARGET_SCHED_INIT
1414 #define TARGET_SCHED_INIT rs6000_sched_init
1415 #undef TARGET_SCHED_FINISH
1416 #define TARGET_SCHED_FINISH rs6000_sched_finish
1417 #undef TARGET_SCHED_REORDER
1418 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1419 #undef TARGET_SCHED_REORDER2
1420 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1422 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1423 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1425 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1426 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1428 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1429 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1430 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1431 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1432 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1433 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1434 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1435 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1437 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1438 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1439 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1440 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1441 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1442 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1443 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1444 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1445 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1446 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1447 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1448 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1449 rs6000_builtin_support_vector_misalignment
1450 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1451 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1452 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1453 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1454 rs6000_builtin_vectorization_cost
1455 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1456 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1457 rs6000_preferred_simd_mode
1459 #undef TARGET_INIT_BUILTINS
1460 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1461 #undef TARGET_BUILTIN_DECL
1462 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1464 #undef TARGET_EXPAND_BUILTIN
1465 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1467 #undef TARGET_MANGLE_TYPE
1468 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1470 #undef TARGET_INIT_LIBFUNCS
1471 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1474 #undef TARGET_BINDS_LOCAL_P
1475 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1478 #undef TARGET_MS_BITFIELD_LAYOUT_P
1479 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1481 #undef TARGET_ASM_OUTPUT_MI_THUNK
1482 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1484 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1485 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1487 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1488 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1490 #undef TARGET_INVALID_WITHIN_DOLOOP
1491 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1493 #undef TARGET_REGISTER_MOVE_COST
1494 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1495 #undef TARGET_MEMORY_MOVE_COST
1496 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1497 #undef TARGET_RTX_COSTS
1498 #define TARGET_RTX_COSTS rs6000_rtx_costs
1499 #undef TARGET_ADDRESS_COST
1500 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1502 #undef TARGET_DWARF_REGISTER_SPAN
1503 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1505 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1506 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1508 /* On rs6000, function arguments are promoted, as are function return
1510 #undef TARGET_PROMOTE_FUNCTION_MODE
1511 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1513 #undef TARGET_RETURN_IN_MEMORY
1514 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1516 #undef TARGET_SETUP_INCOMING_VARARGS
1517 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1519 /* Always strict argument naming on rs6000. */
1520 #undef TARGET_STRICT_ARGUMENT_NAMING
1521 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1522 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1523 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1524 #undef TARGET_SPLIT_COMPLEX_ARG
1525 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1526 #undef TARGET_MUST_PASS_IN_STACK
1527 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1528 #undef TARGET_PASS_BY_REFERENCE
1529 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1530 #undef TARGET_ARG_PARTIAL_BYTES
1531 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1532 #undef TARGET_FUNCTION_ARG_ADVANCE
1533 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1534 #undef TARGET_FUNCTION_ARG
1535 #define TARGET_FUNCTION_ARG rs6000_function_arg
1536 #undef TARGET_FUNCTION_ARG_BOUNDARY
1537 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1539 #undef TARGET_BUILD_BUILTIN_VA_LIST
1540 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1542 #undef TARGET_EXPAND_BUILTIN_VA_START
1543 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1545 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1546 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1548 #undef TARGET_EH_RETURN_FILTER_MODE
1549 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1551 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1552 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1554 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1555 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1557 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1558 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1560 #undef TARGET_HANDLE_OPTION
1561 #define TARGET_HANDLE_OPTION rs6000_handle_option
1563 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1564 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1566 #undef TARGET_OPTION_OVERRIDE
1567 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1569 #undef TARGET_OPTION_INIT_STRUCT
1570 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1572 #undef TARGET_OPTION_DEFAULT_PARAMS
1573 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1575 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1576 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1578 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1579 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1580 rs6000_builtin_vectorized_function
1582 #undef TARGET_DEFAULT_TARGET_FLAGS
1583 #define TARGET_DEFAULT_TARGET_FLAGS \
1586 #undef TARGET_STACK_PROTECT_FAIL
1587 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1589 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1590 The PowerPC architecture requires only weak consistency among
1591 processors--that is, memory accesses between processors need not be
1592 sequentially consistent and memory accesses among processors can occur
1593 in any order. The ability to order memory accesses weakly provides
1594 opportunities for more efficient use of the system bus. Unless a
1595 dependency exists, the 604e allows read operations to precede store
1597 #undef TARGET_RELAXED_ORDERING
1598 #define TARGET_RELAXED_ORDERING true
1601 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1602 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1605 /* Use a 32-bit anchor range. This leads to sequences like:
1607 addis tmp,anchor,high
1610 where tmp itself acts as an anchor, and can be shared between
1611 accesses to the same 64k page. */
1612 #undef TARGET_MIN_ANCHOR_OFFSET
1613 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1614 #undef TARGET_MAX_ANCHOR_OFFSET
1615 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1616 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1617 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1619 #undef TARGET_BUILTIN_RECIPROCAL
1620 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1622 #undef TARGET_EXPAND_TO_RTL_HOOK
1623 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1625 #undef TARGET_INSTANTIATE_DECLS
1626 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1628 #undef TARGET_SECONDARY_RELOAD
1629 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1631 #undef TARGET_IRA_COVER_CLASSES
1632 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1634 #undef TARGET_LEGITIMATE_ADDRESS_P
1635 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1637 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1638 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1640 #undef TARGET_CAN_ELIMINATE
1641 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1643 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1644 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1646 #undef TARGET_TRAMPOLINE_INIT
1647 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1649 #undef TARGET_FUNCTION_VALUE
1650 #define TARGET_FUNCTION_VALUE rs6000_function_value
1652 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1653 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1655 #undef TARGET_OPTION_SAVE
1656 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1658 #undef TARGET_OPTION_RESTORE
1659 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1661 #undef TARGET_OPTION_PRINT
1662 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1664 #undef TARGET_CAN_INLINE_P
1665 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1667 #undef TARGET_SET_CURRENT_FUNCTION
1668 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1670 struct gcc_target targetm = TARGET_INITIALIZER;
1673 /* Simplifications for entries below. */
1676 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1677 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1680 /* Some OSs don't support saving the high part of 64-bit registers on context
1681 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1682 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1683 either, the user must explicitly specify them and we won't interfere with
1684 the user's specification. */
1687 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1688 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1689 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1690 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1691 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1692 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1693 | MASK_RECIP_PRECISION)
1696 /* Masks for instructions set at various powerpc ISAs. */
1698 ISA_2_1_MASKS = MASK_MFCRF,
1699 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1700 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1702 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1703 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1704 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1705 server and embedded. */
1706 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1707 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1708 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1710 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1711 altivec is a win so enable it. */
1712 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1713 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1717 /* This table occasionally claims that a processor does not support a
1718 particular feature even though it does, but the feature is slower than the
1719 alternative. Thus, it shouldn't be relied on as a complete description of
1720 the processor's support.
1722 Please keep this list in order, and don't forget to update the documentation
1723 in invoke.texi when adding a new processor or flag. */
1727 const char *const name; /* Canonical processor name. */
1728 const enum processor_type processor; /* Processor type enum value. */
1729 const int target_enable; /* Target flags to enable. */
1732 static struct rs6000_ptt const processor_target_table[] =
1734 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1735 {"403", PROCESSOR_PPC403,
1736 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1737 {"405", PROCESSOR_PPC405,
1738 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1739 {"405fp", PROCESSOR_PPC405,
1740 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1741 {"440", PROCESSOR_PPC440,
1742 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1743 {"440fp", PROCESSOR_PPC440,
1744 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1745 {"464", PROCESSOR_PPC440,
1746 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1747 {"464fp", PROCESSOR_PPC440,
1748 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1749 {"476", PROCESSOR_PPC476,
1750 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1751 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1752 {"476fp", PROCESSOR_PPC476,
1753 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1754 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1755 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1756 {"601", PROCESSOR_PPC601,
1757 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1758 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1759 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1760 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1761 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1763 {"620", PROCESSOR_PPC620,
1764 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1765 {"630", PROCESSOR_PPC630,
1766 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1767 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1768 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1769 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1770 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1771 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1772 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1773 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1774 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1776 /* 8548 has a dummy entry for now. */
1777 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1779 {"a2", PROCESSOR_PPCA2,
1780 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1781 | MASK_CMPB | MASK_NO_UPDATE },
1782 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1783 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1784 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1786 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1787 | MASK_PPC_GFXOPT | MASK_ISEL},
1788 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1789 {"970", PROCESSOR_POWER4,
1790 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1791 {"cell", PROCESSOR_CELL,
1792 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1793 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1794 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1795 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1796 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1797 {"G5", PROCESSOR_POWER4,
1798 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1799 {"titan", PROCESSOR_TITAN,
1800 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1801 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1802 {"power2", PROCESSOR_POWER,
1803 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1804 {"power3", PROCESSOR_PPC630,
1805 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1806 {"power4", PROCESSOR_POWER4,
1807 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1809 {"power5", PROCESSOR_POWER5,
1810 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1811 | MASK_MFCRF | MASK_POPCNTB},
1812 {"power5+", PROCESSOR_POWER5,
1813 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1814 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1815 {"power6", PROCESSOR_POWER6,
1816 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1817 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1818 | MASK_RECIP_PRECISION},
1819 {"power6x", PROCESSOR_POWER6,
1820 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1821 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1822 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1823 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1824 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1825 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1826 | MASK_VSX | MASK_RECIP_PRECISION},
1827 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1828 {"powerpc64", PROCESSOR_POWERPC64,
1829 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1830 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1831 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1832 {"rios2", PROCESSOR_RIOS2,
1833 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1834 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1835 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1836 {"rs64", PROCESSOR_RS64A,
1837 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1840 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1844 rs6000_cpu_name_lookup (const char *name)
1850 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1851 if (! strcmp (name, processor_target_table[i].name))
1859 /* Return number of consecutive hard regs needed starting at reg REGNO
1860 to hold something of mode MODE.
1861 This is ordinarily the length in words of a value of mode MODE
1862 but can be less for certain modes in special long registers.
1864 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1865 scalar instructions. The upper 32 bits are only available to the
1868 POWER and PowerPC GPRs hold 32 bits worth;
1869 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1872 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1874 unsigned HOST_WIDE_INT reg_size;
1876 if (FP_REGNO_P (regno))
1877 reg_size = (VECTOR_MEM_VSX_P (mode)
1878 ? UNITS_PER_VSX_WORD
1879 : UNITS_PER_FP_WORD);
1881 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1882 reg_size = UNITS_PER_SPE_WORD;
1884 else if (ALTIVEC_REGNO_P (regno))
1885 reg_size = UNITS_PER_ALTIVEC_WORD;
1887 /* The value returned for SCmode in the E500 double case is 2 for
1888 ABI compatibility; storing an SCmode value in a single register
1889 would require function_arg and rs6000_spe_function_arg to handle
1890 SCmode so as to pass the value correctly in a pair of
1892 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1893 && !DECIMAL_FLOAT_MODE_P (mode))
1894 reg_size = UNITS_PER_FP_WORD;
1897 reg_size = UNITS_PER_WORD;
1899 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1902 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1905 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1907 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1909 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1910 implementations. Don't allow an item to be split between a FP register
1911 and an Altivec register. */
1912 if (VECTOR_MEM_VSX_P (mode))
1914 if (FP_REGNO_P (regno))
1915 return FP_REGNO_P (last_regno);
1917 if (ALTIVEC_REGNO_P (regno))
1918 return ALTIVEC_REGNO_P (last_regno);
1921 /* The GPRs can hold any mode, but values bigger than one register
1922 cannot go past R31. */
1923 if (INT_REGNO_P (regno))
1924 return INT_REGNO_P (last_regno);
1926 /* The float registers (except for VSX vector modes) can only hold floating
1927 modes and DImode. This excludes the 32-bit decimal float mode for
1929 if (FP_REGNO_P (regno))
1931 if (SCALAR_FLOAT_MODE_P (mode)
1932 && (mode != TDmode || (regno % 2) == 0)
1933 && FP_REGNO_P (last_regno))
1936 if (GET_MODE_CLASS (mode) == MODE_INT
1937 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1940 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1941 && PAIRED_VECTOR_MODE (mode))
1947 /* The CR register can only hold CC modes. */
1948 if (CR_REGNO_P (regno))
1949 return GET_MODE_CLASS (mode) == MODE_CC;
1951 if (CA_REGNO_P (regno))
1952 return mode == BImode;
1954 /* AltiVec only in AldyVec registers. */
1955 if (ALTIVEC_REGNO_P (regno))
1956 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1958 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1959 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1962 /* We cannot put TImode anywhere except general register and it must be able
1963 to fit within the register set. In the future, allow TImode in the
1964 Altivec or VSX registers. */
1966 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1969 /* Print interesting facts about registers. */
1971 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1975 for (r = first_regno; r <= last_regno; ++r)
1977 const char *comma = "";
1980 if (first_regno == last_regno)
1981 fprintf (stderr, "%s:\t", reg_name);
1983 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1986 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1987 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1991 fprintf (stderr, ",\n\t");
1996 if (rs6000_hard_regno_nregs[m][r] > 1)
1997 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1998 rs6000_hard_regno_nregs[m][r]);
2000 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2005 if (call_used_regs[r])
2009 fprintf (stderr, ",\n\t");
2014 len += fprintf (stderr, "%s%s", comma, "call-used");
2022 fprintf (stderr, ",\n\t");
2027 len += fprintf (stderr, "%s%s", comma, "fixed");
2033 fprintf (stderr, ",\n\t");
2037 fprintf (stderr, "%sregno = %d\n", comma, r);
2041 #define DEBUG_FMT_D "%-32s= %d\n"
2042 #define DEBUG_FMT_S "%-32s= %s\n"
2044 /* Print various interesting information with -mdebug=reg. */
2046 rs6000_debug_reg_global (void)
2048 static const char *const tf[2] = { "false", "true" };
2049 const char *nl = (const char *)0;
2051 char costly_num[20];
2053 const char *costly_str;
2054 const char *nop_str;
2055 const char *trace_str;
2056 const char *abi_str;
2057 const char *cmodel_str;
2059 /* Map enum rs6000_vector to string. */
2060 static const char *rs6000_debug_vector_unit[] = {
2069 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2070 LAST_VIRTUAL_REGISTER);
2071 rs6000_debug_reg_print (0, 31, "gr");
2072 rs6000_debug_reg_print (32, 63, "fp");
2073 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2076 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2077 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2078 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2079 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2080 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2081 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2082 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2083 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2084 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2088 "d reg_class = %s\n"
2089 "f reg_class = %s\n"
2090 "v reg_class = %s\n"
2091 "wa reg_class = %s\n"
2092 "wd reg_class = %s\n"
2093 "wf reg_class = %s\n"
2094 "ws reg_class = %s\n\n",
2095 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2096 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2097 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2098 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2099 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2101 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2103 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2104 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2107 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2109 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2110 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2116 if (rs6000_recip_control)
2118 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2120 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2121 if (rs6000_recip_bits[m])
2124 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2126 (RS6000_RECIP_AUTO_RE_P (m)
2128 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2129 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2131 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2134 fputs ("\n", stderr);
2137 if (rs6000_cpu_index >= 0)
2138 fprintf (stderr, DEBUG_FMT_S, "cpu",
2139 processor_target_table[rs6000_cpu_index].name);
2141 if (rs6000_tune_index >= 0)
2142 fprintf (stderr, DEBUG_FMT_S, "tune",
2143 processor_target_table[rs6000_tune_index].name);
2145 switch (rs6000_sched_costly_dep)
2147 case max_dep_latency:
2148 costly_str = "max_dep_latency";
2152 costly_str = "no_dep_costly";
2155 case all_deps_costly:
2156 costly_str = "all_deps_costly";
2159 case true_store_to_load_dep_costly:
2160 costly_str = "true_store_to_load_dep_costly";
2163 case store_to_load_dep_costly:
2164 costly_str = "store_to_load_dep_costly";
2168 costly_str = costly_num;
2169 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2173 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2175 switch (rs6000_sched_insert_nops)
2177 case sched_finish_regroup_exact:
2178 nop_str = "sched_finish_regroup_exact";
2181 case sched_finish_pad_groups:
2182 nop_str = "sched_finish_pad_groups";
2185 case sched_finish_none:
2186 nop_str = "sched_finish_none";
2191 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2195 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2197 switch (rs6000_sdata)
2204 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2208 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2212 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2217 switch (rs6000_traceback)
2219 case traceback_default: trace_str = "default"; break;
2220 case traceback_none: trace_str = "none"; break;
2221 case traceback_part: trace_str = "part"; break;
2222 case traceback_full: trace_str = "full"; break;
2223 default: trace_str = "unknown"; break;
2226 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2228 switch (rs6000_current_cmodel)
2230 case CMODEL_SMALL: cmodel_str = "small"; break;
2231 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2232 case CMODEL_LARGE: cmodel_str = "large"; break;
2233 default: cmodel_str = "unknown"; break;
2236 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2238 switch (rs6000_current_abi)
2240 case ABI_NONE: abi_str = "none"; break;
2241 case ABI_AIX: abi_str = "aix"; break;
2242 case ABI_V4: abi_str = "V4"; break;
2243 case ABI_DARWIN: abi_str = "darwin"; break;
2244 default: abi_str = "unknown"; break;
2247 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2249 if (rs6000_altivec_abi)
2250 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2253 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2255 if (rs6000_darwin64_abi)
2256 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2258 if (rs6000_float_gprs)
2259 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2261 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2262 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2263 tf[!!rs6000_align_branch_targets]);
2264 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2265 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2266 rs6000_long_double_type_size);
2267 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2268 (int)rs6000_sched_restricted_insns_priority);
2271 /* Initialize the various global tables that are based on register size. */
2273 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2279 /* Precalculate REGNO_REG_CLASS. */
2280 rs6000_regno_regclass[0] = GENERAL_REGS;
2281 for (r = 1; r < 32; ++r)
2282 rs6000_regno_regclass[r] = BASE_REGS;
2284 for (r = 32; r < 64; ++r)
2285 rs6000_regno_regclass[r] = FLOAT_REGS;
2287 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2288 rs6000_regno_regclass[r] = NO_REGS;
2290 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2291 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2293 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2294 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2295 rs6000_regno_regclass[r] = CR_REGS;
2297 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2298 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2299 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2300 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2301 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2302 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2303 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2304 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2305 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2306 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2308 /* Precalculate vector information, this must be set up before the
2309 rs6000_hard_regno_nregs_internal below. */
2310 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2312 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2313 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2314 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2317 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2318 rs6000_constraints[c] = NO_REGS;
2320 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2321 believes it can use native alignment or still uses 128-bit alignment. */
2322 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2333 /* V2DF mode, VSX only. */
2336 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2337 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2338 rs6000_vector_align[V2DFmode] = align64;
2341 /* V4SF mode, either VSX or Altivec. */
2344 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2345 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2346 rs6000_vector_align[V4SFmode] = align32;
2348 else if (TARGET_ALTIVEC)
2350 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2351 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2352 rs6000_vector_align[V4SFmode] = align32;
2355 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2359 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2360 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2361 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2362 rs6000_vector_align[V4SImode] = align32;
2363 rs6000_vector_align[V8HImode] = align32;
2364 rs6000_vector_align[V16QImode] = align32;
2368 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2369 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2370 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2374 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2375 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2376 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2380 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2381 Altivec doesn't have 64-bit support. */
2384 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2385 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2386 rs6000_vector_align[V2DImode] = align64;
2389 /* DFmode, see if we want to use the VSX unit. */
2390 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2392 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2393 rs6000_vector_mem[DFmode]
2394 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2395 rs6000_vector_align[DFmode] = align64;
2398 /* TODO add SPE and paired floating point vector support. */
2400 /* Register class constaints for the constraints that depend on compile
2402 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2403 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2405 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2406 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2410 /* At present, we just use VSX_REGS, but we have different constraints
2411 based on the use, in case we want to fine tune the default register
2412 class used. wa = any VSX register, wf = register class to use for
2413 V4SF, wd = register class to use for V2DF, and ws = register classs to
2414 use for DF scalars. */
2415 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2416 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2417 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2418 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2424 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2426 /* Set up the reload helper functions. */
2427 if (TARGET_VSX || TARGET_ALTIVEC)
2431 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2432 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2433 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2434 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2435 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2436 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2437 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2438 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2439 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2440 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2441 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2442 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2446 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2447 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2448 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2449 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2450 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2451 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2452 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2453 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2454 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2455 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2456 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2457 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2461 /* Precalculate HARD_REGNO_NREGS. */
2462 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2463 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2464 rs6000_hard_regno_nregs[m][r]
2465 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2467 /* Precalculate HARD_REGNO_MODE_OK. */
2468 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2469 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2470 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2471 rs6000_hard_regno_mode_ok_p[m][r] = true;
2473 /* Precalculate CLASS_MAX_NREGS sizes. */
2474 for (c = 0; c < LIM_REG_CLASSES; ++c)
2478 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2479 reg_size = UNITS_PER_VSX_WORD;
2481 else if (c == ALTIVEC_REGS)
2482 reg_size = UNITS_PER_ALTIVEC_WORD;
2484 else if (c == FLOAT_REGS)
2485 reg_size = UNITS_PER_FP_WORD;
2488 reg_size = UNITS_PER_WORD;
2490 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2491 rs6000_class_max_nregs[m][c]
2492 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2495 if (TARGET_E500_DOUBLE)
2496 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2498 /* Calculate which modes to automatically generate code to use a the
2499 reciprocal divide and square root instructions. In the future, possibly
2500 automatically generate the instructions even if the user did not specify
2501 -mrecip. The older machines double precision reciprocal sqrt estimate is
2502 not accurate enough. */
2503 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2505 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2507 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2508 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2509 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2510 if (VECTOR_UNIT_VSX_P (V2DFmode))
2511 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2513 if (TARGET_FRSQRTES)
2514 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2516 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2517 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2518 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2519 if (VECTOR_UNIT_VSX_P (V2DFmode))
2520 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2522 if (rs6000_recip_control)
2524 if (!flag_finite_math_only)
2525 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2526 if (flag_trapping_math)
2527 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2528 if (!flag_reciprocal_math)
2529 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2530 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2532 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2533 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2534 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2536 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2537 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2538 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2540 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2541 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2542 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2544 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2545 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2546 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2548 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2549 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2550 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2552 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2553 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2554 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2556 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2557 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2558 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2560 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2561 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2562 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2566 if (global_init_p || TARGET_DEBUG_TARGET)
2568 if (TARGET_DEBUG_REG)
2569 rs6000_debug_reg_global ();
2571 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2573 "SImode variable mult cost = %d\n"
2574 "SImode constant mult cost = %d\n"
2575 "SImode short constant mult cost = %d\n"
2576 "DImode multipliciation cost = %d\n"
2577 "SImode division cost = %d\n"
2578 "DImode division cost = %d\n"
2579 "Simple fp operation cost = %d\n"
2580 "DFmode multiplication cost = %d\n"
2581 "SFmode division cost = %d\n"
2582 "DFmode division cost = %d\n"
2583 "cache line size = %d\n"
2584 "l1 cache size = %d\n"
2585 "l2 cache size = %d\n"
2586 "simultaneous prefetches = %d\n"
2589 rs6000_cost->mulsi_const,
2590 rs6000_cost->mulsi_const9,
2598 rs6000_cost->cache_line_size,
2599 rs6000_cost->l1_cache_size,
2600 rs6000_cost->l2_cache_size,
2601 rs6000_cost->simultaneous_prefetches);
2606 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2609 darwin_rs6000_override_options (void)
2611 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2613 rs6000_altivec_abi = 1;
2614 TARGET_ALTIVEC_VRSAVE = 1;
2615 rs6000_current_abi = ABI_DARWIN;
2617 if (DEFAULT_ABI == ABI_DARWIN
2619 darwin_one_byte_bool = 1;
2621 if (TARGET_64BIT && ! TARGET_POWERPC64)
2623 target_flags |= MASK_POWERPC64;
2624 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2628 rs6000_default_long_calls = 1;
2629 target_flags |= MASK_SOFT_FLOAT;
2632 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2634 if (!flag_mkernel && !flag_apple_kext
2636 && ! (target_flags_explicit & MASK_ALTIVEC))
2637 target_flags |= MASK_ALTIVEC;
2639 /* Unless the user (not the configurer) has explicitly overridden
2640 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2641 G4 unless targetting the kernel. */
2644 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2645 && ! (target_flags_explicit & MASK_ALTIVEC)
2646 && ! rs6000_select[1].string)
2648 target_flags |= MASK_ALTIVEC;
2653 /* If not otherwise specified by a target, make 'long double' equivalent to
2656 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2657 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2660 /* Override command line options. Mostly we process the processor type and
2661 sometimes adjust other TARGET_ options. */
2664 rs6000_option_override_internal (bool global_init_p)
2667 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2671 struct cl_target_option *main_target_opt
2672 = ((global_init_p || target_option_default_node == NULL)
2673 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2675 /* Numerous experiment shows that IRA based loop pressure
2676 calculation works better for RTL loop invariant motion on targets
2677 with enough (>= 32) registers. It is an expensive optimization.
2678 So it is on only for peak performance. */
2679 if (optimize >= 3 && global_init_p)
2680 flag_ira_loop_pressure = 1;
2682 /* Set the pointer size. */
2685 rs6000_pmode = (int)DImode;
2686 rs6000_pointer_size = 64;
2690 rs6000_pmode = (int)SImode;
2691 rs6000_pointer_size = 32;
2694 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2695 #ifdef OS_MISSING_POWERPC64
2696 if (OS_MISSING_POWERPC64)
2697 set_masks &= ~MASK_POWERPC64;
2699 #ifdef OS_MISSING_ALTIVEC
2700 if (OS_MISSING_ALTIVEC)
2701 set_masks &= ~MASK_ALTIVEC;
2704 /* Don't override by the processor default if given explicitly. */
2705 set_masks &= ~target_flags_explicit;
2707 /* Identify the processor type. */
2710 if (TARGET_POWERPC64)
2711 default_cpu = "powerpc64";
2712 else if (TARGET_POWERPC)
2713 default_cpu = "powerpc";
2716 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2717 the cpu in a target attribute or pragma, but did not specify a tuning
2718 option, use the cpu for the tuning option rather than the option specified
2719 with -mtune on the command line. */
2720 if (rs6000_cpu_index > 0)
2721 cpu_index = rs6000_cpu_index;
2722 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2723 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2725 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2727 if (rs6000_tune_index > 0)
2728 tune_index = rs6000_tune_index;
2730 rs6000_tune_index = tune_index = cpu_index;
2734 target_flags &= ~set_masks;
2735 target_flags |= (processor_target_table[cpu_index].target_enable
2739 rs6000_cpu = ((tune_index >= 0)
2740 ? processor_target_table[tune_index].processor
2742 ? PROCESSOR_DEFAULT64
2743 : PROCESSOR_DEFAULT));
2745 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2746 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2749 error ("AltiVec not supported in this target");
2751 error ("SPE not supported in this target");
2754 /* Disable Cell microcode if we are optimizing for the Cell
2755 and not optimizing for size. */
2756 if (rs6000_gen_cell_microcode == -1)
2757 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2760 /* If we are optimizing big endian systems for space and it's OK to
2761 use instructions that would be microcoded on the Cell, use the
2762 load/store multiple and string instructions. */
2763 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2764 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2766 /* Don't allow -mmultiple or -mstring on little endian systems
2767 unless the cpu is a 750, because the hardware doesn't support the
2768 instructions used in little endian mode, and causes an alignment
2769 trap. The 750 does not cause an alignment trap (except when the
2770 target is unaligned). */
2772 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2774 if (TARGET_MULTIPLE)
2776 target_flags &= ~MASK_MULTIPLE;
2777 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2778 warning (0, "-mmultiple is not supported on little endian systems");
2783 target_flags &= ~MASK_STRING;
2784 if ((target_flags_explicit & MASK_STRING) != 0)
2785 warning (0, "-mstring is not supported on little endian systems");
2789 /* Add some warnings for VSX. */
2792 const char *msg = NULL;
2793 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2794 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2796 if (target_flags_explicit & MASK_VSX)
2797 msg = N_("-mvsx requires hardware floating point");
2799 target_flags &= ~ MASK_VSX;
2801 else if (TARGET_PAIRED_FLOAT)
2802 msg = N_("-mvsx and -mpaired are incompatible");
2803 /* The hardware will allow VSX and little endian, but until we make sure
2804 things like vector select, etc. work don't allow VSX on little endian
2805 systems at this point. */
2806 else if (!BYTES_BIG_ENDIAN)
2807 msg = N_("-mvsx used with little endian code");
2808 else if (TARGET_AVOID_XFORM > 0)
2809 msg = N_("-mvsx needs indexed addressing");
2810 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2812 if (target_flags_explicit & MASK_VSX)
2813 msg = N_("-mvsx and -mno-altivec are incompatible");
2815 msg = N_("-mno-altivec disables vsx");
2821 target_flags &= ~ MASK_VSX;
2822 target_flags_explicit |= MASK_VSX;
2826 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2827 unless the user explicitly used the -mno-<option> to disable the code. */
2829 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2830 else if (TARGET_POPCNTD)
2831 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2832 else if (TARGET_DFP)
2833 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2834 else if (TARGET_CMPB)
2835 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2836 else if (TARGET_FPRND)
2837 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2838 else if (TARGET_POPCNTB)
2839 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2840 else if (TARGET_ALTIVEC)
2841 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2843 /* E500mc does "better" if we inline more aggressively. Respect the
2844 user's opinion, though. */
2845 if (rs6000_block_move_inline_limit == 0
2846 && (rs6000_cpu == PROCESSOR_PPCE500MC
2847 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2848 rs6000_block_move_inline_limit = 128;
2850 /* store_one_arg depends on expand_block_move to handle at least the
2851 size of reg_parm_stack_space. */
2852 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2853 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2857 /* If the appropriate debug option is enabled, replace the target hooks
2858 with debug versions that call the real version and then prints
2859 debugging information. */
2860 if (TARGET_DEBUG_COST)
2862 targetm.rtx_costs = rs6000_debug_rtx_costs;
2863 targetm.address_cost = rs6000_debug_address_cost;
2864 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2867 if (TARGET_DEBUG_ADDR)
2869 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2870 targetm.legitimize_address = rs6000_debug_legitimize_address;
2871 rs6000_secondary_reload_class_ptr
2872 = rs6000_debug_secondary_reload_class;
2873 rs6000_secondary_memory_needed_ptr
2874 = rs6000_debug_secondary_memory_needed;
2875 rs6000_cannot_change_mode_class_ptr
2876 = rs6000_debug_cannot_change_mode_class;
2877 rs6000_preferred_reload_class_ptr
2878 = rs6000_debug_preferred_reload_class;
2879 rs6000_legitimize_reload_address_ptr
2880 = rs6000_debug_legitimize_reload_address;
2881 rs6000_mode_dependent_address_ptr
2882 = rs6000_debug_mode_dependent_address;
2885 if (rs6000_veclibabi_name)
2887 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2888 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2891 error ("unknown vectorization library ABI type (%s) for "
2892 "-mveclibabi= switch", rs6000_veclibabi_name);
2898 if (!rs6000_explicit_options.long_double)
2900 if (main_target_opt != NULL
2901 && (main_target_opt->x_rs6000_long_double_type_size
2902 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2903 error ("target attribute or pragma changes long double size");
2905 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2908 #ifndef POWERPC_LINUX
2909 if (!rs6000_explicit_options.ieee)
2910 rs6000_ieeequad = 1;
2913 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2914 target attribute or pragma which automatically enables both options,
2915 unless the altivec ABI was set. This is set by default for 64-bit, but
2917 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2918 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2920 /* Enable Altivec ABI for AIX -maltivec. */
2921 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2923 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2924 error ("target attribute or pragma changes AltiVec ABI");
2926 rs6000_altivec_abi = 1;
2929 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2930 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2931 be explicitly overridden in either case. */
2934 if (!rs6000_explicit_options.altivec_abi
2935 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2937 if (main_target_opt != NULL &&
2938 !main_target_opt->x_rs6000_altivec_abi)
2939 error ("target attribute or pragma changes AltiVec ABI");
2941 rs6000_altivec_abi = 1;
2944 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2945 if (!rs6000_explicit_options.vrsave)
2946 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2949 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2950 So far, the only darwin64 targets are also MACH-O. */
2952 && DEFAULT_ABI == ABI_DARWIN
2955 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2956 error ("target attribute or pragma changes darwin64 ABI");
2959 rs6000_darwin64_abi = 1;
2960 /* Default to natural alignment, for better performance. */
2961 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2965 /* Place FP constants in the constant pool instead of TOC
2966 if section anchors enabled. */
2967 if (flag_section_anchors)
2968 TARGET_NO_FP_IN_TOC = 1;
2970 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2971 SUBTARGET_OVERRIDE_OPTIONS;
2973 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2974 SUBSUBTARGET_OVERRIDE_OPTIONS;
2976 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2977 SUB3TARGET_OVERRIDE_OPTIONS;
2980 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2981 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2983 /* The e500 and e500mc do not have string instructions, and we set
2984 MASK_STRING above when optimizing for size. */
2985 if ((target_flags & MASK_STRING) != 0)
2986 target_flags = target_flags & ~MASK_STRING;
2988 else if (rs6000_select[1].string != NULL)
2990 /* For the powerpc-eabispe configuration, we set all these by
2991 default, so let's unset them if we manually set another
2992 CPU that is not the E500. */
2993 if (main_target_opt != NULL
2994 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2995 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2996 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2997 error ("target attribute or pragma changes SPE ABI");
3000 if (!rs6000_explicit_options.spe_abi)
3002 if (!rs6000_explicit_options.spe)
3004 if (!rs6000_explicit_options.float_gprs)
3005 rs6000_float_gprs = 0;
3007 if (!(target_flags_explicit & MASK_ISEL))
3008 target_flags &= ~MASK_ISEL;
3011 /* Detect invalid option combinations with E500. */
3014 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3015 && rs6000_cpu != PROCESSOR_POWER5
3016 && rs6000_cpu != PROCESSOR_POWER6
3017 && rs6000_cpu != PROCESSOR_POWER7
3018 && rs6000_cpu != PROCESSOR_PPCA2
3019 && rs6000_cpu != PROCESSOR_CELL);
3020 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3021 || rs6000_cpu == PROCESSOR_POWER5
3022 || rs6000_cpu == PROCESSOR_POWER7);
3023 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3024 || rs6000_cpu == PROCESSOR_POWER5
3025 || rs6000_cpu == PROCESSOR_POWER6
3026 || rs6000_cpu == PROCESSOR_POWER7
3027 || rs6000_cpu == PROCESSOR_PPCE500MC
3028 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3030 /* Allow debug switches to override the above settings. These are set to -1
3031 in rs6000.opt to indicate the user hasn't directly set the switch. */
3032 if (TARGET_ALWAYS_HINT >= 0)
3033 rs6000_always_hint = TARGET_ALWAYS_HINT;
3035 if (TARGET_SCHED_GROUPS >= 0)
3036 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3038 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3039 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3041 rs6000_sched_restricted_insns_priority
3042 = (rs6000_sched_groups ? 1 : 0);
3044 /* Handle -msched-costly-dep option. */
3045 rs6000_sched_costly_dep
3046 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3048 if (rs6000_sched_costly_dep_str)
3050 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3051 rs6000_sched_costly_dep = no_dep_costly;
3052 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3053 rs6000_sched_costly_dep = all_deps_costly;
3054 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3055 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3056 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3057 rs6000_sched_costly_dep = store_to_load_dep_costly;
3059 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3060 atoi (rs6000_sched_costly_dep_str));
3063 /* Handle -minsert-sched-nops option. */
3064 rs6000_sched_insert_nops
3065 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3067 if (rs6000_sched_insert_nops_str)
3069 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3070 rs6000_sched_insert_nops = sched_finish_none;
3071 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3072 rs6000_sched_insert_nops = sched_finish_pad_groups;
3073 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3074 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3076 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3077 atoi (rs6000_sched_insert_nops_str));
3082 #ifdef TARGET_REGNAMES
3083 /* If the user desires alternate register names, copy in the
3084 alternate names now. */
3085 if (TARGET_REGNAMES)
3086 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3089 /* Set aix_struct_return last, after the ABI is determined.
3090 If -maix-struct-return or -msvr4-struct-return was explicitly
3091 used, don't override with the ABI default. */
3092 if (!rs6000_explicit_options.aix_struct_ret)
3093 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3096 /* IBM XL compiler defaults to unsigned bitfields. */
3097 if (TARGET_XL_COMPAT)
3098 flag_signed_bitfields = 0;
3101 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3102 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3105 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3107 /* We can only guarantee the availability of DI pseudo-ops when
3108 assembling for 64-bit targets. */
3111 targetm.asm_out.aligned_op.di = NULL;
3112 targetm.asm_out.unaligned_op.di = NULL;
3116 /* Set branch target alignment, if not optimizing for size. */
3119 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3120 aligned 8byte to avoid misprediction by the branch predictor. */
3121 if (rs6000_cpu == PROCESSOR_TITAN
3122 || rs6000_cpu == PROCESSOR_CELL)
3124 if (align_functions <= 0)
3125 align_functions = 8;
3126 if (align_jumps <= 0)
3128 if (align_loops <= 0)
3131 if (rs6000_align_branch_targets)
3133 if (align_functions <= 0)
3134 align_functions = 16;
3135 if (align_jumps <= 0)
3137 if (align_loops <= 0)
3139 can_override_loop_align = 1;
3143 if (align_jumps_max_skip <= 0)
3144 align_jumps_max_skip = 15;
3145 if (align_loops_max_skip <= 0)
3146 align_loops_max_skip = 15;
3149 /* Arrange to save and restore machine status around nested functions. */
3150 init_machine_status = rs6000_init_machine_status;
3152 /* We should always be splitting complex arguments, but we can't break
3153 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3154 if (DEFAULT_ABI != ABI_AIX)
3155 targetm.calls.split_complex_arg = NULL;
3158 /* Initialize rs6000_cost with the appropriate target costs. */
3160 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3164 case PROCESSOR_RIOS1:
3165 rs6000_cost = &rios1_cost;
3168 case PROCESSOR_RIOS2:
3169 rs6000_cost = &rios2_cost;
3172 case PROCESSOR_RS64A:
3173 rs6000_cost = &rs64a_cost;
3176 case PROCESSOR_MPCCORE:
3177 rs6000_cost = &mpccore_cost;
3180 case PROCESSOR_PPC403:
3181 rs6000_cost = &ppc403_cost;
3184 case PROCESSOR_PPC405:
3185 rs6000_cost = &ppc405_cost;
3188 case PROCESSOR_PPC440:
3189 rs6000_cost = &ppc440_cost;
3192 case PROCESSOR_PPC476:
3193 rs6000_cost = &ppc476_cost;
3196 case PROCESSOR_PPC601:
3197 rs6000_cost = &ppc601_cost;
3200 case PROCESSOR_PPC603:
3201 rs6000_cost = &ppc603_cost;
3204 case PROCESSOR_PPC604:
3205 rs6000_cost = &ppc604_cost;
3208 case PROCESSOR_PPC604e:
3209 rs6000_cost = &ppc604e_cost;
3212 case PROCESSOR_PPC620:
3213 rs6000_cost = &ppc620_cost;
3216 case PROCESSOR_PPC630:
3217 rs6000_cost = &ppc630_cost;
3220 case PROCESSOR_CELL:
3221 rs6000_cost = &ppccell_cost;
3224 case PROCESSOR_PPC750:
3225 case PROCESSOR_PPC7400:
3226 rs6000_cost = &ppc750_cost;
3229 case PROCESSOR_PPC7450:
3230 rs6000_cost = &ppc7450_cost;
3233 case PROCESSOR_PPC8540:
3234 rs6000_cost = &ppc8540_cost;
3237 case PROCESSOR_PPCE300C2:
3238 case PROCESSOR_PPCE300C3:
3239 rs6000_cost = &ppce300c2c3_cost;
3242 case PROCESSOR_PPCE500MC:
3243 rs6000_cost = &ppce500mc_cost;
3246 case PROCESSOR_PPCE500MC64:
3247 rs6000_cost = &ppce500mc64_cost;
3250 case PROCESSOR_TITAN:
3251 rs6000_cost = &titan_cost;
3254 case PROCESSOR_POWER4:
3255 case PROCESSOR_POWER5:
3256 rs6000_cost = &power4_cost;
3259 case PROCESSOR_POWER6:
3260 rs6000_cost = &power6_cost;
3263 case PROCESSOR_POWER7:
3264 rs6000_cost = &power7_cost;
3267 case PROCESSOR_PPCA2:
3268 rs6000_cost = &ppca2_cost;
3277 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3278 rs6000_cost->simultaneous_prefetches,
3279 global_options.x_param_values,
3280 global_options_set.x_param_values);
3281 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3282 global_options.x_param_values,
3283 global_options_set.x_param_values);
3284 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3285 rs6000_cost->cache_line_size,
3286 global_options.x_param_values,
3287 global_options_set.x_param_values);
3288 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3289 global_options.x_param_values,
3290 global_options_set.x_param_values);
3292 /* If using typedef char *va_list, signal that
3293 __builtin_va_start (&ap, 0) can be optimized to
3294 ap = __builtin_next_arg (0). */
3295 if (DEFAULT_ABI != ABI_V4)
3296 targetm.expand_builtin_va_start = NULL;
3299 /* Set up single/double float flags.
3300 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3301 then set both flags. */
3302 if (TARGET_HARD_FLOAT && TARGET_FPRS
3303 && rs6000_single_float == 0 && rs6000_double_float == 0)
3304 rs6000_single_float = rs6000_double_float = 1;
3306 /* Reset single and double FP flags if target is E500. */
3309 rs6000_single_float = rs6000_double_float = 0;
3310 if (TARGET_E500_SINGLE)
3311 rs6000_single_float = 1;
3312 if (TARGET_E500_DOUBLE)
3313 rs6000_single_float = rs6000_double_float = 1;
3316 if (main_target_opt)
3318 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3319 error ("target attribute or pragma changes single precision floating "
3321 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3322 error ("target attribute or pragma changes double precision floating "
3326 /* If not explicitly specified via option, decide whether to generate indexed
3327 load/store instructions. */
3328 if (TARGET_AVOID_XFORM == -1)
3329 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3330 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3331 need indexed accesses and the type used is the scalar type of the element
3332 being loaded or stored. */
3333 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3334 && !TARGET_ALTIVEC);
3336 /* Set the -mrecip options. */
3337 if (rs6000_recip_name)
3339 char *p = ASTRDUP (rs6000_recip_name);
3341 unsigned int mask, i;
3344 while ((q = strtok (p, ",")) != NULL)
3355 if (!strcmp (q, "default"))
3356 mask = ((TARGET_RECIP_PRECISION)
3357 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3360 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3361 if (!strcmp (q, recip_options[i].string))
3363 mask = recip_options[i].mask;
3367 if (i == ARRAY_SIZE (recip_options))
3369 error ("unknown option for -mrecip=%s", q);
3377 rs6000_recip_control &= ~mask;
3379 rs6000_recip_control |= mask;
3383 rs6000_init_hard_regno_mode_ok (global_init_p);
3385 /* Save the initial options in case the user does function specific options */
3387 target_option_default_node = target_option_current_node
3388 = build_target_option_node ();
3393 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3394 define the target cpu type. */
3397 rs6000_option_override (void)
3399 (void) rs6000_option_override_internal (true);
3403 /* Implement targetm.vectorize.builtin_mask_for_load. */
3405 rs6000_builtin_mask_for_load (void)
3407 if (TARGET_ALTIVEC || TARGET_VSX)
3408 return altivec_builtin_mask_for_load;
3413 /* Implement LOOP_ALIGN. */
3415 rs6000_loop_align (rtx label)
3420 /* Don't override loop alignment if -falign-loops was specified. */
3421 if (!can_override_loop_align)
3422 return align_loops_log;
3424 bb = BLOCK_FOR_INSN (label);
3425 ninsns = num_loop_insns(bb->loop_father);
3427 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3428 if (ninsns > 4 && ninsns <= 8
3429 && (rs6000_cpu == PROCESSOR_POWER4
3430 || rs6000_cpu == PROCESSOR_POWER5
3431 || rs6000_cpu == PROCESSOR_POWER6
3432 || rs6000_cpu == PROCESSOR_POWER7))
3435 return align_loops_log;
3438 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3440 rs6000_loop_align_max_skip (rtx label)
3442 return (1 << rs6000_loop_align (label)) - 1;
3445 /* Implement targetm.vectorize.builtin_conversion.
3446 Returns a decl of a function that implements conversion of an integer vector
3447 into a floating-point vector, or vice-versa. DEST_TYPE is the
3448 destination type and SRC_TYPE the source type of the conversion.
3449 Return NULL_TREE if it is not available. */
3451 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3453 enum tree_code code = (enum tree_code) tcode;
3457 case FIX_TRUNC_EXPR:
3458 switch (TYPE_MODE (dest_type))
3461 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3464 return TYPE_UNSIGNED (dest_type)
3465 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3466 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3469 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3472 return TYPE_UNSIGNED (dest_type)
3473 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3474 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3481 switch (TYPE_MODE (src_type))
3484 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3487 return TYPE_UNSIGNED (src_type)
3488 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3489 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3492 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3495 return TYPE_UNSIGNED (src_type)
3496 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3497 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3508 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3510 rs6000_builtin_mul_widen_even (tree type)
3512 if (!TARGET_ALTIVEC)
3515 switch (TYPE_MODE (type))
3518 return TYPE_UNSIGNED (type)
3519 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3520 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3523 return TYPE_UNSIGNED (type)
3524 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3525 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3531 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3533 rs6000_builtin_mul_widen_odd (tree type)
3535 if (!TARGET_ALTIVEC)
3538 switch (TYPE_MODE (type))
3541 return TYPE_UNSIGNED (type)
3542 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3543 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3546 return TYPE_UNSIGNED (type)
3547 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3548 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3555 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3556 after applying N number of iterations. This routine does not determine
3557 how may iterations are required to reach desired alignment. */
3560 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3567 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3570 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3580 /* Assuming that all other types are naturally aligned. CHECKME! */
3585 /* Return true if the vector misalignment factor is supported by the
3588 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3595 /* Return if movmisalign pattern is not supported for this mode. */
3596 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3599 if (misalignment == -1)
3601 /* Misalignment factor is unknown at compile time but we know
3602 it's word aligned. */
3603 if (rs6000_vector_alignment_reachable (type, is_packed))
3605 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3607 if (element_size == 64 || element_size == 32)
3614 /* VSX supports word-aligned vector. */
3615 if (misalignment % 4 == 0)
3621 /* Implement targetm.vectorize.builtin_vec_perm. */
3623 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3625 tree inner_type = TREE_TYPE (type);
3626 bool uns_p = TYPE_UNSIGNED (inner_type);
3629 *mask_element_type = unsigned_char_type_node;
3631 switch (TYPE_MODE (type))
3635 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3636 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3641 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3642 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3647 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3648 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3652 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3656 if (!TARGET_ALLOW_DF_PERMUTE)
3659 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3663 if (!TARGET_ALLOW_DF_PERMUTE)
3667 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3668 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3680 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3682 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3683 tree vectype, int misalign)
3687 switch (type_of_cost)
3697 case cond_branch_not_taken:
3700 case cond_branch_taken:
3709 case vec_promote_demote:
3715 case unaligned_load:
3716 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3718 elements = TYPE_VECTOR_SUBPARTS (vectype);
3720 /* Double word aligned. */
3728 /* Double word aligned. */
3732 /* Unknown misalignment. */
3745 /* Misaligned loads are not supported. */
3750 case unaligned_store:
3751 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3753 elements = TYPE_VECTOR_SUBPARTS (vectype);
3755 /* Double word aligned. */
3763 /* Double word aligned. */
3767 /* Unknown misalignment. */
3780 /* Misaligned stores are not supported. */
3790 /* Implement targetm.vectorize.preferred_simd_mode. */
3792 static enum machine_mode
3793 rs6000_preferred_simd_mode (enum machine_mode mode)
3802 if (TARGET_ALTIVEC || TARGET_VSX)
3826 if (TARGET_PAIRED_FLOAT
3832 /* Handle generic options of the form -mfoo=yes/no.
3833 NAME is the option name.
3834 VALUE is the option value.
3835 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3836 whether the option value is 'yes' or 'no' respectively. */
3838 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3842 else if (!strcmp (value, "yes"))
3844 else if (!strcmp (value, "no"))
3847 error ("unknown -m%s= option specified: '%s'", name, value);
3850 /* Implement TARGET_OPTION_INIT_STRUCT. */
3853 rs6000_option_init_struct (struct gcc_options *opts)
3855 if (DEFAULT_ABI == ABI_DARWIN)
3856 /* The Darwin libraries never set errno, so we might as well
3857 avoid calling them when that's the only reason we would. */
3858 opts->x_flag_errno_math = 0;
3860 /* Enable section anchors by default. */
3862 opts->x_flag_section_anchors = 1;
3865 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3868 rs6000_option_default_params (void)
3870 /* Double growth factor to counter reduced min jump length. */
3871 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3874 static enum fpu_type_t
3875 rs6000_parse_fpu_option (const char *option)
3877 if (!strcmp("none", option)) return FPU_NONE;
3878 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3879 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3880 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3881 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3882 error("unknown value %s for -mfpu", option);
3887 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3888 library with vectorized intrinsics. */
3891 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3894 const char *suffix = NULL;
3895 tree fntype, new_fndecl, bdecl = NULL_TREE;
3898 enum machine_mode el_mode, in_mode;
3901 /* Libmass is suitable for unsafe math only as it does not correctly support
3902 parts of IEEE with the required precision such as denormals. Only support
3903 it if we have VSX to use the simd d2 or f4 functions.
3904 XXX: Add variable length support. */
3905 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3908 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3909 n = TYPE_VECTOR_SUBPARTS (type_out);
3910 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3911 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3912 if (el_mode != in_mode
3916 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3918 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3921 case BUILT_IN_ATAN2:
3922 case BUILT_IN_HYPOT:
3928 case BUILT_IN_ACOSH:
3930 case BUILT_IN_ASINH:
3932 case BUILT_IN_ATANH:
3940 case BUILT_IN_EXPM1:
3941 case BUILT_IN_LGAMMA:
3942 case BUILT_IN_LOG10:
3943 case BUILT_IN_LOG1P:
3951 bdecl = implicit_built_in_decls[fn];
3952 suffix = "d2"; /* pow -> powd2 */
3953 if (el_mode != DFmode
3958 case BUILT_IN_ATAN2F:
3959 case BUILT_IN_HYPOTF:
3964 case BUILT_IN_ACOSF:
3965 case BUILT_IN_ACOSHF:
3966 case BUILT_IN_ASINF:
3967 case BUILT_IN_ASINHF:
3968 case BUILT_IN_ATANF:
3969 case BUILT_IN_ATANHF:
3970 case BUILT_IN_CBRTF:
3972 case BUILT_IN_COSHF:
3974 case BUILT_IN_ERFCF:
3975 case BUILT_IN_EXP2F:
3977 case BUILT_IN_EXPM1F:
3978 case BUILT_IN_LGAMMAF:
3979 case BUILT_IN_LOG10F:
3980 case BUILT_IN_LOG1PF:
3981 case BUILT_IN_LOG2F:
3984 case BUILT_IN_SINHF:
3985 case BUILT_IN_SQRTF:
3987 case BUILT_IN_TANHF:
3988 bdecl = implicit_built_in_decls[fn];
3989 suffix = "4"; /* powf -> powf4 */
3990 if (el_mode != SFmode
4002 gcc_assert (suffix != NULL);
4003 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
4004 strcpy (name, bname + sizeof ("__builtin_") - 1);
4005 strcat (name, suffix);
4008 fntype = build_function_type_list (type_out, type_in, NULL);
4009 else if (n_args == 2)
4010 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
4014 /* Build a function declaration for the vectorized function. */
4015 new_fndecl = build_decl (BUILTINS_LOCATION,
4016 FUNCTION_DECL, get_identifier (name), fntype);
4017 TREE_PUBLIC (new_fndecl) = 1;
4018 DECL_EXTERNAL (new_fndecl) = 1;
4019 DECL_IS_NOVOPS (new_fndecl) = 1;
4020 TREE_READONLY (new_fndecl) = 1;
4025 /* Returns a function decl for a vectorized version of the builtin function
4026 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4027 if it is not available. */
4030 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4033 enum machine_mode in_mode, out_mode;
4036 if (TREE_CODE (type_out) != VECTOR_TYPE
4037 || TREE_CODE (type_in) != VECTOR_TYPE
4038 || !TARGET_VECTORIZE_BUILTINS)
4041 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4042 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4043 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4044 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4046 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4048 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4051 case BUILT_IN_COPYSIGN:
4052 if (VECTOR_UNIT_VSX_P (V2DFmode)
4053 && out_mode == DFmode && out_n == 2
4054 && in_mode == DFmode && in_n == 2)
4055 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4057 case BUILT_IN_COPYSIGNF:
4058 if (out_mode != SFmode || out_n != 4
4059 || in_mode != SFmode || in_n != 4)
4061 if (VECTOR_UNIT_VSX_P (V4SFmode))
4062 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4063 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4064 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4067 if (VECTOR_UNIT_VSX_P (V2DFmode)
4068 && out_mode == DFmode && out_n == 2
4069 && in_mode == DFmode && in_n == 2)
4070 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4072 case BUILT_IN_SQRTF:
4073 if (VECTOR_UNIT_VSX_P (V4SFmode)
4074 && out_mode == SFmode && out_n == 4
4075 && in_mode == SFmode && in_n == 4)
4076 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4079 if (VECTOR_UNIT_VSX_P (V2DFmode)
4080 && out_mode == DFmode && out_n == 2
4081 && in_mode == DFmode && in_n == 2)
4082 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4084 case BUILT_IN_CEILF:
4085 if (out_mode != SFmode || out_n != 4
4086 || in_mode != SFmode || in_n != 4)
4088 if (VECTOR_UNIT_VSX_P (V4SFmode))
4089 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4090 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4091 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4093 case BUILT_IN_FLOOR:
4094 if (VECTOR_UNIT_VSX_P (V2DFmode)
4095 && out_mode == DFmode && out_n == 2
4096 && in_mode == DFmode && in_n == 2)
4097 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4099 case BUILT_IN_FLOORF:
4100 if (out_mode != SFmode || out_n != 4
4101 || in_mode != SFmode || in_n != 4)
4103 if (VECTOR_UNIT_VSX_P (V4SFmode))
4104 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4105 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4106 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4109 if (VECTOR_UNIT_VSX_P (V2DFmode)
4110 && out_mode == DFmode && out_n == 2
4111 && in_mode == DFmode && in_n == 2)
4112 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4115 if (VECTOR_UNIT_VSX_P (V4SFmode)
4116 && out_mode == SFmode && out_n == 4
4117 && in_mode == SFmode && in_n == 4)
4118 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4119 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4120 && out_mode == SFmode && out_n == 4
4121 && in_mode == SFmode && in_n == 4)
4122 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4124 case BUILT_IN_TRUNC:
4125 if (VECTOR_UNIT_VSX_P (V2DFmode)
4126 && out_mode == DFmode && out_n == 2
4127 && in_mode == DFmode && in_n == 2)
4128 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4130 case BUILT_IN_TRUNCF:
4131 if (out_mode != SFmode || out_n != 4
4132 || in_mode != SFmode || in_n != 4)
4134 if (VECTOR_UNIT_VSX_P (V4SFmode))
4135 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4136 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4137 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4139 case BUILT_IN_NEARBYINT:
4140 if (VECTOR_UNIT_VSX_P (V2DFmode)
4141 && flag_unsafe_math_optimizations
4142 && out_mode == DFmode && out_n == 2
4143 && in_mode == DFmode && in_n == 2)
4144 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4146 case BUILT_IN_NEARBYINTF:
4147 if (VECTOR_UNIT_VSX_P (V4SFmode)
4148 && flag_unsafe_math_optimizations
4149 && out_mode == SFmode && out_n == 4
4150 && in_mode == SFmode && in_n == 4)
4151 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4154 if (VECTOR_UNIT_VSX_P (V2DFmode)
4155 && !flag_trapping_math
4156 && out_mode == DFmode && out_n == 2
4157 && in_mode == DFmode && in_n == 2)
4158 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4160 case BUILT_IN_RINTF:
4161 if (VECTOR_UNIT_VSX_P (V4SFmode)
4162 && !flag_trapping_math
4163 && out_mode == SFmode && out_n == 4
4164 && in_mode == SFmode && in_n == 4)
4165 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4172 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4174 enum rs6000_builtins fn
4175 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4178 case RS6000_BUILTIN_RSQRTF:
4179 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4180 && out_mode == SFmode && out_n == 4
4181 && in_mode == SFmode && in_n == 4)
4182 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4184 case RS6000_BUILTIN_RSQRT:
4185 if (VECTOR_UNIT_VSX_P (V2DFmode)
4186 && out_mode == DFmode && out_n == 2
4187 && in_mode == DFmode && in_n == 2)
4188 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4190 case RS6000_BUILTIN_RECIPF:
4191 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4192 && out_mode == SFmode && out_n == 4
4193 && in_mode == SFmode && in_n == 4)
4194 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4196 case RS6000_BUILTIN_RECIP:
4197 if (VECTOR_UNIT_VSX_P (V2DFmode)
4198 && out_mode == DFmode && out_n == 2
4199 && in_mode == DFmode && in_n == 2)
4200 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4207 /* Generate calls to libmass if appropriate. */
4208 if (rs6000_veclib_handler)
4209 return rs6000_veclib_handler (fndecl, type_out, type_in);
4215 /* Implement TARGET_HANDLE_OPTION. */
4218 rs6000_handle_option (size_t code, const char *arg, int value)
4220 enum fpu_type_t fpu_type = FPU_NONE;
4227 target_flags &= ~(MASK_POWER | MASK_POWER2
4228 | MASK_MULTIPLE | MASK_STRING);
4229 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4230 | MASK_MULTIPLE | MASK_STRING);
4232 case OPT_mno_powerpc:
4233 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4234 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4235 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4236 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4239 target_flags &= ~MASK_MINIMAL_TOC;
4240 TARGET_NO_FP_IN_TOC = 0;
4241 TARGET_NO_SUM_IN_TOC = 0;
4242 target_flags_explicit |= MASK_MINIMAL_TOC;
4243 #ifdef TARGET_USES_SYSV4_OPT
4244 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4245 just the same as -mminimal-toc. */
4246 target_flags |= MASK_MINIMAL_TOC;
4247 target_flags_explicit |= MASK_MINIMAL_TOC;
4251 #ifdef TARGET_USES_SYSV4_OPT
4253 /* Make -mtoc behave like -mminimal-toc. */
4254 target_flags |= MASK_MINIMAL_TOC;
4255 target_flags_explicit |= MASK_MINIMAL_TOC;
4259 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4261 if (strcmp (arg, "small") == 0)
4262 rs6000_current_cmodel = CMODEL_SMALL;
4263 else if (strcmp (arg, "medium") == 0)
4264 rs6000_current_cmodel = CMODEL_MEDIUM;
4265 else if (strcmp (arg, "large") == 0)
4266 rs6000_current_cmodel = CMODEL_LARGE;
4269 error ("invalid option for -mcmodel: '%s'", arg);
4272 rs6000_explicit_options.cmodel = true;
4275 #ifdef TARGET_USES_AIX64_OPT
4280 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4281 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4282 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4285 #ifdef TARGET_USES_AIX64_OPT
4290 target_flags &= ~MASK_POWERPC64;
4291 target_flags_explicit |= MASK_POWERPC64;
4294 case OPT_minsert_sched_nops_:
4295 rs6000_sched_insert_nops_str = arg;
4298 case OPT_mminimal_toc:
4301 TARGET_NO_FP_IN_TOC = 0;
4302 TARGET_NO_SUM_IN_TOC = 0;
4309 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4310 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4317 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4318 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4322 case OPT_mpowerpc_gpopt:
4323 case OPT_mpowerpc_gfxopt:
4326 target_flags |= MASK_POWERPC;
4327 target_flags_explicit |= MASK_POWERPC;
4331 case OPT_maix_struct_return:
4332 case OPT_msvr4_struct_return:
4333 rs6000_explicit_options.aix_struct_ret = true;
4337 rs6000_explicit_options.vrsave = true;
4338 TARGET_ALTIVEC_VRSAVE = value;
4342 rs6000_explicit_options.vrsave = true;
4343 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4347 target_flags_explicit |= MASK_ISEL;
4349 rs6000_parse_yes_no_option ("isel", arg, &isel);
4351 target_flags |= MASK_ISEL;
4353 target_flags &= ~MASK_ISEL;
4357 rs6000_explicit_options.spe = true;
4362 rs6000_explicit_options.spe = true;
4363 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4370 while ((q = strtok (p, ",")) != NULL)
4384 if (! strcmp (q, "all"))
4385 mask = MASK_DEBUG_ALL;
4386 else if (! strcmp (q, "stack"))
4387 mask = MASK_DEBUG_STACK;
4388 else if (! strcmp (q, "arg"))
4389 mask = MASK_DEBUG_ARG;
4390 else if (! strcmp (q, "reg"))
4391 mask = MASK_DEBUG_REG;
4392 else if (! strcmp (q, "addr"))
4393 mask = MASK_DEBUG_ADDR;
4394 else if (! strcmp (q, "cost"))
4395 mask = MASK_DEBUG_COST;
4396 else if (! strcmp (q, "target"))
4397 mask = MASK_DEBUG_TARGET;
4399 error ("unknown -mdebug-%s switch", q);
4402 rs6000_debug &= ~mask;
4404 rs6000_debug |= mask;
4408 #ifdef TARGET_USES_SYSV4_OPT
4410 rs6000_abi_name = arg;
4414 rs6000_sdata_name = arg;
4417 case OPT_mtls_size_:
4418 if (strcmp (arg, "16") == 0)
4419 rs6000_tls_size = 16;
4420 else if (strcmp (arg, "32") == 0)
4421 rs6000_tls_size = 32;
4422 else if (strcmp (arg, "64") == 0)
4423 rs6000_tls_size = 64;
4425 error ("bad value %qs for -mtls-size switch", arg);
4428 case OPT_mrelocatable:
4431 target_flags |= MASK_MINIMAL_TOC;
4432 target_flags_explicit |= MASK_MINIMAL_TOC;
4433 TARGET_NO_FP_IN_TOC = 1;
4437 case OPT_mrelocatable_lib:
4440 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4441 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4442 TARGET_NO_FP_IN_TOC = 1;
4446 target_flags &= ~MASK_RELOCATABLE;
4447 target_flags_explicit |= MASK_RELOCATABLE;
4453 if (!strcmp (arg, "altivec"))
4455 rs6000_explicit_options.altivec_abi = true;
4456 rs6000_altivec_abi = 1;
4458 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4461 else if (! strcmp (arg, "no-altivec"))
4463 rs6000_explicit_options.altivec_abi = true;
4464 rs6000_altivec_abi = 0;
4466 else if (! strcmp (arg, "spe"))
4468 rs6000_explicit_options.spe_abi = true;
4470 rs6000_altivec_abi = 0;
4471 if (!TARGET_SPE_ABI)
4472 error ("not configured for ABI: '%s'", arg);
4474 else if (! strcmp (arg, "no-spe"))
4476 rs6000_explicit_options.spe_abi = true;
4480 /* These are here for testing during development only, do not
4481 document in the manual please. */
4482 else if (! strcmp (arg, "d64"))
4484 rs6000_darwin64_abi = 1;
4485 warning (0, "using darwin64 ABI");
4487 else if (! strcmp (arg, "d32"))
4489 rs6000_darwin64_abi = 0;
4490 warning (0, "using old darwin ABI");
4493 else if (! strcmp (arg, "ibmlongdouble"))
4495 rs6000_explicit_options.ieee = true;
4496 rs6000_ieeequad = 0;
4497 warning (0, "using IBM extended precision long double");
4499 else if (! strcmp (arg, "ieeelongdouble"))
4501 rs6000_explicit_options.ieee = true;
4502 rs6000_ieeequad = 1;
4503 warning (0, "using IEEE extended precision long double");
4508 error ("unknown ABI specified: '%s'", arg);
4514 rs6000_select[1].string = arg;
4515 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4516 if (rs6000_cpu_index < 0)
4517 error ("bad value (%s) for -mcpu", arg);
4521 rs6000_select[2].string = arg;
4522 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4523 if (rs6000_tune_index < 0)
4524 error ("bad value (%s) for -mtune", arg);
4527 case OPT_mtraceback_:
4528 if (! strncmp (arg, "full", 4))
4529 rs6000_traceback = traceback_full;
4530 else if (! strncmp (arg, "part", 4))
4531 rs6000_traceback = traceback_part;
4532 else if (! strncmp (arg, "no", 2))
4533 rs6000_traceback = traceback_none;
4535 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4536 "%<partial%> or %<none%>", arg);
4539 case OPT_mfloat_gprs_:
4540 rs6000_explicit_options.float_gprs = true;
4541 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4542 rs6000_float_gprs = 1;
4543 else if (! strcmp (arg, "double"))
4544 rs6000_float_gprs = 2;
4545 else if (! strcmp (arg, "no"))
4546 rs6000_float_gprs = 0;
4549 error ("invalid option for -mfloat-gprs: '%s'", arg);
4554 case OPT_mlong_double_:
4555 rs6000_explicit_options.long_double = true;
4556 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4557 if (value != 64 && value != 128)
4559 error ("unknown switch -mlong-double-%s", arg);
4560 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4564 rs6000_long_double_type_size = value;
4567 case OPT_msched_costly_dep_:
4568 rs6000_sched_costly_dep_str = arg;
4572 rs6000_explicit_options.alignment = true;
4573 if (! strcmp (arg, "power"))
4575 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4576 some C library functions, so warn about it. The flag may be
4577 useful for performance studies from time to time though, so
4578 don't disable it entirely. */
4579 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4580 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4581 " it is incompatible with the installed C and C++ libraries");
4582 rs6000_alignment_flags = MASK_ALIGN_POWER;
4584 else if (! strcmp (arg, "natural"))
4585 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4588 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4593 case OPT_msingle_float:
4594 if (!TARGET_SINGLE_FPU)
4595 warning (0, "-msingle-float option equivalent to -mhard-float");
4596 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4597 rs6000_double_float = 0;
4598 target_flags &= ~MASK_SOFT_FLOAT;
4599 target_flags_explicit |= MASK_SOFT_FLOAT;
4602 case OPT_mdouble_float:
4603 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4604 rs6000_single_float = 1;
4605 target_flags &= ~MASK_SOFT_FLOAT;
4606 target_flags_explicit |= MASK_SOFT_FLOAT;
4609 case OPT_msimple_fpu:
4610 if (!TARGET_SINGLE_FPU)
4611 warning (0, "-msimple-fpu option ignored");
4614 case OPT_mhard_float:
4615 /* -mhard_float implies -msingle-float and -mdouble-float. */
4616 rs6000_single_float = rs6000_double_float = 1;
4619 case OPT_msoft_float:
4620 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4621 rs6000_single_float = rs6000_double_float = 0;
4625 fpu_type = rs6000_parse_fpu_option(arg);
4626 if (fpu_type != FPU_NONE)
4627 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4629 target_flags &= ~MASK_SOFT_FLOAT;
4630 target_flags_explicit |= MASK_SOFT_FLOAT;
4631 rs6000_xilinx_fpu = 1;
4632 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4633 rs6000_single_float = 1;
4634 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4635 rs6000_single_float = rs6000_double_float = 1;
4636 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4637 rs6000_simple_fpu = 1;
4641 /* -mfpu=none is equivalent to -msoft-float */
4642 target_flags |= MASK_SOFT_FLOAT;
4643 target_flags_explicit |= MASK_SOFT_FLOAT;
4644 rs6000_single_float = rs6000_double_float = 0;
4649 rs6000_recip_name = (value) ? "default" : "none";
4653 rs6000_recip_name = arg;
4659 /* Do anything needed at the start of the asm file. */
4662 rs6000_file_start (void)
4666 const char *start = buffer;
4667 struct rs6000_cpu_select *ptr;
4668 const char *default_cpu = TARGET_CPU_DEFAULT;
4669 FILE *file = asm_out_file;
4671 default_file_start ();
4673 #ifdef TARGET_BI_ARCH
4674 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4678 if (flag_verbose_asm)
4680 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4681 rs6000_select[0].string = default_cpu;
4683 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4685 ptr = &rs6000_select[i];
4686 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4688 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4693 if (PPC405_ERRATUM77)
4695 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4699 #ifdef USING_ELFOS_H
4700 switch (rs6000_sdata)
4702 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4703 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4704 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4705 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4708 if (rs6000_sdata && g_switch_value)
4710 fprintf (file, "%s -G %d", start,
4720 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4722 switch_to_section (toc_section);
4723 switch_to_section (text_section);
4728 /* Return nonzero if this function is known to have a null epilogue. */
4731 direct_return (void)
4733 if (reload_completed)
4735 rs6000_stack_t *info = rs6000_stack_info ();
4737 if (info->first_gp_reg_save == 32
4738 && info->first_fp_reg_save == 64
4739 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4740 && ! info->lr_save_p
4741 && ! info->cr_save_p
4742 && info->vrsave_mask == 0
4750 /* Return the number of instructions it takes to form a constant in an
4751 integer register. */
4754 num_insns_constant_wide (HOST_WIDE_INT value)
4756 /* signed constant loadable with {cal|addi} */
4757 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4760 /* constant loadable with {cau|addis} */
4761 else if ((value & 0xffff) == 0
4762 && (value >> 31 == -1 || value >> 31 == 0))
4765 #if HOST_BITS_PER_WIDE_INT == 64
4766 else if (TARGET_POWERPC64)
4768 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4769 HOST_WIDE_INT high = value >> 31;
4771 if (high == 0 || high == -1)
4777 return num_insns_constant_wide (high) + 1;
4779 return num_insns_constant_wide (low) + 1;
4781 return (num_insns_constant_wide (high)
4782 + num_insns_constant_wide (low) + 1);
4791 num_insns_constant (rtx op, enum machine_mode mode)
4793 HOST_WIDE_INT low, high;
4795 switch (GET_CODE (op))
4798 #if HOST_BITS_PER_WIDE_INT == 64
4799 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4800 && mask64_operand (op, mode))
4804 return num_insns_constant_wide (INTVAL (op));
4807 if (mode == SFmode || mode == SDmode)
4812 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4813 if (DECIMAL_FLOAT_MODE_P (mode))
4814 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4816 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4817 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4820 if (mode == VOIDmode || mode == DImode)
4822 high = CONST_DOUBLE_HIGH (op);
4823 low = CONST_DOUBLE_LOW (op);
4830 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4831 if (DECIMAL_FLOAT_MODE_P (mode))
4832 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4834 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4835 high = l[WORDS_BIG_ENDIAN == 0];
4836 low = l[WORDS_BIG_ENDIAN != 0];
4840 return (num_insns_constant_wide (low)
4841 + num_insns_constant_wide (high));
4844 if ((high == 0 && low >= 0)
4845 || (high == -1 && low < 0))
4846 return num_insns_constant_wide (low);
4848 else if (mask64_operand (op, mode))
4852 return num_insns_constant_wide (high) + 1;
4855 return (num_insns_constant_wide (high)
4856 + num_insns_constant_wide (low) + 1);
4864 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4865 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4866 corresponding element of the vector, but for V4SFmode and V2SFmode,
4867 the corresponding "float" is interpreted as an SImode integer. */
4870 const_vector_elt_as_int (rtx op, unsigned int elt)
4874 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4875 gcc_assert (GET_MODE (op) != V2DImode
4876 && GET_MODE (op) != V2DFmode);
4878 tmp = CONST_VECTOR_ELT (op, elt);
4879 if (GET_MODE (op) == V4SFmode
4880 || GET_MODE (op) == V2SFmode)
4881 tmp = gen_lowpart (SImode, tmp);
4882 return INTVAL (tmp);
4885 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4886 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4887 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4888 all items are set to the same value and contain COPIES replicas of the
4889 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4890 operand and the others are set to the value of the operand's msb. */
4893 vspltis_constant (rtx op, unsigned step, unsigned copies)
4895 enum machine_mode mode = GET_MODE (op);
4896 enum machine_mode inner = GET_MODE_INNER (mode);
4904 HOST_WIDE_INT splat_val;
4905 HOST_WIDE_INT msb_val;
4907 if (mode == V2DImode || mode == V2DFmode)
4910 nunits = GET_MODE_NUNITS (mode);
4911 bitsize = GET_MODE_BITSIZE (inner);
4912 mask = GET_MODE_MASK (inner);
4914 val = const_vector_elt_as_int (op, nunits - 1);
4916 msb_val = val > 0 ? 0 : -1;
4918 /* Construct the value to be splatted, if possible. If not, return 0. */
4919 for (i = 2; i <= copies; i *= 2)
4921 HOST_WIDE_INT small_val;
4923 small_val = splat_val >> bitsize;
4925 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4927 splat_val = small_val;
4930 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4931 if (EASY_VECTOR_15 (splat_val))
4934 /* Also check if we can splat, and then add the result to itself. Do so if
4935 the value is positive, of if the splat instruction is using OP's mode;
4936 for splat_val < 0, the splat and the add should use the same mode. */
4937 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4938 && (splat_val >= 0 || (step == 1 && copies == 1)))
4941 /* Also check if are loading up the most significant bit which can be done by
4942 loading up -1 and shifting the value left by -1. */
4943 else if (EASY_VECTOR_MSB (splat_val, inner))
4949 /* Check if VAL is present in every STEP-th element, and the
4950 other elements are filled with its most significant bit. */
4951 for (i = 0; i < nunits - 1; ++i)
4953 HOST_WIDE_INT desired_val;
4954 if (((i + 1) & (step - 1)) == 0)
4957 desired_val = msb_val;
4959 if (desired_val != const_vector_elt_as_int (op, i))
4967 /* Return true if OP is of the given MODE and can be synthesized
4968 with a vspltisb, vspltish or vspltisw. */
4971 easy_altivec_constant (rtx op, enum machine_mode mode)
4973 unsigned step, copies;
4975 if (mode == VOIDmode)
4976 mode = GET_MODE (op);
4977 else if (mode != GET_MODE (op))
4980 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4982 if (mode == V2DFmode)
4983 return zero_constant (op, mode);
4985 if (mode == V2DImode)
4987 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4989 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4990 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4993 if (zero_constant (op, mode))
4996 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4997 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
5003 /* Start with a vspltisw. */
5004 step = GET_MODE_NUNITS (mode) / 4;
5007 if (vspltis_constant (op, step, copies))
5010 /* Then try with a vspltish. */
5016 if (vspltis_constant (op, step, copies))
5019 /* And finally a vspltisb. */
5025 if (vspltis_constant (op, step, copies))
5031 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
5032 result is OP. Abort if it is not possible. */
5035 gen_easy_altivec_constant (rtx op)
5037 enum machine_mode mode = GET_MODE (op);
5038 int nunits = GET_MODE_NUNITS (mode);
5039 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
5040 unsigned step = nunits / 4;
5041 unsigned copies = 1;
5043 /* Start with a vspltisw. */
5044 if (vspltis_constant (op, step, copies))
5045 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5047 /* Then try with a vspltish. */
5053 if (vspltis_constant (op, step, copies))
5054 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5056 /* And finally a vspltisb. */
5062 if (vspltis_constant (op, step, copies))
5063 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5069 output_vec_const_move (rtx *operands)
5072 enum machine_mode mode;
5077 mode = GET_MODE (dest);
5081 if (zero_constant (vec, mode))
5082 return "xxlxor %x0,%x0,%x0";
5084 if (mode == V2DImode
5085 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5086 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5087 return "vspltisw %0,-1";
5093 if (zero_constant (vec, mode))
5094 return "vxor %0,%0,%0";
5096 splat_vec = gen_easy_altivec_constant (vec);
5097 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5098 operands[1] = XEXP (splat_vec, 0);
5099 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5102 switch (GET_MODE (splat_vec))
5105 return "vspltisw %0,%1";
5108 return "vspltish %0,%1";
5111 return "vspltisb %0,%1";
5118 gcc_assert (TARGET_SPE);
5120 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5121 pattern of V1DI, V4HI, and V2SF.
5123 FIXME: We should probably return # and add post reload
5124 splitters for these, but this way is so easy ;-). */
5125 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5126 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5127 operands[1] = CONST_VECTOR_ELT (vec, 0);
5128 operands[2] = CONST_VECTOR_ELT (vec, 1);
5130 return "li %0,%1\n\tevmergelo %0,%0,%0";
5132 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5135 /* Initialize TARGET of vector PAIRED to VALS. */
5138 paired_expand_vector_init (rtx target, rtx vals)
5140 enum machine_mode mode = GET_MODE (target);
5141 int n_elts = GET_MODE_NUNITS (mode);
5143 rtx x, new_rtx, tmp, constant_op, op1, op2;
5146 for (i = 0; i < n_elts; ++i)
5148 x = XVECEXP (vals, 0, i);
5149 if (!CONSTANT_P (x))
5154 /* Load from constant pool. */
5155 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5161 /* The vector is initialized only with non-constants. */
5162 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5163 XVECEXP (vals, 0, 1));
5165 emit_move_insn (target, new_rtx);
5169 /* One field is non-constant and the other one is a constant. Load the
5170 constant from the constant pool and use ps_merge instruction to
5171 construct the whole vector. */
5172 op1 = XVECEXP (vals, 0, 0);
5173 op2 = XVECEXP (vals, 0, 1);
5175 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5177 tmp = gen_reg_rtx (GET_MODE (constant_op));
5178 emit_move_insn (tmp, constant_op);
5180 if (CONSTANT_P (op1))
5181 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5183 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5185 emit_move_insn (target, new_rtx);
5189 paired_expand_vector_move (rtx operands[])
5191 rtx op0 = operands[0], op1 = operands[1];
5193 emit_move_insn (op0, op1);
5196 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5197 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5198 operands for the relation operation COND. This is a recursive
5202 paired_emit_vector_compare (enum rtx_code rcode,
5203 rtx dest, rtx op0, rtx op1,
5204 rtx cc_op0, rtx cc_op1)
5206 rtx tmp = gen_reg_rtx (V2SFmode);
5209 gcc_assert (TARGET_PAIRED_FLOAT);
5210 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5216 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5220 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5221 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5225 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5228 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5231 tmp1 = gen_reg_rtx (V2SFmode);
5232 max = gen_reg_rtx (V2SFmode);
5233 min = gen_reg_rtx (V2SFmode);
5234 gen_reg_rtx (V2SFmode);
5236 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5237 emit_insn (gen_selv2sf4
5238 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5239 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5240 emit_insn (gen_selv2sf4
5241 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5242 emit_insn (gen_subv2sf3 (tmp1, min, max));
5243 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5246 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5249 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5252 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5255 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5258 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5267 /* Emit vector conditional expression.
5268 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5269 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5272 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5273 rtx cond, rtx cc_op0, rtx cc_op1)
5275 enum rtx_code rcode = GET_CODE (cond);
5277 if (!TARGET_PAIRED_FLOAT)
5280 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5285 /* Initialize vector TARGET to VALS. */
5288 rs6000_expand_vector_init (rtx target, rtx vals)
5290 enum machine_mode mode = GET_MODE (target);
5291 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5292 int n_elts = GET_MODE_NUNITS (mode);
5293 int n_var = 0, one_var = -1;
5294 bool all_same = true, all_const_zero = true;
5298 for (i = 0; i < n_elts; ++i)
5300 x = XVECEXP (vals, 0, i);
5301 if (!CONSTANT_P (x))
5302 ++n_var, one_var = i;
5303 else if (x != CONST0_RTX (inner_mode))
5304 all_const_zero = false;
5306 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5312 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5313 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5314 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5316 /* Zero register. */
5317 emit_insn (gen_rtx_SET (VOIDmode, target,
5318 gen_rtx_XOR (mode, target, target)));
5321 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5323 /* Splat immediate. */
5324 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5329 /* Load from constant pool. */
5330 emit_move_insn (target, const_vec);
5335 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5336 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5338 rtx op0 = XVECEXP (vals, 0, 0);
5339 rtx op1 = XVECEXP (vals, 0, 1);
5342 if (!MEM_P (op0) && !REG_P (op0))
5343 op0 = force_reg (inner_mode, op0);
5344 if (mode == V2DFmode)
5345 emit_insn (gen_vsx_splat_v2df (target, op0));
5347 emit_insn (gen_vsx_splat_v2di (target, op0));
5351 op0 = force_reg (inner_mode, op0);
5352 op1 = force_reg (inner_mode, op1);
5353 if (mode == V2DFmode)
5354 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5356 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5361 /* With single precision floating point on VSX, know that internally single
5362 precision is actually represented as a double, and either make 2 V2DF
5363 vectors, and convert these vectors to single precision, or do one
5364 conversion, and splat the result to the other elements. */
5365 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5369 rtx freg = gen_reg_rtx (V4SFmode);
5370 rtx sreg = force_reg (SFmode, XVECEXP (vals, 0, 0));
5372 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5373 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5377 rtx dbl_even = gen_reg_rtx (V2DFmode);
5378 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5379 rtx flt_even = gen_reg_rtx (V4SFmode);
5380 rtx flt_odd = gen_reg_rtx (V4SFmode);
5381 rtx op0 = force_reg (SFmode, XVECEXP (vals, 0, 0));
5382 rtx op1 = force_reg (SFmode, XVECEXP (vals, 0, 1));
5383 rtx op2 = force_reg (SFmode, XVECEXP (vals, 0, 2));
5384 rtx op3 = force_reg (SFmode, XVECEXP (vals, 0, 3));
5386 emit_insn (gen_vsx_concat_v2sf (dbl_even, op0, op1));
5387 emit_insn (gen_vsx_concat_v2sf (dbl_odd, op2, op3));
5388 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5389 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5390 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5395 /* Store value to stack temp. Load vector element. Splat. However, splat
5396 of 64-bit items is not supported on Altivec. */
5397 if (all_same && GET_MODE_SIZE (mode) <= 4)
5399 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5400 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5401 XVECEXP (vals, 0, 0));
5402 x = gen_rtx_UNSPEC (VOIDmode,
5403 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5404 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5406 gen_rtx_SET (VOIDmode,
5409 x = gen_rtx_VEC_SELECT (inner_mode, target,
5410 gen_rtx_PARALLEL (VOIDmode,
5411 gen_rtvec (1, const0_rtx)));
5412 emit_insn (gen_rtx_SET (VOIDmode, target,
5413 gen_rtx_VEC_DUPLICATE (mode, x)));
5417 /* One field is non-constant. Load constant then overwrite
5421 rtx copy = copy_rtx (vals);
5423 /* Load constant part of vector, substitute neighboring value for
5425 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5426 rs6000_expand_vector_init (target, copy);
5428 /* Insert variable. */
5429 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5433 /* Construct the vector in memory one field at a time
5434 and load the whole vector. */
5435 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5436 for (i = 0; i < n_elts; i++)
5437 emit_move_insn (adjust_address_nv (mem, inner_mode,
5438 i * GET_MODE_SIZE (inner_mode)),
5439 XVECEXP (vals, 0, i));
5440 emit_move_insn (target, mem);
5443 /* Set field ELT of TARGET to VAL. */
5446 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5448 enum machine_mode mode = GET_MODE (target);
5449 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5450 rtx reg = gen_reg_rtx (mode);
5452 int width = GET_MODE_SIZE (inner_mode);
5455 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5457 rtx (*set_func) (rtx, rtx, rtx, rtx)
5458 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5459 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5463 /* Load single variable value. */
5464 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5465 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5466 x = gen_rtx_UNSPEC (VOIDmode,
5467 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5468 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5470 gen_rtx_SET (VOIDmode,
5474 /* Linear sequence. */
5475 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5476 for (i = 0; i < 16; ++i)
5477 XVECEXP (mask, 0, i) = GEN_INT (i);
5479 /* Set permute mask to insert element into target. */
5480 for (i = 0; i < width; ++i)
5481 XVECEXP (mask, 0, elt*width + i)
5482 = GEN_INT (i + 0x10);
5483 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5484 x = gen_rtx_UNSPEC (mode,
5485 gen_rtvec (3, target, reg,
5486 force_reg (V16QImode, x)),
5488 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5491 /* Extract field ELT from VEC into TARGET. */
5494 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5496 enum machine_mode mode = GET_MODE (vec);
5497 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5500 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5502 rtx (*extract_func) (rtx, rtx, rtx)
5503 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5504 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5508 /* Allocate mode-sized buffer. */
5509 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5511 emit_move_insn (mem, vec);
5513 /* Add offset to field within buffer matching vector element. */
5514 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5516 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5519 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5520 implement ANDing by the mask IN. */
5522 build_mask64_2_operands (rtx in, rtx *out)
5524 #if HOST_BITS_PER_WIDE_INT >= 64
5525 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5528 gcc_assert (GET_CODE (in) == CONST_INT);
5533 /* Assume c initially something like 0x00fff000000fffff. The idea
5534 is to rotate the word so that the middle ^^^^^^ group of zeros
5535 is at the MS end and can be cleared with an rldicl mask. We then
5536 rotate back and clear off the MS ^^ group of zeros with a
5538 c = ~c; /* c == 0xff000ffffff00000 */
5539 lsb = c & -c; /* lsb == 0x0000000000100000 */
5540 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5541 c = ~c; /* c == 0x00fff000000fffff */
5542 c &= -lsb; /* c == 0x00fff00000000000 */
5543 lsb = c & -c; /* lsb == 0x0000100000000000 */
5544 c = ~c; /* c == 0xff000fffffffffff */
5545 c &= -lsb; /* c == 0xff00000000000000 */
5547 while ((lsb >>= 1) != 0)
5548 shift++; /* shift == 44 on exit from loop */
5549 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5550 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5551 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5555 /* Assume c initially something like 0xff000f0000000000. The idea
5556 is to rotate the word so that the ^^^ middle group of zeros
5557 is at the LS end and can be cleared with an rldicr mask. We then
5558 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5560 lsb = c & -c; /* lsb == 0x0000010000000000 */
5561 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5562 c = ~c; /* c == 0x00fff0ffffffffff */
5563 c &= -lsb; /* c == 0x00fff00000000000 */
5564 lsb = c & -c; /* lsb == 0x0000100000000000 */
5565 c = ~c; /* c == 0xff000fffffffffff */
5566 c &= -lsb; /* c == 0xff00000000000000 */
5568 while ((lsb >>= 1) != 0)
5569 shift++; /* shift == 44 on exit from loop */
5570 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5571 m1 >>= shift; /* m1 == 0x0000000000000fff */
5572 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5575 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5576 masks will be all 1's. We are guaranteed more than one transition. */
5577 out[0] = GEN_INT (64 - shift);
5578 out[1] = GEN_INT (m1);
5579 out[2] = GEN_INT (shift);
5580 out[3] = GEN_INT (m2);
5588 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5591 invalid_e500_subreg (rtx op, enum machine_mode mode)
5593 if (TARGET_E500_DOUBLE)
5595 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5596 subreg:TI and reg:TF. Decimal float modes are like integer
5597 modes (only low part of each register used) for this
5599 if (GET_CODE (op) == SUBREG
5600 && (mode == SImode || mode == DImode || mode == TImode
5601 || mode == DDmode || mode == TDmode)
5602 && REG_P (SUBREG_REG (op))
5603 && (GET_MODE (SUBREG_REG (op)) == DFmode
5604 || GET_MODE (SUBREG_REG (op)) == TFmode))
5607 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5609 if (GET_CODE (op) == SUBREG
5610 && (mode == DFmode || mode == TFmode)
5611 && REG_P (SUBREG_REG (op))
5612 && (GET_MODE (SUBREG_REG (op)) == DImode
5613 || GET_MODE (SUBREG_REG (op)) == TImode
5614 || GET_MODE (SUBREG_REG (op)) == DDmode
5615 || GET_MODE (SUBREG_REG (op)) == TDmode))
5620 && GET_CODE (op) == SUBREG
5622 && REG_P (SUBREG_REG (op))
5623 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5629 /* AIX increases natural record alignment to doubleword if the first
5630 field is an FP double while the FP fields remain word aligned. */
5633 rs6000_special_round_type_align (tree type, unsigned int computed,
5634 unsigned int specified)
5636 unsigned int align = MAX (computed, specified);
5637 tree field = TYPE_FIELDS (type);
5639 /* Skip all non field decls */
5640 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5641 field = DECL_CHAIN (field);
5643 if (field != NULL && field != type)
5645 type = TREE_TYPE (field);
5646 while (TREE_CODE (type) == ARRAY_TYPE)
5647 type = TREE_TYPE (type);
5649 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5650 align = MAX (align, 64);
5656 /* Darwin increases record alignment to the natural alignment of
5660 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5661 unsigned int specified)
5663 unsigned int align = MAX (computed, specified);
5665 if (TYPE_PACKED (type))
5668 /* Find the first field, looking down into aggregates. */
5670 tree field = TYPE_FIELDS (type);
5671 /* Skip all non field decls */
5672 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5673 field = DECL_CHAIN (field);
5676 /* A packed field does not contribute any extra alignment. */
5677 if (DECL_PACKED (field))
5679 type = TREE_TYPE (field);
5680 while (TREE_CODE (type) == ARRAY_TYPE)
5681 type = TREE_TYPE (type);
5682 } while (AGGREGATE_TYPE_P (type));
5684 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5685 align = MAX (align, TYPE_ALIGN (type));
5690 /* Return 1 for an operand in small memory on V.4/eabi. */
5693 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5694 enum machine_mode mode ATTRIBUTE_UNUSED)
5699 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5702 if (DEFAULT_ABI != ABI_V4)
5705 /* Vector and float memory instructions have a limited offset on the
5706 SPE, so using a vector or float variable directly as an operand is
5709 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5712 if (GET_CODE (op) == SYMBOL_REF)
5715 else if (GET_CODE (op) != CONST
5716 || GET_CODE (XEXP (op, 0)) != PLUS
5717 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5718 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5723 rtx sum = XEXP (op, 0);
5724 HOST_WIDE_INT summand;
5726 /* We have to be careful here, because it is the referenced address
5727 that must be 32k from _SDA_BASE_, not just the symbol. */
5728 summand = INTVAL (XEXP (sum, 1));
5729 if (summand < 0 || summand > g_switch_value)
5732 sym_ref = XEXP (sum, 0);
5735 return SYMBOL_REF_SMALL_P (sym_ref);
5741 /* Return true if either operand is a general purpose register. */
5744 gpr_or_gpr_p (rtx op0, rtx op1)
5746 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5747 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5751 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5754 reg_offset_addressing_ok_p (enum machine_mode mode)
5764 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5765 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5773 /* Paired vector modes. Only reg+reg addressing is valid. */
5774 if (TARGET_PAIRED_FLOAT)
5786 virtual_stack_registers_memory_p (rtx op)
5790 if (GET_CODE (op) == REG)
5791 regnum = REGNO (op);
5793 else if (GET_CODE (op) == PLUS
5794 && GET_CODE (XEXP (op, 0)) == REG
5795 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5796 regnum = REGNO (XEXP (op, 0));
5801 return (regnum >= FIRST_VIRTUAL_REGISTER
5802 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5805 /* Return true if memory accesses to OP are known to never straddle
5809 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5810 enum machine_mode mode)
5813 unsigned HOST_WIDE_INT dsize, dalign;
5815 if (GET_CODE (op) != SYMBOL_REF)
5818 decl = SYMBOL_REF_DECL (op);
5821 if (GET_MODE_SIZE (mode) == 0)
5824 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5825 replacing memory addresses with an anchor plus offset. We
5826 could find the decl by rummaging around in the block->objects
5827 VEC for the given offset but that seems like too much work. */
5829 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5830 && SYMBOL_REF_ANCHOR_P (op)
5831 && SYMBOL_REF_BLOCK (op) != NULL)
5833 struct object_block *block = SYMBOL_REF_BLOCK (op);
5834 HOST_WIDE_INT lsb, mask;
5836 /* Given the alignment of the block.. */
5837 dalign = block->alignment;
5838 mask = dalign / BITS_PER_UNIT - 1;
5840 /* ..and the combined offset of the anchor and any offset
5841 to this block object.. */
5842 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5843 lsb = offset & -offset;
5845 /* ..find how many bits of the alignment we know for the
5850 return dalign >= GET_MODE_SIZE (mode);
5855 if (TREE_CODE (decl) == FUNCTION_DECL)
5858 if (!DECL_SIZE_UNIT (decl))
5861 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5864 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5868 dalign = DECL_ALIGN_UNIT (decl);
5869 return dalign >= dsize;
5872 type = TREE_TYPE (decl);
5874 if (TREE_CODE (decl) == STRING_CST)
5875 dsize = TREE_STRING_LENGTH (decl);
5876 else if (TYPE_SIZE_UNIT (type)
5877 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5878 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5884 dalign = TYPE_ALIGN (type);
5885 if (CONSTANT_CLASS_P (decl))
5886 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5888 dalign = DATA_ALIGNMENT (decl, dalign);
5889 dalign /= BITS_PER_UNIT;
5890 return dalign >= dsize;
5894 constant_pool_expr_p (rtx op)
5898 split_const (op, &base, &offset);
5899 return (GET_CODE (base) == SYMBOL_REF
5900 && CONSTANT_POOL_ADDRESS_P (base)
5901 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5904 static rtx tocrel_base, tocrel_offset;
5907 toc_relative_expr_p (rtx op)
5909 if (GET_CODE (op) != CONST)
5912 split_const (op, &tocrel_base, &tocrel_offset);
5913 return (GET_CODE (tocrel_base) == UNSPEC
5914 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5917 /* Return true if X is a constant pool address, and also for cmodel=medium
5918 if X is a toc-relative address known to be offsettable within MODE. */
5921 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5925 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5926 && GET_CODE (XEXP (x, 0)) == REG
5927 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5928 || ((TARGET_MINIMAL_TOC
5929 || TARGET_CMODEL != CMODEL_SMALL)
5930 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5931 && toc_relative_expr_p (XEXP (x, 1))
5932 && (TARGET_CMODEL != CMODEL_MEDIUM
5933 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5935 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5936 INTVAL (tocrel_offset), mode)));
5940 legitimate_small_data_p (enum machine_mode mode, rtx x)
5942 return (DEFAULT_ABI == ABI_V4
5943 && !flag_pic && !TARGET_TOC
5944 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5945 && small_data_operand (x, mode));
5948 /* SPE offset addressing is limited to 5-bits worth of double words. */
5949 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5952 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5954 unsigned HOST_WIDE_INT offset, extra;
5956 if (GET_CODE (x) != PLUS)
5958 if (GET_CODE (XEXP (x, 0)) != REG)
5960 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5962 if (!reg_offset_addressing_ok_p (mode))
5963 return virtual_stack_registers_memory_p (x);
5964 if (legitimate_constant_pool_address_p (x, mode, strict))
5966 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5969 offset = INTVAL (XEXP (x, 1));
5977 /* SPE vector modes. */
5978 return SPE_CONST_OFFSET_OK (offset);
5981 if (TARGET_E500_DOUBLE)
5982 return SPE_CONST_OFFSET_OK (offset);
5984 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5986 if (VECTOR_MEM_VSX_P (DFmode))
5991 /* On e500v2, we may have:
5993 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5995 Which gets addressed with evldd instructions. */
5996 if (TARGET_E500_DOUBLE)
5997 return SPE_CONST_OFFSET_OK (offset);
5999 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
6001 else if (offset & 3)
6006 if (TARGET_E500_DOUBLE)
6007 return (SPE_CONST_OFFSET_OK (offset)
6008 && SPE_CONST_OFFSET_OK (offset + 8));
6012 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
6014 else if (offset & 3)
6025 return (offset < 0x10000) && (offset + extra < 0x10000);
6029 legitimate_indexed_address_p (rtx x, int strict)
6033 if (GET_CODE (x) != PLUS)
6039 /* Recognize the rtl generated by reload which we know will later be
6040 replaced with proper base and index regs. */
6042 && reload_in_progress
6043 && (REG_P (op0) || GET_CODE (op0) == PLUS)
6047 return (REG_P (op0) && REG_P (op1)
6048 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
6049 && INT_REG_OK_FOR_INDEX_P (op1, strict))
6050 || (INT_REG_OK_FOR_BASE_P (op1, strict)
6051 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
6055 avoiding_indexed_address_p (enum machine_mode mode)
6057 /* Avoid indexed addressing for modes that have non-indexed
6058 load/store instruction forms. */
6059 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
6063 legitimate_indirect_address_p (rtx x, int strict)
6065 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
6069 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
6071 if (!TARGET_MACHO || !flag_pic
6072 || mode != SImode || GET_CODE (x) != MEM)
6076 if (GET_CODE (x) != LO_SUM)
6078 if (GET_CODE (XEXP (x, 0)) != REG)
6080 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
6084 return CONSTANT_P (x);
6088 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
6090 if (GET_CODE (x) != LO_SUM)
6092 if (GET_CODE (XEXP (x, 0)) != REG)
6094 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
6096 /* Restrict addressing for DI because of our SUBREG hackery. */
6097 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6098 || mode == DDmode || mode == TDmode
6103 if (TARGET_ELF || TARGET_MACHO)
6105 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
6109 if (GET_MODE_NUNITS (mode) != 1)
6111 if (GET_MODE_BITSIZE (mode) > 64
6112 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6113 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6114 && (mode == DFmode || mode == DDmode))))
6117 return CONSTANT_P (x);
6124 /* Try machine-dependent ways of modifying an illegitimate address
6125 to be legitimate. If we find one, return the new, valid address.
6126 This is used from only one place: `memory_address' in explow.c.
6128 OLDX is the address as it was before break_out_memory_refs was
6129 called. In some cases it is useful to look at this to decide what
6132 It is always safe for this function to do nothing. It exists to
6133 recognize opportunities to optimize the output.
6135 On RS/6000, first check for the sum of a register with a constant
6136 integer that is out of range. If so, generate code to add the
6137 constant with the low-order 16 bits masked to the register and force
6138 this result into another register (this can be done with `cau').
6139 Then generate an address of REG+(CONST&0xffff), allowing for the
6140 possibility of bit 16 being a one.
6142 Then check for the sum of a register and something not constant, try to
6143 load the other things into a register and return the sum. */
6146 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6147 enum machine_mode mode)
6149 unsigned int extra = 0;
6151 if (!reg_offset_addressing_ok_p (mode))
6153 if (virtual_stack_registers_memory_p (x))
6156 /* In theory we should not be seeing addresses of the form reg+0,
6157 but just in case it is generated, optimize it away. */
6158 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6159 return force_reg (Pmode, XEXP (x, 0));
6161 /* Make sure both operands are registers. */
6162 else if (GET_CODE (x) == PLUS)
6163 return gen_rtx_PLUS (Pmode,
6164 force_reg (Pmode, XEXP (x, 0)),
6165 force_reg (Pmode, XEXP (x, 1)));
6167 return force_reg (Pmode, x);
6169 if (GET_CODE (x) == SYMBOL_REF)
6171 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6173 return rs6000_legitimize_tls_address (x, model);
6183 if (!TARGET_POWERPC64)
6191 extra = TARGET_POWERPC64 ? 8 : 12;
6197 if (GET_CODE (x) == PLUS
6198 && GET_CODE (XEXP (x, 0)) == REG
6199 && GET_CODE (XEXP (x, 1)) == CONST_INT
6200 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6202 && !((TARGET_POWERPC64
6203 && (mode == DImode || mode == TImode)
6204 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6205 || SPE_VECTOR_MODE (mode)
6206 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6207 || mode == DImode || mode == DDmode
6208 || mode == TDmode))))
6210 HOST_WIDE_INT high_int, low_int;
6212 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6213 if (low_int >= 0x8000 - extra)
6215 high_int = INTVAL (XEXP (x, 1)) - low_int;
6216 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6217 GEN_INT (high_int)), 0);
6218 return plus_constant (sum, low_int);
6220 else if (GET_CODE (x) == PLUS
6221 && GET_CODE (XEXP (x, 0)) == REG
6222 && GET_CODE (XEXP (x, 1)) != CONST_INT
6223 && GET_MODE_NUNITS (mode) == 1
6224 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6226 || ((mode != DImode && mode != DFmode && mode != DDmode)
6227 || (TARGET_E500_DOUBLE && mode != DDmode)))
6228 && (TARGET_POWERPC64 || mode != DImode)
6229 && !avoiding_indexed_address_p (mode)
6234 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6235 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6237 else if (SPE_VECTOR_MODE (mode)
6238 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6239 || mode == DDmode || mode == TDmode
6240 || mode == DImode)))
6244 /* We accept [reg + reg] and [reg + OFFSET]. */
6246 if (GET_CODE (x) == PLUS)
6248 rtx op1 = XEXP (x, 0);
6249 rtx op2 = XEXP (x, 1);
6252 op1 = force_reg (Pmode, op1);
6254 if (GET_CODE (op2) != REG
6255 && (GET_CODE (op2) != CONST_INT
6256 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6257 || (GET_MODE_SIZE (mode) > 8
6258 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6259 op2 = force_reg (Pmode, op2);
6261 /* We can't always do [reg + reg] for these, because [reg +
6262 reg + offset] is not a legitimate addressing mode. */
6263 y = gen_rtx_PLUS (Pmode, op1, op2);
6265 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6266 return force_reg (Pmode, y);
6271 return force_reg (Pmode, x);
6277 && GET_CODE (x) != CONST_INT
6278 && GET_CODE (x) != CONST_DOUBLE
6280 && GET_MODE_NUNITS (mode) == 1
6281 && (GET_MODE_BITSIZE (mode) <= 32
6282 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6283 && (mode == DFmode || mode == DDmode))))
6285 rtx reg = gen_reg_rtx (Pmode);
6286 emit_insn (gen_elf_high (reg, x));
6287 return gen_rtx_LO_SUM (Pmode, reg, x);
6289 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6292 && ! MACHO_DYNAMIC_NO_PIC_P
6294 && GET_CODE (x) != CONST_INT
6295 && GET_CODE (x) != CONST_DOUBLE
6297 && GET_MODE_NUNITS (mode) == 1
6298 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6299 || (mode != DFmode && mode != DDmode))
6303 rtx reg = gen_reg_rtx (Pmode);
6304 emit_insn (gen_macho_high (reg, x));
6305 return gen_rtx_LO_SUM (Pmode, reg, x);
6308 && GET_CODE (x) == SYMBOL_REF
6309 && constant_pool_expr_p (x)
6310 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6312 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6313 return create_TOC_reference (x, reg);
6319 /* Debug version of rs6000_legitimize_address. */
6321 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6327 ret = rs6000_legitimize_address (x, oldx, mode);
6328 insns = get_insns ();
6334 "\nrs6000_legitimize_address: mode %s, old code %s, "
6335 "new code %s, modified\n",
6336 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6337 GET_RTX_NAME (GET_CODE (ret)));
6339 fprintf (stderr, "Original address:\n");
6342 fprintf (stderr, "oldx:\n");
6345 fprintf (stderr, "New address:\n");
6350 fprintf (stderr, "Insns added:\n");
6351 debug_rtx_list (insns, 20);
6357 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6358 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6369 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6370 We need to emit DTP-relative relocations. */
6373 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6378 fputs ("\t.long\t", file);
6381 fputs (DOUBLE_INT_ASM_OP, file);
6386 output_addr_const (file, x);
6387 fputs ("@dtprel+0x8000", file);
6390 /* In the name of slightly smaller debug output, and to cater to
6391 general assembler lossage, recognize various UNSPEC sequences
6392 and turn them back into a direct symbol reference. */
6395 rs6000_delegitimize_address (rtx orig_x)
6399 orig_x = delegitimize_mem_from_attrs (orig_x);
6404 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6405 && GET_CODE (XEXP (x, 1)) == CONST)
6407 y = XEXP (XEXP (x, 1), 0);
6408 if (GET_CODE (y) == UNSPEC
6409 && XINT (y, 1) == UNSPEC_TOCREL
6410 && ((GET_CODE (XEXP (x, 0)) == REG
6411 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6412 || TARGET_MINIMAL_TOC
6413 || TARGET_CMODEL != CMODEL_SMALL))
6414 || (TARGET_CMODEL != CMODEL_SMALL
6415 && GET_CODE (XEXP (x, 0)) == CONST
6416 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
6417 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
6418 && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
6419 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
6420 && rtx_equal_p (XEXP (x, 1),
6421 XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
6423 y = XVECEXP (y, 0, 0);
6424 if (!MEM_P (orig_x))
6427 return replace_equiv_address_nv (orig_x, y);
6432 && GET_CODE (orig_x) == LO_SUM
6433 && GET_CODE (XEXP (x, 1)) == CONST)
6435 y = XEXP (XEXP (x, 1), 0);
6436 if (GET_CODE (y) == UNSPEC
6437 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6438 return XVECEXP (y, 0, 0);
6444 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6446 static GTY(()) rtx rs6000_tls_symbol;
6448 rs6000_tls_get_addr (void)
6450 if (!rs6000_tls_symbol)
6451 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6453 return rs6000_tls_symbol;
6456 /* Construct the SYMBOL_REF for TLS GOT references. */
6458 static GTY(()) rtx rs6000_got_symbol;
6460 rs6000_got_sym (void)
6462 if (!rs6000_got_symbol)
6464 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6465 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6466 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6469 return rs6000_got_symbol;
6472 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6473 this (thread-local) address. */
6476 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6480 dest = gen_reg_rtx (Pmode);
6481 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6487 tlsreg = gen_rtx_REG (Pmode, 13);
6488 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6492 tlsreg = gen_rtx_REG (Pmode, 2);
6493 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6497 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6501 tmp = gen_reg_rtx (Pmode);
6504 tlsreg = gen_rtx_REG (Pmode, 13);
6505 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6509 tlsreg = gen_rtx_REG (Pmode, 2);
6510 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6514 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6516 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6521 rtx r3, got, tga, tmp1, tmp2, call_insn;
6523 /* We currently use relocations like @got@tlsgd for tls, which
6524 means the linker will handle allocation of tls entries, placing
6525 them in the .got section. So use a pointer to the .got section,
6526 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6527 or to secondary GOT sections used by 32-bit -fPIC. */
6529 got = gen_rtx_REG (Pmode, 2);
6533 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6536 rtx gsym = rs6000_got_sym ();
6537 got = gen_reg_rtx (Pmode);
6539 rs6000_emit_move (got, gsym, Pmode);
6544 tmp1 = gen_reg_rtx (Pmode);
6545 tmp2 = gen_reg_rtx (Pmode);
6546 mem = gen_const_mem (Pmode, tmp1);
6547 lab = gen_label_rtx ();
6548 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6549 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6550 emit_move_insn (tmp2, mem);
6551 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6552 set_unique_reg_note (last, REG_EQUAL, gsym);
6557 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6559 tga = rs6000_tls_get_addr ();
6560 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
6561 1, const0_rtx, Pmode);
6563 r3 = gen_rtx_REG (Pmode, 3);
6564 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6565 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6566 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6567 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6568 else if (DEFAULT_ABI == ABI_V4)
6569 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6572 call_insn = last_call_insn ();
6573 PATTERN (call_insn) = insn;
6574 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6575 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6576 pic_offset_table_rtx);
6578 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6580 tga = rs6000_tls_get_addr ();
6581 tmp1 = gen_reg_rtx (Pmode);
6582 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
6583 1, const0_rtx, Pmode);
6585 r3 = gen_rtx_REG (Pmode, 3);
6586 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6587 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6588 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6589 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6590 else if (DEFAULT_ABI == ABI_V4)
6591 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6594 call_insn = last_call_insn ();
6595 PATTERN (call_insn) = insn;
6596 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6597 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6598 pic_offset_table_rtx);
6600 if (rs6000_tls_size == 16)
6603 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6605 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6607 else if (rs6000_tls_size == 32)
6609 tmp2 = gen_reg_rtx (Pmode);
6611 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6613 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6616 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6618 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6622 tmp2 = gen_reg_rtx (Pmode);
6624 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6626 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6628 insn = gen_rtx_SET (Pmode, dest,
6629 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6635 /* IE, or 64-bit offset LE. */
6636 tmp2 = gen_reg_rtx (Pmode);
6638 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6640 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6643 insn = gen_tls_tls_64 (dest, tmp2, addr);
6645 insn = gen_tls_tls_32 (dest, tmp2, addr);
6653 /* Return 1 if X contains a thread-local symbol. */
6656 rs6000_tls_referenced_p (rtx x)
6658 if (! TARGET_HAVE_TLS)
6661 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6664 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6667 rs6000_cannot_force_const_mem (rtx x)
6669 if (GET_CODE (x) == CONST
6670 && GET_CODE (XEXP (x, 0)) == PLUS
6671 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
6674 return rs6000_tls_referenced_p (x);
6677 /* Return 1 if *X is a thread-local symbol. This is the same as
6678 rs6000_tls_symbol_ref except for the type of the unused argument. */
6681 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6683 return RS6000_SYMBOL_REF_TLS_P (*x);
6686 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6687 replace the input X, or the original X if no replacement is called for.
6688 The output parameter *WIN is 1 if the calling macro should goto WIN,
6691 For RS/6000, we wish to handle large displacements off a base
6692 register by splitting the addend across an addiu/addis and the mem insn.
6693 This cuts number of extra insns needed from 3 to 1.
6695 On Darwin, we use this to generate code for floating point constants.
6696 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6697 The Darwin code is inside #if TARGET_MACHO because only then are the
6698 machopic_* functions defined. */
6700 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6701 int opnum, int type,
6702 int ind_levels ATTRIBUTE_UNUSED, int *win)
6704 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6706 /* We must recognize output that we have already generated ourselves. */
6707 if (GET_CODE (x) == PLUS
6708 && GET_CODE (XEXP (x, 0)) == PLUS
6709 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6710 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6711 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6713 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6714 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6715 opnum, (enum reload_type)type);
6720 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6721 if (GET_CODE (x) == LO_SUM
6722 && GET_CODE (XEXP (x, 0)) == HIGH)
6724 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6725 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6726 opnum, (enum reload_type)type);
6732 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6733 && GET_CODE (x) == LO_SUM
6734 && GET_CODE (XEXP (x, 0)) == PLUS
6735 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6736 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6737 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6738 && machopic_operand_p (XEXP (x, 1)))
6740 /* Result of previous invocation of this function on Darwin
6741 floating point constant. */
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);
6750 if (TARGET_CMODEL != CMODEL_SMALL
6751 && GET_CODE (x) == LO_SUM
6752 && GET_CODE (XEXP (x, 0)) == PLUS
6753 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6754 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6755 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
6756 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
6757 && GET_CODE (XEXP (x, 1)) == CONST
6758 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6759 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6760 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
6762 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6763 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6764 opnum, (enum reload_type) type);
6769 /* Force ld/std non-word aligned offset into base register by wrapping
6771 if (GET_CODE (x) == PLUS
6772 && GET_CODE (XEXP (x, 0)) == REG
6773 && REGNO (XEXP (x, 0)) < 32
6774 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6775 && GET_CODE (XEXP (x, 1)) == CONST_INT
6777 && (INTVAL (XEXP (x, 1)) & 3) != 0
6778 && VECTOR_MEM_NONE_P (mode)
6779 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6780 && TARGET_POWERPC64)
6782 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6783 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6784 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6785 opnum, (enum reload_type) type);
6790 if (GET_CODE (x) == PLUS
6791 && GET_CODE (XEXP (x, 0)) == REG
6792 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6793 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6794 && GET_CODE (XEXP (x, 1)) == CONST_INT
6796 && !SPE_VECTOR_MODE (mode)
6797 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6798 || mode == DDmode || mode == TDmode
6800 && VECTOR_MEM_NONE_P (mode))
6802 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6803 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6805 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6807 /* Check for 32-bit overflow. */
6808 if (high + low != val)
6814 /* Reload the high part into a base reg; leave the low part
6815 in the mem directly. */
6817 x = gen_rtx_PLUS (GET_MODE (x),
6818 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6822 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6823 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6824 opnum, (enum reload_type)type);
6829 if (GET_CODE (x) == SYMBOL_REF
6831 && VECTOR_MEM_NONE_P (mode)
6832 && !SPE_VECTOR_MODE (mode)
6834 && DEFAULT_ABI == ABI_DARWIN
6835 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6836 && machopic_symbol_defined_p (x)
6838 && DEFAULT_ABI == ABI_V4
6841 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6842 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6846 && (mode != DImode || TARGET_POWERPC64)
6847 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6848 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6853 rtx offset = machopic_gen_offset (x);
6854 x = gen_rtx_LO_SUM (GET_MODE (x),
6855 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6856 gen_rtx_HIGH (Pmode, offset)), offset);
6860 x = gen_rtx_LO_SUM (GET_MODE (x),
6861 gen_rtx_HIGH (Pmode, x), x);
6863 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6864 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6865 opnum, (enum reload_type)type);
6870 /* Reload an offset address wrapped by an AND that represents the
6871 masking of the lower bits. Strip the outer AND and let reload
6872 convert the offset address into an indirect address. For VSX,
6873 force reload to create the address with an AND in a separate
6874 register, because we can't guarantee an altivec register will
6876 if (VECTOR_MEM_ALTIVEC_P (mode)
6877 && GET_CODE (x) == AND
6878 && GET_CODE (XEXP (x, 0)) == PLUS
6879 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6880 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6881 && GET_CODE (XEXP (x, 1)) == CONST_INT
6882 && INTVAL (XEXP (x, 1)) == -16)
6891 && GET_CODE (x) == SYMBOL_REF
6892 && constant_pool_expr_p (x)
6893 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6895 x = create_TOC_reference (x, NULL_RTX);
6896 if (TARGET_CMODEL != CMODEL_SMALL)
6897 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6898 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6899 opnum, (enum reload_type) type);
6907 /* Debug version of rs6000_legitimize_reload_address. */
6909 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6910 int opnum, int type,
6911 int ind_levels, int *win)
6913 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6916 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6917 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6918 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6922 fprintf (stderr, "Same address returned\n");
6924 fprintf (stderr, "NULL returned\n");
6927 fprintf (stderr, "New address:\n");
6934 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6935 that is a valid memory address for an instruction.
6936 The MODE argument is the machine mode for the MEM expression
6937 that wants to use this address.
6939 On the RS/6000, there are four valid address: a SYMBOL_REF that
6940 refers to a constant pool entry of an address (or the sum of it
6941 plus a constant), a short (16-bit signed) constant plus a register,
6942 the sum of two registers, or a register indirect, possibly with an
6943 auto-increment. For DFmode, DDmode and DImode with a constant plus
6944 register, we must ensure that both words are addressable or PowerPC64
6945 with offset word aligned.
6947 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6948 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6949 because adjacent memory cells are accessed by adding word-sized offsets
6950 during assembly output. */
6952 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6954 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6956 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6957 if (VECTOR_MEM_ALTIVEC_P (mode)
6958 && GET_CODE (x) == AND
6959 && GET_CODE (XEXP (x, 1)) == CONST_INT
6960 && INTVAL (XEXP (x, 1)) == -16)
6963 if (RS6000_SYMBOL_REF_TLS_P (x))
6965 if (legitimate_indirect_address_p (x, reg_ok_strict))
6967 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6968 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6969 && !SPE_VECTOR_MODE (mode)
6972 /* Restrict addressing for DI because of our SUBREG hackery. */
6973 && !(TARGET_E500_DOUBLE
6974 && (mode == DFmode || mode == DDmode || mode == DImode))
6976 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6978 if (virtual_stack_registers_memory_p (x))
6980 if (reg_offset_p && legitimate_small_data_p (mode, x))
6983 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6985 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6988 && GET_CODE (x) == PLUS
6989 && GET_CODE (XEXP (x, 0)) == REG
6990 && (XEXP (x, 0) == virtual_stack_vars_rtx
6991 || XEXP (x, 0) == arg_pointer_rtx)
6992 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6994 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6999 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
7001 || (mode != DFmode && mode != DDmode)
7002 || (TARGET_E500_DOUBLE && mode != DDmode))
7003 && (TARGET_POWERPC64 || mode != DImode)
7004 && !avoiding_indexed_address_p (mode)
7005 && legitimate_indexed_address_p (x, reg_ok_strict))
7007 if (GET_CODE (x) == PRE_MODIFY
7011 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
7013 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
7014 && (TARGET_POWERPC64 || mode != DImode)
7015 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
7016 && !SPE_VECTOR_MODE (mode)
7017 /* Restrict addressing for DI because of our SUBREG hackery. */
7018 && !(TARGET_E500_DOUBLE
7019 && (mode == DFmode || mode == DDmode || mode == DImode))
7021 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
7022 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
7023 || (!avoiding_indexed_address_p (mode)
7024 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
7025 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
7027 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
7032 /* Debug version of rs6000_legitimate_address_p. */
7034 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
7037 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
7039 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
7040 "strict = %d, code = %s\n",
7041 ret ? "true" : "false",
7042 GET_MODE_NAME (mode),
7044 GET_RTX_NAME (GET_CODE (x)));
7050 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7053 rs6000_mode_dependent_address_p (const_rtx addr)
7055 return rs6000_mode_dependent_address_ptr (addr);
7058 /* Go to LABEL if ADDR (a legitimate address expression)
7059 has an effect that depends on the machine mode it is used for.
7061 On the RS/6000 this is true of all integral offsets (since AltiVec
7062 and VSX modes don't allow them) or is a pre-increment or decrement.
7064 ??? Except that due to conceptual problems in offsettable_address_p
7065 we can't really report the problems of integral offsets. So leave
7066 this assuming that the adjustable offset must be valid for the
7067 sub-words of a TFmode operand, which is what we had before. */
7070 rs6000_mode_dependent_address (const_rtx addr)
7072 switch (GET_CODE (addr))
7075 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7076 is considered a legitimate address before reload, so there
7077 are no offset restrictions in that case. Note that this
7078 condition is safe in strict mode because any address involving
7079 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7080 been rejected as illegitimate. */
7081 if (XEXP (addr, 0) != virtual_stack_vars_rtx
7082 && XEXP (addr, 0) != arg_pointer_rtx
7083 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
7085 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
7086 return val + 12 + 0x8000 >= 0x10000;
7091 /* Anything in the constant pool is sufficiently aligned that
7092 all bytes have the same high part address. */
7093 return !legitimate_constant_pool_address_p (addr, QImode, false);
7095 /* Auto-increment cases are now treated generically in recog.c. */
7097 return TARGET_UPDATE;
7099 /* AND is only allowed in Altivec loads. */
7110 /* Debug version of rs6000_mode_dependent_address. */
7112 rs6000_debug_mode_dependent_address (const_rtx addr)
7114 bool ret = rs6000_mode_dependent_address (addr);
7116 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
7117 ret ? "true" : "false");
7123 /* Implement FIND_BASE_TERM. */
7126 rs6000_find_base_term (rtx op)
7130 split_const (op, &base, &offset);
7131 if (GET_CODE (base) == UNSPEC)
7132 switch (XINT (base, 1))
7135 case UNSPEC_MACHOPIC_OFFSET:
7136 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7137 for aliasing purposes. */
7138 return XVECEXP (base, 0, 0);
7144 /* More elaborate version of recog's offsettable_memref_p predicate
7145 that works around the ??? note of rs6000_mode_dependent_address.
7146 In particular it accepts
7148 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7150 in 32-bit mode, that the recog predicate rejects. */
7153 rs6000_offsettable_memref_p (rtx op)
7158 /* First mimic offsettable_memref_p. */
7159 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7162 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7163 the latter predicate knows nothing about the mode of the memory
7164 reference and, therefore, assumes that it is the largest supported
7165 mode (TFmode). As a consequence, legitimate offsettable memory
7166 references are rejected. rs6000_legitimate_offset_address_p contains
7167 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7168 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7171 /* Change register usage conditional on target flags. */
7173 rs6000_conditional_register_usage (void)
7177 if (TARGET_DEBUG_TARGET)
7178 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7180 /* Set MQ register fixed (already call_used) if not POWER
7181 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7186 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7188 fixed_regs[13] = call_used_regs[13]
7189 = call_really_used_regs[13] = 1;
7191 /* Conditionally disable FPRs. */
7192 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7193 for (i = 32; i < 64; i++)
7194 fixed_regs[i] = call_used_regs[i]
7195 = call_really_used_regs[i] = 1;
7197 /* The TOC register is not killed across calls in a way that is
7198 visible to the compiler. */
7199 if (DEFAULT_ABI == ABI_AIX)
7200 call_really_used_regs[2] = 0;
7202 if (DEFAULT_ABI == ABI_V4
7203 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7205 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7207 if (DEFAULT_ABI == ABI_V4
7208 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7210 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7211 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7212 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7214 if (DEFAULT_ABI == ABI_DARWIN
7215 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7216 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7217 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7218 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7220 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7221 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7222 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7226 global_regs[SPEFSCR_REGNO] = 1;
7227 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7228 registers in prologues and epilogues. We no longer use r14
7229 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7230 pool for link-compatibility with older versions of GCC. Once
7231 "old" code has died out, we can return r14 to the allocation
7234 = call_used_regs[14]
7235 = call_really_used_regs[14] = 1;
7238 if (!TARGET_ALTIVEC && !TARGET_VSX)
7240 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7241 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7242 call_really_used_regs[VRSAVE_REGNO] = 1;
7245 if (TARGET_ALTIVEC || TARGET_VSX)
7246 global_regs[VSCR_REGNO] = 1;
7248 if (TARGET_ALTIVEC_ABI)
7250 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7251 call_used_regs[i] = call_really_used_regs[i] = 1;
7253 /* AIX reserves VR20:31 in non-extended ABI mode. */
7255 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7256 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7260 /* Try to output insns to set TARGET equal to the constant C if it can
7261 be done in less than N insns. Do all computations in MODE.
7262 Returns the place where the output has been placed if it can be
7263 done and the insns have been emitted. If it would take more than N
7264 insns, zero is returned and no insns and emitted. */
7267 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7268 rtx source, int n ATTRIBUTE_UNUSED)
7270 rtx result, insn, set;
7271 HOST_WIDE_INT c0, c1;
7278 dest = gen_reg_rtx (mode);
7279 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7283 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7285 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7286 GEN_INT (INTVAL (source)
7287 & (~ (HOST_WIDE_INT) 0xffff))));
7288 emit_insn (gen_rtx_SET (VOIDmode, dest,
7289 gen_rtx_IOR (SImode, copy_rtx (result),
7290 GEN_INT (INTVAL (source) & 0xffff))));
7295 switch (GET_CODE (source))
7298 c0 = INTVAL (source);
7303 #if HOST_BITS_PER_WIDE_INT >= 64
7304 c0 = CONST_DOUBLE_LOW (source);
7307 c0 = CONST_DOUBLE_LOW (source);
7308 c1 = CONST_DOUBLE_HIGH (source);
7316 result = rs6000_emit_set_long_const (dest, c0, c1);
7323 insn = get_last_insn ();
7324 set = single_set (insn);
7325 if (! CONSTANT_P (SET_SRC (set)))
7326 set_unique_reg_note (insn, REG_EQUAL, source);
7331 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7332 fall back to a straight forward decomposition. We do this to avoid
7333 exponential run times encountered when looking for longer sequences
7334 with rs6000_emit_set_const. */
7336 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7338 if (!TARGET_POWERPC64)
7340 rtx operand1, operand2;
7342 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7344 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7346 emit_move_insn (operand1, GEN_INT (c1));
7347 emit_move_insn (operand2, GEN_INT (c2));
7351 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7354 ud2 = (c1 & 0xffff0000) >> 16;
7355 #if HOST_BITS_PER_WIDE_INT >= 64
7359 ud4 = (c2 & 0xffff0000) >> 16;
7361 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7362 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7365 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7367 emit_move_insn (dest, GEN_INT (ud1));
7370 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7371 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7374 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7377 emit_move_insn (dest, GEN_INT (ud2 << 16));
7379 emit_move_insn (copy_rtx (dest),
7380 gen_rtx_IOR (DImode, copy_rtx (dest),
7383 else if (ud3 == 0 && ud4 == 0)
7385 gcc_assert (ud2 & 0x8000);
7386 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7389 emit_move_insn (copy_rtx (dest),
7390 gen_rtx_IOR (DImode, copy_rtx (dest),
7392 emit_move_insn (copy_rtx (dest),
7393 gen_rtx_ZERO_EXTEND (DImode,
7394 gen_lowpart (SImode,
7397 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7398 || (ud4 == 0 && ! (ud3 & 0x8000)))
7401 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7404 emit_move_insn (dest, GEN_INT (ud3 << 16));
7407 emit_move_insn (copy_rtx (dest),
7408 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),
7421 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7424 emit_move_insn (dest, GEN_INT (ud4 << 16));
7427 emit_move_insn (copy_rtx (dest),
7428 gen_rtx_IOR (DImode, copy_rtx (dest),
7431 emit_move_insn (copy_rtx (dest),
7432 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7435 emit_move_insn (copy_rtx (dest),
7436 gen_rtx_IOR (DImode, copy_rtx (dest),
7437 GEN_INT (ud2 << 16)));
7439 emit_move_insn (copy_rtx (dest),
7440 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7446 /* Helper for the following. Get rid of [r+r] memory refs
7447 in cases where it won't work (TImode, TFmode, TDmode). */
7450 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7452 if (reload_in_progress)
7455 if (GET_CODE (operands[0]) == MEM
7456 && GET_CODE (XEXP (operands[0], 0)) != REG
7457 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7458 GET_MODE (operands[0]), false))
7460 = replace_equiv_address (operands[0],
7461 copy_addr_to_reg (XEXP (operands[0], 0)));
7463 if (GET_CODE (operands[1]) == MEM
7464 && GET_CODE (XEXP (operands[1], 0)) != REG
7465 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7466 GET_MODE (operands[1]), false))
7468 = replace_equiv_address (operands[1],
7469 copy_addr_to_reg (XEXP (operands[1], 0)));
7472 /* Emit a move from SOURCE to DEST in mode MODE. */
7474 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7478 operands[1] = source;
7480 if (TARGET_DEBUG_ADDR)
7483 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7484 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7485 GET_MODE_NAME (mode),
7488 can_create_pseudo_p ());
7490 fprintf (stderr, "source:\n");
7494 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7495 if (GET_CODE (operands[1]) == CONST_DOUBLE
7496 && ! FLOAT_MODE_P (mode)
7497 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7499 /* FIXME. This should never happen. */
7500 /* Since it seems that it does, do the safe thing and convert
7502 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7504 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7505 || FLOAT_MODE_P (mode)
7506 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7507 || CONST_DOUBLE_LOW (operands[1]) < 0)
7508 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7509 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7511 /* Check if GCC is setting up a block move that will end up using FP
7512 registers as temporaries. We must make sure this is acceptable. */
7513 if (GET_CODE (operands[0]) == MEM
7514 && GET_CODE (operands[1]) == MEM
7516 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7517 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7518 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7519 ? 32 : MEM_ALIGN (operands[0])))
7520 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7522 : MEM_ALIGN (operands[1]))))
7523 && ! MEM_VOLATILE_P (operands [0])
7524 && ! MEM_VOLATILE_P (operands [1]))
7526 emit_move_insn (adjust_address (operands[0], SImode, 0),
7527 adjust_address (operands[1], SImode, 0));
7528 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7529 adjust_address (copy_rtx (operands[1]), SImode, 4));
7533 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7534 && !gpc_reg_operand (operands[1], mode))
7535 operands[1] = force_reg (mode, operands[1]);
7537 if (mode == SFmode && ! TARGET_POWERPC
7538 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7539 && GET_CODE (operands[0]) == MEM)
7543 if (reload_in_progress || reload_completed)
7544 regnum = true_regnum (operands[1]);
7545 else if (GET_CODE (operands[1]) == REG)
7546 regnum = REGNO (operands[1]);
7550 /* If operands[1] is a register, on POWER it may have
7551 double-precision data in it, so truncate it to single
7553 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7556 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7557 : gen_reg_rtx (mode));
7558 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7559 operands[1] = newreg;
7563 /* Recognize the case where operand[1] is a reference to thread-local
7564 data and load its address to a register. */
7565 if (rs6000_tls_referenced_p (operands[1]))
7567 enum tls_model model;
7568 rtx tmp = operands[1];
7571 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7573 addend = XEXP (XEXP (tmp, 0), 1);
7574 tmp = XEXP (XEXP (tmp, 0), 0);
7577 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7578 model = SYMBOL_REF_TLS_MODEL (tmp);
7579 gcc_assert (model != 0);
7581 tmp = rs6000_legitimize_tls_address (tmp, model);
7584 tmp = gen_rtx_PLUS (mode, tmp, addend);
7585 tmp = force_operand (tmp, operands[0]);
7590 /* Handle the case where reload calls us with an invalid address. */
7591 if (reload_in_progress && mode == Pmode
7592 && (! general_operand (operands[1], mode)
7593 || ! nonimmediate_operand (operands[0], mode)))
7596 /* 128-bit constant floating-point values on Darwin should really be
7597 loaded as two parts. */
7598 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7599 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7601 rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode, 0),
7602 simplify_gen_subreg (DFmode, operands[1], mode, 0),
7604 rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode,
7605 GET_MODE_SIZE (DFmode)),
7606 simplify_gen_subreg (DFmode, operands[1], mode,
7607 GET_MODE_SIZE (DFmode)),
7612 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7613 cfun->machine->sdmode_stack_slot =
7614 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7616 if (reload_in_progress
7618 && MEM_P (operands[0])
7619 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7620 && REG_P (operands[1]))
7622 if (FP_REGNO_P (REGNO (operands[1])))
7624 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7625 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7626 emit_insn (gen_movsd_store (mem, operands[1]));
7628 else if (INT_REGNO_P (REGNO (operands[1])))
7630 rtx mem = adjust_address_nv (operands[0], mode, 4);
7631 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7632 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7638 if (reload_in_progress
7640 && REG_P (operands[0])
7641 && MEM_P (operands[1])
7642 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7644 if (FP_REGNO_P (REGNO (operands[0])))
7646 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7647 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7648 emit_insn (gen_movsd_load (operands[0], mem));
7650 else if (INT_REGNO_P (REGNO (operands[0])))
7652 rtx mem = adjust_address_nv (operands[1], mode, 4);
7653 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7654 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7661 /* FIXME: In the long term, this switch statement should go away
7662 and be replaced by a sequence of tests based on things like
7668 if (CONSTANT_P (operands[1])
7669 && GET_CODE (operands[1]) != CONST_INT)
7670 operands[1] = force_const_mem (mode, operands[1]);
7675 rs6000_eliminate_indexed_memrefs (operands);
7682 if (CONSTANT_P (operands[1])
7683 && ! easy_fp_constant (operands[1], mode))
7684 operands[1] = force_const_mem (mode, operands[1]);
7697 if (CONSTANT_P (operands[1])
7698 && !easy_vector_constant (operands[1], mode))
7699 operands[1] = force_const_mem (mode, operands[1]);
7704 /* Use default pattern for address of ELF small data */
7707 && DEFAULT_ABI == ABI_V4
7708 && (GET_CODE (operands[1]) == SYMBOL_REF
7709 || GET_CODE (operands[1]) == CONST)
7710 && small_data_operand (operands[1], mode))
7712 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7716 if (DEFAULT_ABI == ABI_V4
7717 && mode == Pmode && mode == SImode
7718 && flag_pic == 1 && got_operand (operands[1], mode))
7720 emit_insn (gen_movsi_got (operands[0], operands[1]));
7724 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7728 && CONSTANT_P (operands[1])
7729 && GET_CODE (operands[1]) != HIGH
7730 && GET_CODE (operands[1]) != CONST_INT)
7732 rtx target = (!can_create_pseudo_p ()
7734 : gen_reg_rtx (mode));
7736 /* If this is a function address on -mcall-aixdesc,
7737 convert it to the address of the descriptor. */
7738 if (DEFAULT_ABI == ABI_AIX
7739 && GET_CODE (operands[1]) == SYMBOL_REF
7740 && XSTR (operands[1], 0)[0] == '.')
7742 const char *name = XSTR (operands[1], 0);
7744 while (*name == '.')
7746 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7747 CONSTANT_POOL_ADDRESS_P (new_ref)
7748 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7749 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7750 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7751 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7752 operands[1] = new_ref;
7755 if (DEFAULT_ABI == ABI_DARWIN)
7758 if (MACHO_DYNAMIC_NO_PIC_P)
7760 /* Take care of any required data indirection. */
7761 operands[1] = rs6000_machopic_legitimize_pic_address (
7762 operands[1], mode, operands[0]);
7763 if (operands[0] != operands[1])
7764 emit_insn (gen_rtx_SET (VOIDmode,
7765 operands[0], operands[1]));
7769 emit_insn (gen_macho_high (target, operands[1]));
7770 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7774 emit_insn (gen_elf_high (target, operands[1]));
7775 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7779 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7780 and we have put it in the TOC, we just need to make a TOC-relative
7783 && GET_CODE (operands[1]) == SYMBOL_REF
7784 && constant_pool_expr_p (operands[1])
7785 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7786 get_pool_mode (operands[1])))
7787 || (TARGET_CMODEL == CMODEL_MEDIUM
7788 && GET_CODE (operands[1]) == SYMBOL_REF
7789 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7790 && SYMBOL_REF_LOCAL_P (operands[1])))
7793 if (TARGET_CMODEL != CMODEL_SMALL)
7795 if (can_create_pseudo_p ())
7796 reg = gen_reg_rtx (Pmode);
7800 operands[1] = create_TOC_reference (operands[1], reg);
7802 else if (mode == Pmode
7803 && CONSTANT_P (operands[1])
7804 && GET_CODE (operands[1]) != HIGH
7805 && !(TARGET_CMODEL != CMODEL_SMALL
7806 && GET_CODE (operands[1]) == CONST
7807 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7808 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
7809 && ((GET_CODE (operands[1]) != CONST_INT
7810 && ! easy_fp_constant (operands[1], mode))
7811 || (GET_CODE (operands[1]) == CONST_INT
7812 && (num_insns_constant (operands[1], mode)
7813 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7814 || (GET_CODE (operands[0]) == REG
7815 && FP_REGNO_P (REGNO (operands[0]))))
7816 && ! legitimate_constant_pool_address_p (operands[1], mode,
7818 && ! toc_relative_expr_p (operands[1])
7819 && (TARGET_CMODEL == CMODEL_SMALL
7820 || can_create_pseudo_p ()
7821 || (REG_P (operands[0])
7822 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7826 /* Darwin uses a special PIC legitimizer. */
7827 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7830 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7832 if (operands[0] != operands[1])
7833 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7838 /* If we are to limit the number of things we put in the TOC and
7839 this is a symbol plus a constant we can add in one insn,
7840 just put the symbol in the TOC and add the constant. Don't do
7841 this if reload is in progress. */
7842 if (GET_CODE (operands[1]) == CONST
7843 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7844 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7845 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7846 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7847 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7848 && ! side_effects_p (operands[0]))
7851 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7852 rtx other = XEXP (XEXP (operands[1], 0), 1);
7854 sym = force_reg (mode, sym);
7855 emit_insn (gen_add3_insn (operands[0], sym, other));
7859 operands[1] = force_const_mem (mode, operands[1]);
7862 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7863 && constant_pool_expr_p (XEXP (operands[1], 0))
7864 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7865 get_pool_constant (XEXP (operands[1], 0)),
7866 get_pool_mode (XEXP (operands[1], 0))))
7870 if (TARGET_CMODEL != CMODEL_SMALL)
7872 if (can_create_pseudo_p ())
7873 reg = gen_reg_rtx (Pmode);
7877 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7878 operands[1] = gen_const_mem (mode, tocref);
7879 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7885 rs6000_eliminate_indexed_memrefs (operands);
7889 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7891 gen_rtx_SET (VOIDmode,
7892 operands[0], operands[1]),
7893 gen_rtx_CLOBBER (VOIDmode,
7894 gen_rtx_SCRATCH (SImode)))));
7900 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7903 /* Above, we may have called force_const_mem which may have returned
7904 an invalid address. If we can, fix this up; otherwise, reload will
7905 have to deal with it. */
7906 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7907 operands[1] = validize_mem (operands[1]);
7910 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7913 /* Nonzero if we can use a floating-point register to pass this arg. */
7914 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7915 (SCALAR_FLOAT_MODE_P (MODE) \
7916 && (CUM)->fregno <= FP_ARG_MAX_REG \
7917 && TARGET_HARD_FLOAT && TARGET_FPRS)
7919 /* Nonzero if we can use an AltiVec register to pass this arg. */
7920 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7921 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7922 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7923 && TARGET_ALTIVEC_ABI \
7926 /* Return a nonzero value to say to return the function value in
7927 memory, just as large structures are always returned. TYPE will be
7928 the data type of the value, and FNTYPE will be the type of the
7929 function doing the returning, or @code{NULL} for libcalls.
7931 The AIX ABI for the RS/6000 specifies that all structures are
7932 returned in memory. The Darwin ABI does the same.
7934 For the Darwin 64 Bit ABI, a function result can be returned in
7935 registers or in memory, depending on the size of the return data
7936 type. If it is returned in registers, the value occupies the same
7937 registers as it would if it were the first and only function
7938 argument. Otherwise, the function places its result in memory at
7939 the location pointed to by GPR3.
7941 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7942 but a draft put them in memory, and GCC used to implement the draft
7943 instead of the final standard. Therefore, aix_struct_return
7944 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7945 compatibility can change DRAFT_V4_STRUCT_RET to override the
7946 default, and -m switches get the final word. See
7947 rs6000_option_override_internal for more details.
7949 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7950 long double support is enabled. These values are returned in memory.
7952 int_size_in_bytes returns -1 for variable size objects, which go in
7953 memory always. The cast to unsigned makes -1 > 8. */
7956 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7958 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7960 && rs6000_darwin64_abi
7961 && TREE_CODE (type) == RECORD_TYPE
7962 && int_size_in_bytes (type) > 0)
7964 CUMULATIVE_ARGS valcum;
7968 valcum.fregno = FP_ARG_MIN_REG;
7969 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7970 /* Do a trial code generation as if this were going to be passed
7971 as an argument; if any part goes in memory, we return NULL. */
7972 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7975 /* Otherwise fall through to more conventional ABI rules. */
7978 if (AGGREGATE_TYPE_P (type)
7979 && (aix_struct_return
7980 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7983 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7984 modes only exist for GCC vector types if -maltivec. */
7985 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7986 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7989 /* Return synthetic vectors in memory. */
7990 if (TREE_CODE (type) == VECTOR_TYPE
7991 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7993 static bool warned_for_return_big_vectors = false;
7994 if (!warned_for_return_big_vectors)
7996 warning (0, "GCC vector returned by reference: "
7997 "non-standard ABI extension with no compatibility guarantee");
7998 warned_for_return_big_vectors = true;
8003 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
8009 #ifdef HAVE_AS_GNU_ATTRIBUTE
8010 /* Return TRUE if a call to function FNDECL may be one that
8011 potentially affects the function calling ABI of the object file. */
8014 call_ABI_of_interest (tree fndecl)
8016 if (cgraph_state == CGRAPH_STATE_EXPANSION)
8018 struct cgraph_node *c_node;
8020 /* Libcalls are always interesting. */
8021 if (fndecl == NULL_TREE)
8024 /* Any call to an external function is interesting. */
8025 if (DECL_EXTERNAL (fndecl))
8028 /* Interesting functions that we are emitting in this object file. */
8029 c_node = cgraph_node (fndecl);
8030 return !cgraph_only_called_directly_p (c_node);
8036 /* Initialize a variable CUM of type CUMULATIVE_ARGS
8037 for a call to a function whose data type is FNTYPE.
8038 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
8040 For incoming args we set the number of arguments in the prototype large
8041 so we never return a PARALLEL. */
8044 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
8045 rtx libname ATTRIBUTE_UNUSED, int incoming,
8046 int libcall, int n_named_args,
8047 tree fndecl ATTRIBUTE_UNUSED,
8048 enum machine_mode return_mode ATTRIBUTE_UNUSED)
8050 static CUMULATIVE_ARGS zero_cumulative;
8052 *cum = zero_cumulative;
8054 cum->fregno = FP_ARG_MIN_REG;
8055 cum->vregno = ALTIVEC_ARG_MIN_REG;
8056 cum->prototype = (fntype && prototype_p (fntype));
8057 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
8058 ? CALL_LIBCALL : CALL_NORMAL);
8059 cum->sysv_gregno = GP_ARG_MIN_REG;
8060 cum->stdarg = stdarg_p (fntype);
8062 cum->nargs_prototype = 0;
8063 if (incoming || cum->prototype)
8064 cum->nargs_prototype = n_named_args;
8066 /* Check for a longcall attribute. */
8067 if ((!fntype && rs6000_default_long_calls)
8069 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
8070 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
8071 cum->call_cookie |= CALL_LONG;
8073 if (TARGET_DEBUG_ARG)
8075 fprintf (stderr, "\ninit_cumulative_args:");
8078 tree ret_type = TREE_TYPE (fntype);
8079 fprintf (stderr, " ret code = %s,",
8080 tree_code_name[ (int)TREE_CODE (ret_type) ]);
8083 if (cum->call_cookie & CALL_LONG)
8084 fprintf (stderr, " longcall,");
8086 fprintf (stderr, " proto = %d, nargs = %d\n",
8087 cum->prototype, cum->nargs_prototype);
8090 #ifdef HAVE_AS_GNU_ATTRIBUTE
8091 if (DEFAULT_ABI == ABI_V4)
8093 cum->escapes = call_ABI_of_interest (fndecl);
8100 return_type = TREE_TYPE (fntype);
8101 return_mode = TYPE_MODE (return_type);
8104 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8106 if (return_type != NULL)
8108 if (TREE_CODE (return_type) == RECORD_TYPE
8109 && TYPE_TRANSPARENT_AGGR (return_type))
8111 return_type = TREE_TYPE (first_field (return_type));
8112 return_mode = TYPE_MODE (return_type);
8114 if (AGGREGATE_TYPE_P (return_type)
8115 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8117 rs6000_returns_struct = true;
8119 if (SCALAR_FLOAT_MODE_P (return_mode))
8120 rs6000_passes_float = true;
8121 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
8122 || SPE_VECTOR_MODE (return_mode))
8123 rs6000_passes_vector = true;
8130 && TARGET_ALTIVEC_ABI
8131 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8133 error ("cannot return value in vector register because"
8134 " altivec instructions are disabled, use -maltivec"
8139 /* Return true if TYPE must be passed on the stack and not in registers. */
8142 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8144 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8145 return must_pass_in_stack_var_size (mode, type);
8147 return must_pass_in_stack_var_size_or_pad (mode, type);
8150 /* If defined, a C expression which determines whether, and in which
8151 direction, to pad out an argument with extra space. The value
8152 should be of type `enum direction': either `upward' to pad above
8153 the argument, `downward' to pad below, or `none' to inhibit
8156 For the AIX ABI structs are always stored left shifted in their
8160 function_arg_padding (enum machine_mode mode, const_tree type)
8162 #ifndef AGGREGATE_PADDING_FIXED
8163 #define AGGREGATE_PADDING_FIXED 0
8165 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8166 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8169 if (!AGGREGATE_PADDING_FIXED)
8171 /* GCC used to pass structures of the same size as integer types as
8172 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8173 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8174 passed padded downward, except that -mstrict-align further
8175 muddied the water in that multi-component structures of 2 and 4
8176 bytes in size were passed padded upward.
8178 The following arranges for best compatibility with previous
8179 versions of gcc, but removes the -mstrict-align dependency. */
8180 if (BYTES_BIG_ENDIAN)
8182 HOST_WIDE_INT size = 0;
8184 if (mode == BLKmode)
8186 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8187 size = int_size_in_bytes (type);
8190 size = GET_MODE_SIZE (mode);
8192 if (size == 1 || size == 2 || size == 4)
8198 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8200 if (type != 0 && AGGREGATE_TYPE_P (type))
8204 /* Fall back to the default. */
8205 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8208 /* If defined, a C expression that gives the alignment boundary, in bits,
8209 of an argument with the specified mode and type. If it is not defined,
8210 PARM_BOUNDARY is used for all arguments.
8212 V.4 wants long longs and doubles to be double word aligned. Just
8213 testing the mode size is a boneheaded way to do this as it means
8214 that other types such as complex int are also double word aligned.
8215 However, we're stuck with this because changing the ABI might break
8216 existing library interfaces.
8218 Doubleword align SPE vectors.
8219 Quadword align Altivec/VSX vectors.
8220 Quadword align large synthetic vector types. */
8223 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8225 if (DEFAULT_ABI == ABI_V4
8226 && (GET_MODE_SIZE (mode) == 8
8227 || (TARGET_HARD_FLOAT
8229 && (mode == TFmode || mode == TDmode))))
8231 else if (SPE_VECTOR_MODE (mode)
8232 || (type && TREE_CODE (type) == VECTOR_TYPE
8233 && int_size_in_bytes (type) >= 8
8234 && int_size_in_bytes (type) < 16))
8236 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8237 || (type && TREE_CODE (type) == VECTOR_TYPE
8238 && int_size_in_bytes (type) >= 16))
8240 else if (TARGET_MACHO
8241 && rs6000_darwin64_abi
8243 && type && TYPE_ALIGN (type) > 64)
8246 return PARM_BOUNDARY;
8249 /* For a function parm of MODE and TYPE, return the starting word in
8250 the parameter area. NWORDS of the parameter area are already used. */
8253 rs6000_parm_start (enum machine_mode mode, const_tree type,
8254 unsigned int nwords)
8257 unsigned int parm_offset;
8259 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8260 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8261 return nwords + (-(parm_offset + nwords) & align);
8264 /* Compute the size (in words) of a function argument. */
8266 static unsigned long
8267 rs6000_arg_size (enum machine_mode mode, const_tree type)
8271 if (mode != BLKmode)
8272 size = GET_MODE_SIZE (mode);
8274 size = int_size_in_bytes (type);
8277 return (size + 3) >> 2;
8279 return (size + 7) >> 3;
8282 /* Use this to flush pending int fields. */
8285 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8286 HOST_WIDE_INT bitpos, int final)
8288 unsigned int startbit, endbit;
8289 int intregs, intoffset;
8290 enum machine_mode mode;
8292 /* Handle the situations where a float is taking up the first half
8293 of the GPR, and the other half is empty (typically due to
8294 alignment restrictions). We can detect this by a 8-byte-aligned
8295 int field, or by seeing that this is the final flush for this
8296 argument. Count the word and continue on. */
8297 if (cum->floats_in_gpr == 1
8298 && (cum->intoffset % 64 == 0
8299 || (cum->intoffset == -1 && final)))
8302 cum->floats_in_gpr = 0;
8305 if (cum->intoffset == -1)
8308 intoffset = cum->intoffset;
8309 cum->intoffset = -1;
8310 cum->floats_in_gpr = 0;
8312 if (intoffset % BITS_PER_WORD != 0)
8314 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8316 if (mode == BLKmode)
8318 /* We couldn't find an appropriate mode, which happens,
8319 e.g., in packed structs when there are 3 bytes to load.
8320 Back intoffset back to the beginning of the word in this
8322 intoffset = intoffset & -BITS_PER_WORD;
8326 startbit = intoffset & -BITS_PER_WORD;
8327 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8328 intregs = (endbit - startbit) / BITS_PER_WORD;
8329 cum->words += intregs;
8330 /* words should be unsigned. */
8331 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8333 int pad = (endbit/BITS_PER_WORD) - cum->words;
8338 /* The darwin64 ABI calls for us to recurse down through structs,
8339 looking for elements passed in registers. Unfortunately, we have
8340 to track int register count here also because of misalignments
8341 in powerpc alignment mode. */
8344 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8346 HOST_WIDE_INT startbitpos)
8350 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8351 if (TREE_CODE (f) == FIELD_DECL)
8353 HOST_WIDE_INT bitpos = startbitpos;
8354 tree ftype = TREE_TYPE (f);
8355 enum machine_mode mode;
8356 if (ftype == error_mark_node)
8358 mode = TYPE_MODE (ftype);
8360 if (DECL_SIZE (f) != 0
8361 && host_integerp (bit_position (f), 1))
8362 bitpos += int_bit_position (f);
8364 /* ??? FIXME: else assume zero offset. */
8366 if (TREE_CODE (ftype) == RECORD_TYPE)
8367 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8368 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8370 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8371 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8372 cum->fregno += n_fpregs;
8373 /* Single-precision floats present a special problem for
8374 us, because they are smaller than an 8-byte GPR, and so
8375 the structure-packing rules combined with the standard
8376 varargs behavior mean that we want to pack float/float
8377 and float/int combinations into a single register's
8378 space. This is complicated by the arg advance flushing,
8379 which works on arbitrarily large groups of int-type
8383 if (cum->floats_in_gpr == 1)
8385 /* Two floats in a word; count the word and reset
8388 cum->floats_in_gpr = 0;
8390 else if (bitpos % 64 == 0)
8392 /* A float at the beginning of an 8-byte word;
8393 count it and put off adjusting cum->words until
8394 we see if a arg advance flush is going to do it
8396 cum->floats_in_gpr++;
8400 /* The float is at the end of a word, preceded
8401 by integer fields, so the arg advance flush
8402 just above has already set cum->words and
8403 everything is taken care of. */
8407 cum->words += n_fpregs;
8409 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8411 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8415 else if (cum->intoffset == -1)
8416 cum->intoffset = bitpos;
8420 /* Check for an item that needs to be considered specially under the darwin 64
8421 bit ABI. These are record types where the mode is BLK or the structure is
8424 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8426 return rs6000_darwin64_abi
8427 && ((mode == BLKmode
8428 && TREE_CODE (type) == RECORD_TYPE
8429 && int_size_in_bytes (type) > 0)
8430 || (type && TREE_CODE (type) == RECORD_TYPE
8431 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8434 /* Update the data in CUM to advance over an argument
8435 of mode MODE and data type TYPE.
8436 (TYPE is null for libcalls where that information may not be available.)
8438 Note that for args passed by reference, function_arg will be called
8439 with MODE and TYPE set to that of the pointer to the arg, not the arg
8443 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8444 const_tree type, bool named, int depth)
8446 /* Only tick off an argument if we're not recursing. */
8448 cum->nargs_prototype--;
8450 #ifdef HAVE_AS_GNU_ATTRIBUTE
8451 if (DEFAULT_ABI == ABI_V4
8454 if (SCALAR_FLOAT_MODE_P (mode))
8455 rs6000_passes_float = true;
8456 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
8457 rs6000_passes_vector = true;
8458 else if (SPE_VECTOR_MODE (mode)
8460 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8461 rs6000_passes_vector = true;
8465 if (TARGET_ALTIVEC_ABI
8466 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8467 || (type && TREE_CODE (type) == VECTOR_TYPE
8468 && int_size_in_bytes (type) == 16)))
8472 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8475 if (!TARGET_ALTIVEC)
8476 error ("cannot pass argument in vector register because"
8477 " altivec instructions are disabled, use -maltivec"
8480 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8481 even if it is going to be passed in a vector register.
8482 Darwin does the same for variable-argument functions. */
8483 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8484 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8494 /* Vector parameters must be 16-byte aligned. This places
8495 them at 2 mod 4 in terms of words in 32-bit mode, since
8496 the parameter save area starts at offset 24 from the
8497 stack. In 64-bit mode, they just have to start on an
8498 even word, since the parameter save area is 16-byte
8499 aligned. Space for GPRs is reserved even if the argument
8500 will be passed in memory. */
8502 align = (2 - cum->words) & 3;
8504 align = cum->words & 1;
8505 cum->words += align + rs6000_arg_size (mode, type);
8507 if (TARGET_DEBUG_ARG)
8509 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8511 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8512 cum->nargs_prototype, cum->prototype,
8513 GET_MODE_NAME (mode));
8517 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8519 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8522 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8524 int size = int_size_in_bytes (type);
8525 /* Variable sized types have size == -1 and are
8526 treated as if consisting entirely of ints.
8527 Pad to 16 byte boundary if needed. */
8528 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8529 && (cum->words % 2) != 0)
8531 /* For varargs, we can just go up by the size of the struct. */
8533 cum->words += (size + 7) / 8;
8536 /* It is tempting to say int register count just goes up by
8537 sizeof(type)/8, but this is wrong in a case such as
8538 { int; double; int; } [powerpc alignment]. We have to
8539 grovel through the fields for these too. */
8541 cum->floats_in_gpr = 0;
8542 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8543 rs6000_darwin64_record_arg_advance_flush (cum,
8544 size * BITS_PER_UNIT, 1);
8546 if (TARGET_DEBUG_ARG)
8548 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8549 cum->words, TYPE_ALIGN (type), size);
8551 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8552 cum->nargs_prototype, cum->prototype,
8553 GET_MODE_NAME (mode));
8556 else if (DEFAULT_ABI == ABI_V4)
8558 if (TARGET_HARD_FLOAT && TARGET_FPRS
8559 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8560 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8561 || (mode == TFmode && !TARGET_IEEEQUAD)
8562 || mode == SDmode || mode == DDmode || mode == TDmode))
8564 /* _Decimal128 must use an even/odd register pair. This assumes
8565 that the register number is odd when fregno is odd. */
8566 if (mode == TDmode && (cum->fregno % 2) == 1)
8569 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8570 <= FP_ARG_V4_MAX_REG)
8571 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8574 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8575 if (mode == DFmode || mode == TFmode
8576 || mode == DDmode || mode == TDmode)
8577 cum->words += cum->words & 1;
8578 cum->words += rs6000_arg_size (mode, type);
8583 int n_words = rs6000_arg_size (mode, type);
8584 int gregno = cum->sysv_gregno;
8586 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8587 (r7,r8) or (r9,r10). As does any other 2 word item such
8588 as complex int due to a historical mistake. */
8590 gregno += (1 - gregno) & 1;
8592 /* Multi-reg args are not split between registers and stack. */
8593 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8595 /* Long long and SPE vectors are aligned on the stack.
8596 So are other 2 word items such as complex int due to
8597 a historical mistake. */
8599 cum->words += cum->words & 1;
8600 cum->words += n_words;
8603 /* Note: continuing to accumulate gregno past when we've started
8604 spilling to the stack indicates the fact that we've started
8605 spilling to the stack to expand_builtin_saveregs. */
8606 cum->sysv_gregno = gregno + n_words;
8609 if (TARGET_DEBUG_ARG)
8611 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8612 cum->words, cum->fregno);
8613 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8614 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8615 fprintf (stderr, "mode = %4s, named = %d\n",
8616 GET_MODE_NAME (mode), named);
8621 int n_words = rs6000_arg_size (mode, type);
8622 int start_words = cum->words;
8623 int align_words = rs6000_parm_start (mode, type, start_words);
8625 cum->words = align_words + n_words;
8627 if (SCALAR_FLOAT_MODE_P (mode)
8628 && TARGET_HARD_FLOAT && TARGET_FPRS)
8630 /* _Decimal128 must be passed in an even/odd float register pair.
8631 This assumes that the register number is odd when fregno is
8633 if (mode == TDmode && (cum->fregno % 2) == 1)
8635 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8638 if (TARGET_DEBUG_ARG)
8640 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8641 cum->words, cum->fregno);
8642 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8643 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8644 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8645 named, align_words - start_words, depth);
8651 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8652 const_tree type, bool named)
8654 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8658 spe_build_register_parallel (enum machine_mode mode, int gregno)
8665 r1 = gen_rtx_REG (DImode, gregno);
8666 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8667 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8671 r1 = gen_rtx_REG (DImode, gregno);
8672 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8673 r3 = gen_rtx_REG (DImode, gregno + 2);
8674 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8675 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8678 r1 = gen_rtx_REG (DImode, gregno);
8679 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8680 r3 = gen_rtx_REG (DImode, gregno + 2);
8681 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8682 r5 = gen_rtx_REG (DImode, gregno + 4);
8683 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8684 r7 = gen_rtx_REG (DImode, gregno + 6);
8685 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8686 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8693 /* Determine where to put a SIMD argument on the SPE. */
8695 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8698 int gregno = cum->sysv_gregno;
8700 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8701 are passed and returned in a pair of GPRs for ABI compatibility. */
8702 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8703 || mode == DCmode || mode == TCmode))
8705 int n_words = rs6000_arg_size (mode, type);
8707 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8709 gregno += (1 - gregno) & 1;
8711 /* Multi-reg args are not split between registers and stack. */
8712 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8715 return spe_build_register_parallel (mode, gregno);
8719 int n_words = rs6000_arg_size (mode, type);
8721 /* SPE vectors are put in odd registers. */
8722 if (n_words == 2 && (gregno & 1) == 0)
8725 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8728 enum machine_mode m = SImode;
8730 r1 = gen_rtx_REG (m, gregno);
8731 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8732 r2 = gen_rtx_REG (m, gregno + 1);
8733 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8734 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8741 if (gregno <= GP_ARG_MAX_REG)
8742 return gen_rtx_REG (mode, gregno);
8748 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8749 structure between cum->intoffset and bitpos to integer registers. */
8752 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8753 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8755 enum machine_mode mode;
8757 unsigned int startbit, endbit;
8758 int this_regno, intregs, intoffset;
8761 if (cum->intoffset == -1)
8764 intoffset = cum->intoffset;
8765 cum->intoffset = -1;
8767 /* If this is the trailing part of a word, try to only load that
8768 much into the register. Otherwise load the whole register. Note
8769 that in the latter case we may pick up unwanted bits. It's not a
8770 problem at the moment but may wish to revisit. */
8772 if (intoffset % BITS_PER_WORD != 0)
8774 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8776 if (mode == BLKmode)
8778 /* We couldn't find an appropriate mode, which happens,
8779 e.g., in packed structs when there are 3 bytes to load.
8780 Back intoffset back to the beginning of the word in this
8782 intoffset = intoffset & -BITS_PER_WORD;
8789 startbit = intoffset & -BITS_PER_WORD;
8790 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8791 intregs = (endbit - startbit) / BITS_PER_WORD;
8792 this_regno = cum->words + intoffset / BITS_PER_WORD;
8794 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8797 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8801 intoffset /= BITS_PER_UNIT;
8804 regno = GP_ARG_MIN_REG + this_regno;
8805 reg = gen_rtx_REG (mode, regno);
8807 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8810 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8814 while (intregs > 0);
8817 /* Recursive workhorse for the following. */
8820 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8821 HOST_WIDE_INT startbitpos, rtx rvec[],
8826 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8827 if (TREE_CODE (f) == FIELD_DECL)
8829 HOST_WIDE_INT bitpos = startbitpos;
8830 tree ftype = TREE_TYPE (f);
8831 enum machine_mode mode;
8832 if (ftype == error_mark_node)
8834 mode = TYPE_MODE (ftype);
8836 if (DECL_SIZE (f) != 0
8837 && host_integerp (bit_position (f), 1))
8838 bitpos += int_bit_position (f);
8840 /* ??? FIXME: else assume zero offset. */
8842 if (TREE_CODE (ftype) == RECORD_TYPE)
8843 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8844 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8846 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8850 case SCmode: mode = SFmode; break;
8851 case DCmode: mode = DFmode; break;
8852 case TCmode: mode = TFmode; break;
8856 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8857 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8859 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8860 && (mode == TFmode || mode == TDmode));
8861 /* Long double or _Decimal128 split over regs and memory. */
8862 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8866 = gen_rtx_EXPR_LIST (VOIDmode,
8867 gen_rtx_REG (mode, cum->fregno++),
8868 GEN_INT (bitpos / BITS_PER_UNIT));
8869 if (mode == TFmode || mode == TDmode)
8872 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8874 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8876 = gen_rtx_EXPR_LIST (VOIDmode,
8877 gen_rtx_REG (mode, cum->vregno++),
8878 GEN_INT (bitpos / BITS_PER_UNIT));
8880 else if (cum->intoffset == -1)
8881 cum->intoffset = bitpos;
8885 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8886 the register(s) to be used for each field and subfield of a struct
8887 being passed by value, along with the offset of where the
8888 register's value may be found in the block. FP fields go in FP
8889 register, vector fields go in vector registers, and everything
8890 else goes in int registers, packed as in memory.
8892 This code is also used for function return values. RETVAL indicates
8893 whether this is the case.
8895 Much of this is taken from the SPARC V9 port, which has a similar
8896 calling convention. */
8899 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8900 bool named, bool retval)
8902 rtx rvec[FIRST_PSEUDO_REGISTER];
8903 int k = 1, kbase = 1;
8904 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8905 /* This is a copy; modifications are not visible to our caller. */
8906 CUMULATIVE_ARGS copy_cum = *orig_cum;
8907 CUMULATIVE_ARGS *cum = ©_cum;
8909 /* Pad to 16 byte boundary if needed. */
8910 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8911 && (cum->words % 2) != 0)
8918 /* Put entries into rvec[] for individual FP and vector fields, and
8919 for the chunks of memory that go in int regs. Note we start at
8920 element 1; 0 is reserved for an indication of using memory, and
8921 may or may not be filled in below. */
8922 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8923 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8925 /* If any part of the struct went on the stack put all of it there.
8926 This hack is because the generic code for
8927 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8928 parts of the struct are not at the beginning. */
8932 return NULL_RTX; /* doesn't go in registers at all */
8934 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8936 if (k > 1 || cum->use_stack)
8937 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8942 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8945 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8950 rtx rvec[GP_ARG_NUM_REG + 1];
8952 if (align_words >= GP_ARG_NUM_REG)
8955 n_units = rs6000_arg_size (mode, type);
8957 /* Optimize the simple case where the arg fits in one gpr, except in
8958 the case of BLKmode due to assign_parms assuming that registers are
8959 BITS_PER_WORD wide. */
8961 || (n_units == 1 && mode != BLKmode))
8962 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8965 if (align_words + n_units > GP_ARG_NUM_REG)
8966 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8967 using a magic NULL_RTX component.
8968 This is not strictly correct. Only some of the arg belongs in
8969 memory, not all of it. However, the normal scheme using
8970 function_arg_partial_nregs can result in unusual subregs, eg.
8971 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8972 store the whole arg to memory is often more efficient than code
8973 to store pieces, and we know that space is available in the right
8974 place for the whole arg. */
8975 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8980 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8981 rtx off = GEN_INT (i++ * 4);
8982 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8984 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8986 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8989 /* Determine where to put an argument to a function.
8990 Value is zero to push the argument on the stack,
8991 or a hard register in which to store the argument.
8993 MODE is the argument's machine mode.
8994 TYPE is the data type of the argument (as a tree).
8995 This is null for libcalls where that information may
8997 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8998 the preceding args and about the function being called. It is
8999 not modified in this routine.
9000 NAMED is nonzero if this argument is a named parameter
9001 (otherwise it is an extra parameter matching an ellipsis).
9003 On RS/6000 the first eight words of non-FP are normally in registers
9004 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
9005 Under V.4, the first 8 FP args are in registers.
9007 If this is floating-point and no prototype is specified, we use
9008 both an FP and integer register (or possibly FP reg and stack). Library
9009 functions (when CALL_LIBCALL is set) always have the proper types for args,
9010 so we can pass the FP value just in one register. emit_library_function
9011 doesn't support PARALLEL anyway.
9013 Note that for args passed by reference, function_arg will be called
9014 with MODE and TYPE set to that of the pointer to the arg, not the arg
9018 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9019 const_tree type, bool named)
9021 enum rs6000_abi abi = DEFAULT_ABI;
9023 /* Return a marker to indicate whether CR1 needs to set or clear the
9024 bit that V.4 uses to say fp args were passed in registers.
9025 Assume that we don't need the marker for software floating point,
9026 or compiler generated library calls. */
9027 if (mode == VOIDmode)
9030 && (cum->call_cookie & CALL_LIBCALL) == 0
9032 || (cum->nargs_prototype < 0
9033 && (cum->prototype || TARGET_NO_PROTOTYPE))))
9035 /* For the SPE, we need to crxor CR6 always. */
9037 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
9038 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
9039 return GEN_INT (cum->call_cookie
9040 | ((cum->fregno == FP_ARG_MIN_REG)
9041 ? CALL_V4_SET_FP_ARGS
9042 : CALL_V4_CLEAR_FP_ARGS));
9045 return GEN_INT (cum->call_cookie);
9048 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9050 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
9051 if (rslt != NULL_RTX)
9053 /* Else fall through to usual handling. */
9056 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
9057 if (TARGET_64BIT && ! cum->prototype)
9059 /* Vector parameters get passed in vector register
9060 and also in GPRs or memory, in absence of prototype. */
9063 align_words = (cum->words + 1) & ~1;
9065 if (align_words >= GP_ARG_NUM_REG)
9071 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9073 return gen_rtx_PARALLEL (mode,
9075 gen_rtx_EXPR_LIST (VOIDmode,
9077 gen_rtx_EXPR_LIST (VOIDmode,
9078 gen_rtx_REG (mode, cum->vregno),
9082 return gen_rtx_REG (mode, cum->vregno);
9083 else if (TARGET_ALTIVEC_ABI
9084 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
9085 || (type && TREE_CODE (type) == VECTOR_TYPE
9086 && int_size_in_bytes (type) == 16)))
9088 if (named || abi == ABI_V4)
9092 /* Vector parameters to varargs functions under AIX or Darwin
9093 get passed in memory and possibly also in GPRs. */
9094 int align, align_words, n_words;
9095 enum machine_mode part_mode;
9097 /* Vector parameters must be 16-byte aligned. This places them at
9098 2 mod 4 in terms of words in 32-bit mode, since the parameter
9099 save area starts at offset 24 from the stack. In 64-bit mode,
9100 they just have to start on an even word, since the parameter
9101 save area is 16-byte aligned. */
9103 align = (2 - cum->words) & 3;
9105 align = cum->words & 1;
9106 align_words = cum->words + align;
9108 /* Out of registers? Memory, then. */
9109 if (align_words >= GP_ARG_NUM_REG)
9112 if (TARGET_32BIT && TARGET_POWERPC64)
9113 return rs6000_mixed_function_arg (mode, type, align_words);
9115 /* The vector value goes in GPRs. Only the part of the
9116 value in GPRs is reported here. */
9118 n_words = rs6000_arg_size (mode, type);
9119 if (align_words + n_words > GP_ARG_NUM_REG)
9120 /* Fortunately, there are only two possibilities, the value
9121 is either wholly in GPRs or half in GPRs and half not. */
9124 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9127 else if (TARGET_SPE_ABI && TARGET_SPE
9128 && (SPE_VECTOR_MODE (mode)
9129 || (TARGET_E500_DOUBLE && (mode == DFmode
9132 || mode == TCmode))))
9133 return rs6000_spe_function_arg (cum, mode, type);
9135 else if (abi == ABI_V4)
9137 if (TARGET_HARD_FLOAT && TARGET_FPRS
9138 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9139 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9140 || (mode == TFmode && !TARGET_IEEEQUAD)
9141 || mode == SDmode || mode == DDmode || mode == TDmode))
9143 /* _Decimal128 must use an even/odd register pair. This assumes
9144 that the register number is odd when fregno is odd. */
9145 if (mode == TDmode && (cum->fregno % 2) == 1)
9148 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9149 <= FP_ARG_V4_MAX_REG)
9150 return gen_rtx_REG (mode, cum->fregno);
9156 int n_words = rs6000_arg_size (mode, type);
9157 int gregno = cum->sysv_gregno;
9159 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9160 (r7,r8) or (r9,r10). As does any other 2 word item such
9161 as complex int due to a historical mistake. */
9163 gregno += (1 - gregno) & 1;
9165 /* Multi-reg args are not split between registers and stack. */
9166 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9169 if (TARGET_32BIT && TARGET_POWERPC64)
9170 return rs6000_mixed_function_arg (mode, type,
9171 gregno - GP_ARG_MIN_REG);
9172 return gen_rtx_REG (mode, gregno);
9177 int align_words = rs6000_parm_start (mode, type, cum->words);
9179 /* _Decimal128 must be passed in an even/odd float register pair.
9180 This assumes that the register number is odd when fregno is odd. */
9181 if (mode == TDmode && (cum->fregno % 2) == 1)
9184 if (USE_FP_FOR_ARG_P (cum, mode, type))
9186 rtx rvec[GP_ARG_NUM_REG + 1];
9190 enum machine_mode fmode = mode;
9191 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9193 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9195 /* Currently, we only ever need one reg here because complex
9196 doubles are split. */
9197 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9198 && (fmode == TFmode || fmode == TDmode));
9200 /* Long double or _Decimal128 split over regs and memory. */
9201 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9204 /* Do we also need to pass this arg in the parameter save
9207 && (cum->nargs_prototype <= 0
9208 || (DEFAULT_ABI == ABI_AIX
9210 && align_words >= GP_ARG_NUM_REG)));
9212 if (!needs_psave && mode == fmode)
9213 return gen_rtx_REG (fmode, cum->fregno);
9218 /* Describe the part that goes in gprs or the stack.
9219 This piece must come first, before the fprs. */
9220 if (align_words < GP_ARG_NUM_REG)
9222 unsigned long n_words = rs6000_arg_size (mode, type);
9224 if (align_words + n_words > GP_ARG_NUM_REG
9225 || (TARGET_32BIT && TARGET_POWERPC64))
9227 /* If this is partially on the stack, then we only
9228 include the portion actually in registers here. */
9229 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9232 if (align_words + n_words > GP_ARG_NUM_REG)
9233 /* Not all of the arg fits in gprs. Say that it
9234 goes in memory too, using a magic NULL_RTX
9235 component. Also see comment in
9236 rs6000_mixed_function_arg for why the normal
9237 function_arg_partial_nregs scheme doesn't work
9239 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9243 r = gen_rtx_REG (rmode,
9244 GP_ARG_MIN_REG + align_words);
9245 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9246 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9248 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9252 /* The whole arg fits in gprs. */
9253 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9254 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9258 /* It's entirely in memory. */
9259 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9262 /* Describe where this piece goes in the fprs. */
9263 r = gen_rtx_REG (fmode, cum->fregno);
9264 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9266 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9268 else if (align_words < GP_ARG_NUM_REG)
9270 if (TARGET_32BIT && TARGET_POWERPC64)
9271 return rs6000_mixed_function_arg (mode, type, align_words);
9273 if (mode == BLKmode)
9276 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9283 /* For an arg passed partly in registers and partly in memory, this is
9284 the number of bytes passed in registers. For args passed entirely in
9285 registers or entirely in memory, zero. When an arg is described by a
9286 PARALLEL, perhaps using more than one register type, this function
9287 returns the number of bytes used by the first element of the PARALLEL. */
9290 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9291 tree type, bool named)
9296 if (DEFAULT_ABI == ABI_V4)
9299 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9300 && cum->nargs_prototype >= 0)
9303 /* In this complicated case we just disable the partial_nregs code. */
9304 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9307 align_words = rs6000_parm_start (mode, type, cum->words);
9309 if (USE_FP_FOR_ARG_P (cum, mode, type))
9311 /* If we are passing this arg in the fixed parameter save area
9312 (gprs or memory) as well as fprs, then this function should
9313 return the number of partial bytes passed in the parameter
9314 save area rather than partial bytes passed in fprs. */
9316 && (cum->nargs_prototype <= 0
9317 || (DEFAULT_ABI == ABI_AIX
9319 && align_words >= GP_ARG_NUM_REG)))
9321 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9322 > FP_ARG_MAX_REG + 1)
9323 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9324 else if (cum->nargs_prototype >= 0)
9328 if (align_words < GP_ARG_NUM_REG
9329 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9330 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9332 if (ret != 0 && TARGET_DEBUG_ARG)
9333 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9338 /* A C expression that indicates when an argument must be passed by
9339 reference. If nonzero for an argument, a copy of that argument is
9340 made in memory and a pointer to the argument is passed instead of
9341 the argument itself. The pointer is passed in whatever way is
9342 appropriate for passing a pointer to that type.
9344 Under V.4, aggregates and long double are passed by reference.
9346 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9347 reference unless the AltiVec vector extension ABI is in force.
9349 As an extension to all ABIs, variable sized types are passed by
9353 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9354 enum machine_mode mode, const_tree type,
9355 bool named ATTRIBUTE_UNUSED)
9357 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9359 if (TARGET_DEBUG_ARG)
9360 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9367 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9369 if (TARGET_DEBUG_ARG)
9370 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9374 if (int_size_in_bytes (type) < 0)
9376 if (TARGET_DEBUG_ARG)
9377 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9381 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9382 modes only exist for GCC vector types if -maltivec. */
9383 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9385 if (TARGET_DEBUG_ARG)
9386 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9390 /* Pass synthetic vectors in memory. */
9391 if (TREE_CODE (type) == VECTOR_TYPE
9392 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9394 static bool warned_for_pass_big_vectors = false;
9395 if (TARGET_DEBUG_ARG)
9396 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9397 if (!warned_for_pass_big_vectors)
9399 warning (0, "GCC vector passed by reference: "
9400 "non-standard ABI extension with no compatibility guarantee");
9401 warned_for_pass_big_vectors = true;
9410 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9413 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9418 for (i = 0; i < nregs; i++)
9420 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9421 if (reload_completed)
9423 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9426 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9427 i * GET_MODE_SIZE (reg_mode));
9430 tem = replace_equiv_address (tem, XEXP (tem, 0));
9434 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9438 /* Perform any needed actions needed for a function that is receiving a
9439 variable number of arguments.
9443 MODE and TYPE are the mode and type of the current parameter.
9445 PRETEND_SIZE is a variable that should be set to the amount of stack
9446 that must be pushed by the prolog to pretend that our caller pushed
9449 Normally, this macro will push all remaining incoming registers on the
9450 stack and set PRETEND_SIZE to the length of the registers pushed. */
9453 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9454 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9457 CUMULATIVE_ARGS next_cum;
9458 int reg_size = TARGET_32BIT ? 4 : 8;
9459 rtx save_area = NULL_RTX, mem;
9460 int first_reg_offset;
9463 /* Skip the last named argument. */
9465 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9467 if (DEFAULT_ABI == ABI_V4)
9469 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9473 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9474 HOST_WIDE_INT offset = 0;
9476 /* Try to optimize the size of the varargs save area.
9477 The ABI requires that ap.reg_save_area is doubleword
9478 aligned, but we don't need to allocate space for all
9479 the bytes, only those to which we actually will save
9481 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9482 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9483 if (TARGET_HARD_FLOAT && TARGET_FPRS
9484 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9485 && cfun->va_list_fpr_size)
9488 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9489 * UNITS_PER_FP_WORD;
9490 if (cfun->va_list_fpr_size
9491 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9492 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9494 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9495 * UNITS_PER_FP_WORD;
9499 offset = -((first_reg_offset * reg_size) & ~7);
9500 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9502 gpr_reg_num = cfun->va_list_gpr_size;
9503 if (reg_size == 4 && (first_reg_offset & 1))
9506 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9509 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9511 - (int) (GP_ARG_NUM_REG * reg_size);
9513 if (gpr_size + fpr_size)
9516 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9517 gcc_assert (GET_CODE (reg_save_area) == MEM);
9518 reg_save_area = XEXP (reg_save_area, 0);
9519 if (GET_CODE (reg_save_area) == PLUS)
9521 gcc_assert (XEXP (reg_save_area, 0)
9522 == virtual_stack_vars_rtx);
9523 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9524 offset += INTVAL (XEXP (reg_save_area, 1));
9527 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9530 cfun->machine->varargs_save_offset = offset;
9531 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9536 first_reg_offset = next_cum.words;
9537 save_area = virtual_incoming_args_rtx;
9539 if (targetm.calls.must_pass_in_stack (mode, type))
9540 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9543 set = get_varargs_alias_set ();
9544 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9545 && cfun->va_list_gpr_size)
9547 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9549 if (va_list_gpr_counter_field)
9551 /* V4 va_list_gpr_size counts number of registers needed. */
9552 if (nregs > cfun->va_list_gpr_size)
9553 nregs = cfun->va_list_gpr_size;
9557 /* char * va_list instead counts number of bytes needed. */
9558 if (nregs > cfun->va_list_gpr_size / reg_size)
9559 nregs = cfun->va_list_gpr_size / reg_size;
9562 mem = gen_rtx_MEM (BLKmode,
9563 plus_constant (save_area,
9564 first_reg_offset * reg_size));
9565 MEM_NOTRAP_P (mem) = 1;
9566 set_mem_alias_set (mem, set);
9567 set_mem_align (mem, BITS_PER_WORD);
9569 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9573 /* Save FP registers if needed. */
9574 if (DEFAULT_ABI == ABI_V4
9575 && TARGET_HARD_FLOAT && TARGET_FPRS
9577 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9578 && cfun->va_list_fpr_size)
9580 int fregno = next_cum.fregno, nregs;
9581 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9582 rtx lab = gen_label_rtx ();
9583 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9584 * UNITS_PER_FP_WORD);
9587 (gen_rtx_SET (VOIDmode,
9589 gen_rtx_IF_THEN_ELSE (VOIDmode,
9590 gen_rtx_NE (VOIDmode, cr1,
9592 gen_rtx_LABEL_REF (VOIDmode, lab),
9596 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9597 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9599 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9601 plus_constant (save_area, off));
9602 MEM_NOTRAP_P (mem) = 1;
9603 set_mem_alias_set (mem, set);
9604 set_mem_align (mem, GET_MODE_ALIGNMENT (
9605 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9606 ? DFmode : SFmode));
9607 emit_move_insn (mem, gen_rtx_REG (
9608 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9609 ? DFmode : SFmode, fregno));
9616 /* Create the va_list data type. */
9619 rs6000_build_builtin_va_list (void)
9621 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9623 /* For AIX, prefer 'char *' because that's what the system
9624 header files like. */
9625 if (DEFAULT_ABI != ABI_V4)
9626 return build_pointer_type (char_type_node);
9628 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9629 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9630 get_identifier ("__va_list_tag"), record);
9632 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9633 unsigned_char_type_node);
9634 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9635 unsigned_char_type_node);
9636 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9638 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9639 get_identifier ("reserved"), short_unsigned_type_node);
9640 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9641 get_identifier ("overflow_arg_area"),
9643 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9644 get_identifier ("reg_save_area"),
9647 va_list_gpr_counter_field = f_gpr;
9648 va_list_fpr_counter_field = f_fpr;
9650 DECL_FIELD_CONTEXT (f_gpr) = record;
9651 DECL_FIELD_CONTEXT (f_fpr) = record;
9652 DECL_FIELD_CONTEXT (f_res) = record;
9653 DECL_FIELD_CONTEXT (f_ovf) = record;
9654 DECL_FIELD_CONTEXT (f_sav) = record;
9656 TYPE_STUB_DECL (record) = type_decl;
9657 TYPE_NAME (record) = type_decl;
9658 TYPE_FIELDS (record) = f_gpr;
9659 DECL_CHAIN (f_gpr) = f_fpr;
9660 DECL_CHAIN (f_fpr) = f_res;
9661 DECL_CHAIN (f_res) = f_ovf;
9662 DECL_CHAIN (f_ovf) = f_sav;
9664 layout_type (record);
9666 /* The correct type is an array type of one element. */
9667 return build_array_type (record, build_index_type (size_zero_node));
9670 /* Implement va_start. */
9673 rs6000_va_start (tree valist, rtx nextarg)
9675 HOST_WIDE_INT words, n_gpr, n_fpr;
9676 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9677 tree gpr, fpr, ovf, sav, t;
9679 /* Only SVR4 needs something special. */
9680 if (DEFAULT_ABI != ABI_V4)
9682 std_expand_builtin_va_start (valist, nextarg);
9686 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9687 f_fpr = DECL_CHAIN (f_gpr);
9688 f_res = DECL_CHAIN (f_fpr);
9689 f_ovf = DECL_CHAIN (f_res);
9690 f_sav = DECL_CHAIN (f_ovf);
9692 valist = build_simple_mem_ref (valist);
9693 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9694 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9696 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9698 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9701 /* Count number of gp and fp argument registers used. */
9702 words = crtl->args.info.words;
9703 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9705 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9708 if (TARGET_DEBUG_ARG)
9709 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9710 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9711 words, n_gpr, n_fpr);
9713 if (cfun->va_list_gpr_size)
9715 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9716 build_int_cst (NULL_TREE, n_gpr));
9717 TREE_SIDE_EFFECTS (t) = 1;
9718 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9721 if (cfun->va_list_fpr_size)
9723 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9724 build_int_cst (NULL_TREE, n_fpr));
9725 TREE_SIDE_EFFECTS (t) = 1;
9726 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9728 #ifdef HAVE_AS_GNU_ATTRIBUTE
9729 if (call_ABI_of_interest (cfun->decl))
9730 rs6000_passes_float = true;
9734 /* Find the overflow area. */
9735 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9737 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9738 size_int (words * UNITS_PER_WORD));
9739 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9740 TREE_SIDE_EFFECTS (t) = 1;
9741 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9743 /* If there were no va_arg invocations, don't set up the register
9745 if (!cfun->va_list_gpr_size
9746 && !cfun->va_list_fpr_size
9747 && n_gpr < GP_ARG_NUM_REG
9748 && n_fpr < FP_ARG_V4_MAX_REG)
9751 /* Find the register save area. */
9752 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9753 if (cfun->machine->varargs_save_offset)
9754 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9755 size_int (cfun->machine->varargs_save_offset));
9756 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9757 TREE_SIDE_EFFECTS (t) = 1;
9758 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9761 /* Implement va_arg. */
9764 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9767 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9768 tree gpr, fpr, ovf, sav, reg, t, u;
9769 int size, rsize, n_reg, sav_ofs, sav_scale;
9770 tree lab_false, lab_over, addr;
9772 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9776 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9778 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9779 return build_va_arg_indirect_ref (t);
9782 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9783 earlier version of gcc, with the property that it always applied alignment
9784 adjustments to the va-args (even for zero-sized types). The cheapest way
9785 to deal with this is to replicate the effect of the part of
9786 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9788 We don't need to check for pass-by-reference because of the test above.
9789 We can return a simplifed answer, since we know there's no offset to add. */
9792 && rs6000_darwin64_abi
9793 && integer_zerop (TYPE_SIZE (type)))
9795 unsigned HOST_WIDE_INT align, boundary;
9796 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9797 align = PARM_BOUNDARY / BITS_PER_UNIT;
9798 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9799 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9800 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9801 boundary /= BITS_PER_UNIT;
9802 if (boundary > align)
9805 /* This updates arg ptr by the amount that would be necessary
9806 to align the zero-sized (but not zero-alignment) item. */
9807 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9808 fold_build2 (POINTER_PLUS_EXPR,
9810 valist_tmp, size_int (boundary - 1)));
9811 gimplify_and_add (t, pre_p);
9813 t = fold_convert (sizetype, valist_tmp);
9814 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9815 fold_convert (TREE_TYPE (valist),
9816 fold_build2 (BIT_AND_EXPR, sizetype, t,
9817 size_int (-boundary))));
9818 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9819 gimplify_and_add (t, pre_p);
9821 /* Since it is zero-sized there's no increment for the item itself. */
9822 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9823 return build_va_arg_indirect_ref (valist_tmp);
9826 if (DEFAULT_ABI != ABI_V4)
9828 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9830 tree elem_type = TREE_TYPE (type);
9831 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9832 int elem_size = GET_MODE_SIZE (elem_mode);
9834 if (elem_size < UNITS_PER_WORD)
9836 tree real_part, imag_part;
9837 gimple_seq post = NULL;
9839 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9841 /* Copy the value into a temporary, lest the formal temporary
9842 be reused out from under us. */
9843 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9844 gimple_seq_add_seq (pre_p, post);
9846 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9849 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9853 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9856 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9857 f_fpr = DECL_CHAIN (f_gpr);
9858 f_res = DECL_CHAIN (f_fpr);
9859 f_ovf = DECL_CHAIN (f_res);
9860 f_sav = DECL_CHAIN (f_ovf);
9862 valist = build_va_arg_indirect_ref (valist);
9863 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9864 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9866 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9868 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9871 size = int_size_in_bytes (type);
9872 rsize = (size + 3) / 4;
9875 if (TARGET_HARD_FLOAT && TARGET_FPRS
9876 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9877 || (TARGET_DOUBLE_FLOAT
9878 && (TYPE_MODE (type) == DFmode
9879 || TYPE_MODE (type) == TFmode
9880 || TYPE_MODE (type) == SDmode
9881 || TYPE_MODE (type) == DDmode
9882 || TYPE_MODE (type) == TDmode))))
9884 /* FP args go in FP registers, if present. */
9886 n_reg = (size + 7) / 8;
9887 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9888 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9889 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9894 /* Otherwise into GP registers. */
9903 /* Pull the value out of the saved registers.... */
9906 addr = create_tmp_var (ptr_type_node, "addr");
9908 /* AltiVec vectors never go in registers when -mabi=altivec. */
9909 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9913 lab_false = create_artificial_label (input_location);
9914 lab_over = create_artificial_label (input_location);
9916 /* Long long and SPE vectors are aligned in the registers.
9917 As are any other 2 gpr item such as complex int due to a
9918 historical mistake. */
9920 if (n_reg == 2 && reg == gpr)
9923 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9924 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9925 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9926 unshare_expr (reg), u);
9928 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9929 reg number is 0 for f1, so we want to make it odd. */
9930 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9932 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9933 build_int_cst (TREE_TYPE (reg), 1));
9934 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9937 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9938 t = build2 (GE_EXPR, boolean_type_node, u, t);
9939 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9940 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9941 gimplify_and_add (t, pre_p);
9945 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9947 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9948 build_int_cst (TREE_TYPE (reg), n_reg));
9949 u = fold_convert (sizetype, u);
9950 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9951 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9953 /* _Decimal32 varargs are located in the second word of the 64-bit
9954 FP register for 32-bit binaries. */
9955 if (!TARGET_POWERPC64
9956 && TARGET_HARD_FLOAT && TARGET_FPRS
9957 && TYPE_MODE (type) == SDmode)
9958 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9960 gimplify_assign (addr, t, pre_p);
9962 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9964 stmt = gimple_build_label (lab_false);
9965 gimple_seq_add_stmt (pre_p, stmt);
9967 if ((n_reg == 2 && !regalign) || n_reg > 2)
9969 /* Ensure that we don't find any more args in regs.
9970 Alignment has taken care of for special cases. */
9971 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9975 /* ... otherwise out of the overflow area. */
9977 /* Care for on-stack alignment if needed. */
9981 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9982 t = fold_convert (sizetype, t);
9983 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9985 t = fold_convert (TREE_TYPE (ovf), t);
9987 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9989 gimplify_assign (unshare_expr (addr), t, pre_p);
9991 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9992 gimplify_assign (unshare_expr (ovf), t, pre_p);
9996 stmt = gimple_build_label (lab_over);
9997 gimple_seq_add_stmt (pre_p, stmt);
10000 if (STRICT_ALIGNMENT
10001 && (TYPE_ALIGN (type)
10002 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
10004 /* The value (of type complex double, for example) may not be
10005 aligned in memory in the saved registers, so copy via a
10006 temporary. (This is the same code as used for SPARC.) */
10007 tree tmp = create_tmp_var (type, "va_arg_tmp");
10008 tree dest_addr = build_fold_addr_expr (tmp);
10010 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
10011 3, dest_addr, addr, size_int (rsize * 4));
10013 gimplify_and_add (copy, pre_p);
10017 addr = fold_convert (ptrtype, addr);
10018 return build_va_arg_indirect_ref (addr);
10024 def_builtin (int mask, const char *name, tree type, int code)
10026 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
10029 if (rs6000_builtin_decls[code])
10030 fatal_error ("internal error: builtin function to %s already processed",
10033 rs6000_builtin_decls[code] = t =
10034 add_builtin_function (name, type, code, BUILT_IN_MD,
10037 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
10038 switch (builtin_classify[code])
10041 gcc_unreachable ();
10043 /* assume builtin can do anything. */
10044 case RS6000_BTC_MISC:
10047 /* const function, function only depends on the inputs. */
10048 case RS6000_BTC_CONST:
10049 TREE_READONLY (t) = 1;
10050 TREE_NOTHROW (t) = 1;
10053 /* pure function, function can read global memory. */
10054 case RS6000_BTC_PURE:
10055 DECL_PURE_P (t) = 1;
10056 TREE_NOTHROW (t) = 1;
10059 /* Function is a math function. If rounding mode is on, then treat
10060 the function as not reading global memory, but it can have
10061 arbitrary side effects. If it is off, then assume the function is
10062 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10063 attribute in builtin-attribute.def that is used for the math
10065 case RS6000_BTC_FP_PURE:
10066 TREE_NOTHROW (t) = 1;
10067 if (flag_rounding_math)
10069 DECL_PURE_P (t) = 1;
10070 DECL_IS_NOVOPS (t) = 1;
10073 TREE_READONLY (t) = 1;
10079 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10081 static const struct builtin_description bdesc_3arg[] =
10083 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
10084 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
10085 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
10086 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
10087 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
10088 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
10089 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
10090 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
10091 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
10092 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10093 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10094 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10095 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10096 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10097 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10098 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10099 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10100 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10101 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10102 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10103 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10104 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10105 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10106 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10107 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10108 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10109 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10110 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10111 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10112 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10113 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10114 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10115 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10116 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10117 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10119 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10120 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10121 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10122 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10123 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10124 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10125 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10126 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10127 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10128 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10129 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10130 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10131 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10132 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10133 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10135 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10136 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10137 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10138 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10140 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10141 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10142 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10143 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10145 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10146 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10148 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10149 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10150 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10151 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10152 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10153 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10154 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10155 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10156 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10157 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10159 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10160 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10161 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10162 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10163 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10164 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10165 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10166 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10167 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10168 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10170 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10171 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10172 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10173 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10174 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10175 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10176 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10177 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10178 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10180 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10181 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10182 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10183 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10184 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10185 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10186 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10188 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10189 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10190 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10191 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10192 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10193 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10194 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10195 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10196 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10199 /* DST operations: void foo (void *, const int, const char). */
10201 static const struct builtin_description bdesc_dst[] =
10203 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10204 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10205 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10206 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10214 /* Simple binary operations: VECc = foo (VECa, VECb). */
10216 static struct builtin_description bdesc_2arg[] =
10218 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10219 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10220 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10221 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10222 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10223 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10224 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10225 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10226 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10227 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10228 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10229 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10230 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10231 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10232 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10233 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10234 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10235 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10236 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10237 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10238 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10239 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10240 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10241 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10242 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10243 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10244 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10245 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10246 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10247 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10248 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10249 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10250 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10251 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10252 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10253 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10254 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10255 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10256 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10257 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10258 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10259 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10260 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10261 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10262 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10263 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10264 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10265 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10266 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10267 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10268 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10269 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10270 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10271 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10272 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10273 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10274 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10275 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10276 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10277 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10278 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10279 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10280 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10281 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10282 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10283 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10284 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10285 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10286 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10287 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10288 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10289 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10290 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10291 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10292 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10293 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10294 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10295 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10296 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10297 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10298 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10299 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10300 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10301 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10302 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10303 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10304 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10305 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10306 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10307 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10308 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10309 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10310 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10311 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10312 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10313 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10314 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10315 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10316 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10317 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10318 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10319 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10320 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10321 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10322 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10323 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10324 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10325 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10326 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10327 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10328 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10329 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10330 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10331 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10332 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10333 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10334 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10336 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10337 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10338 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10339 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10340 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10341 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10342 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10343 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10344 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10345 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10346 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10347 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10349 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10350 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10351 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10352 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10353 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10354 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10355 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10356 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10357 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10358 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10359 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10360 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10362 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10363 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10364 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10365 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10366 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10367 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10369 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10370 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10371 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10372 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10373 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10374 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10375 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10376 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10377 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10378 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10379 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10380 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10382 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10383 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10395 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10396 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10422 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10423 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10438 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10439 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10456 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10457 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10472 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10473 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10476 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10477 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10478 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10480 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10491 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10492 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10497 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10498 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10499 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10500 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10501 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10502 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10503 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10504 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10505 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10506 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10507 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10508 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10509 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10510 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10512 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10513 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10515 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10516 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10517 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10518 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10519 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10520 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10521 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10522 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10523 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10524 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10526 /* Place holder, leave as first spe builtin. */
10527 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10528 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10529 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10530 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10531 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10532 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10533 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10534 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10535 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10536 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10537 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10538 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10539 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10540 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10541 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10542 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10543 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10544 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10545 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10546 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10547 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10548 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10549 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10550 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10551 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10552 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10553 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10554 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10555 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10556 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10557 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10558 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10559 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10560 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10561 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10562 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10563 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10564 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10565 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10566 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10567 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10568 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10569 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10570 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10571 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10572 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10573 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10574 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10575 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10576 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10577 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10578 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10579 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10580 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10581 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10582 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10583 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10584 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10585 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10586 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10587 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10588 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10589 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10590 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10591 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10592 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10593 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10594 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10595 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10596 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10597 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10598 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10599 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10600 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10601 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10602 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10603 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10604 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10605 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10606 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10607 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10608 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10609 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10610 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10611 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10612 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10613 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10614 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10615 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10616 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10617 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10618 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10619 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10620 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10621 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10622 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10623 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10624 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10625 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10626 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10627 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10628 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10629 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10630 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10631 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10632 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10633 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10634 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10635 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10637 /* SPE binary operations expecting a 5-bit unsigned literal. */
10638 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10640 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10641 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10642 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10643 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10644 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10645 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10646 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10647 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10648 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10649 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10650 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10651 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10652 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10653 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10654 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10655 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10656 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10657 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10658 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10659 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10660 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10661 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10662 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10663 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10664 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10665 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10667 /* Place-holder. Leave as last binary SPE builtin. */
10668 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10671 /* AltiVec predicates. */
10673 struct builtin_description_predicates
10675 const unsigned int mask;
10676 const enum insn_code icode;
10677 const char *const name;
10678 const enum rs6000_builtins code;
10681 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10683 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10684 ALTIVEC_BUILTIN_VCMPBFP_P },
10685 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10686 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10687 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10688 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10689 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10690 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10691 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10692 ALTIVEC_BUILTIN_VCMPEQUW_P },
10693 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10694 ALTIVEC_BUILTIN_VCMPGTSW_P },
10695 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10696 ALTIVEC_BUILTIN_VCMPGTUW_P },
10697 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10698 ALTIVEC_BUILTIN_VCMPEQUH_P },
10699 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10700 ALTIVEC_BUILTIN_VCMPGTSH_P },
10701 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10702 ALTIVEC_BUILTIN_VCMPGTUH_P },
10703 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10704 ALTIVEC_BUILTIN_VCMPEQUB_P },
10705 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10706 ALTIVEC_BUILTIN_VCMPGTSB_P },
10707 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10708 ALTIVEC_BUILTIN_VCMPGTUB_P },
10710 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10711 VSX_BUILTIN_XVCMPEQSP_P },
10712 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10713 VSX_BUILTIN_XVCMPGESP_P },
10714 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10715 VSX_BUILTIN_XVCMPGTSP_P },
10716 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10717 VSX_BUILTIN_XVCMPEQDP_P },
10718 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10719 VSX_BUILTIN_XVCMPGEDP_P },
10720 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10721 VSX_BUILTIN_XVCMPGTDP_P },
10723 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10724 ALTIVEC_BUILTIN_VCMPEQ_P },
10725 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10726 ALTIVEC_BUILTIN_VCMPGT_P },
10727 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10728 ALTIVEC_BUILTIN_VCMPGE_P }
10731 /* SPE predicates. */
10732 static struct builtin_description bdesc_spe_predicates[] =
10734 /* Place-holder. Leave as first. */
10735 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10736 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10737 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10738 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10739 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10740 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10741 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10742 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10743 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10744 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10745 /* Place-holder. Leave as last. */
10746 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10749 /* SPE evsel predicates. */
10750 static struct builtin_description bdesc_spe_evsel[] =
10752 /* Place-holder. Leave as first. */
10753 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10754 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10755 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10756 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10757 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10758 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10759 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10760 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10761 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10762 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10763 /* Place-holder. Leave as last. */
10764 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10767 /* PAIRED predicates. */
10768 static const struct builtin_description bdesc_paired_preds[] =
10770 /* Place-holder. Leave as first. */
10771 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10772 /* Place-holder. Leave as last. */
10773 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10776 /* ABS* operations. */
10778 static const struct builtin_description bdesc_abs[] =
10780 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10781 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10782 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10783 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10784 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10785 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10786 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10787 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10788 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10789 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10790 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10793 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10796 static struct builtin_description bdesc_1arg[] =
10798 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10799 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10800 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10801 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10802 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10803 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10804 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10805 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10806 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10807 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10808 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10809 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10810 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10811 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10812 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10813 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10814 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10815 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10817 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10818 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10819 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10820 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10821 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10822 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10823 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10825 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10826 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10827 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10828 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10829 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10830 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10831 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10833 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10834 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10835 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10836 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10837 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10838 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10840 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10841 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10842 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10843 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10844 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10845 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10847 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10848 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10849 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10850 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10852 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10853 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10854 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10855 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10856 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10857 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10858 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10859 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10860 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10862 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10863 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10864 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10865 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10866 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10867 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10868 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10869 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10870 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10872 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10873 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10874 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10875 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10876 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10899 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10900 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10901 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10903 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10904 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10905 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10906 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10908 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10909 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10910 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10911 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10912 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10913 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10914 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10915 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10916 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10917 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10918 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10919 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10920 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10921 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10922 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10923 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10924 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10925 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10926 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10927 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10928 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10929 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10930 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10931 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10932 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10933 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10934 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10935 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10936 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10937 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10939 /* Place-holder. Leave as last unary SPE builtin. */
10940 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10942 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10943 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10944 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10945 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10946 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10950 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10953 tree arg0 = CALL_EXPR_ARG (exp, 0);
10954 rtx op0 = expand_normal (arg0);
10955 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10956 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10958 if (icode == CODE_FOR_nothing)
10959 /* Builtin not supported on this processor. */
10962 /* If we got invalid arguments bail out before generating bad rtl. */
10963 if (arg0 == error_mark_node)
10966 if (icode == CODE_FOR_altivec_vspltisb
10967 || icode == CODE_FOR_altivec_vspltish
10968 || icode == CODE_FOR_altivec_vspltisw
10969 || icode == CODE_FOR_spe_evsplatfi
10970 || icode == CODE_FOR_spe_evsplati)
10972 /* Only allow 5-bit *signed* literals. */
10973 if (GET_CODE (op0) != CONST_INT
10974 || INTVAL (op0) > 15
10975 || INTVAL (op0) < -16)
10977 error ("argument 1 must be a 5-bit signed literal");
10983 || GET_MODE (target) != tmode
10984 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10985 target = gen_reg_rtx (tmode);
10987 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10988 op0 = copy_to_mode_reg (mode0, op0);
10990 pat = GEN_FCN (icode) (target, op0);
10999 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
11001 rtx pat, scratch1, scratch2;
11002 tree arg0 = CALL_EXPR_ARG (exp, 0);
11003 rtx op0 = expand_normal (arg0);
11004 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11005 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11007 /* If we have invalid arguments, bail out before generating bad rtl. */
11008 if (arg0 == error_mark_node)
11012 || GET_MODE (target) != tmode
11013 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11014 target = gen_reg_rtx (tmode);
11016 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11017 op0 = copy_to_mode_reg (mode0, op0);
11019 scratch1 = gen_reg_rtx (mode0);
11020 scratch2 = gen_reg_rtx (mode0);
11022 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
11031 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
11034 tree arg0 = CALL_EXPR_ARG (exp, 0);
11035 tree arg1 = CALL_EXPR_ARG (exp, 1);
11036 rtx op0 = expand_normal (arg0);
11037 rtx op1 = expand_normal (arg1);
11038 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11039 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11040 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11042 if (icode == CODE_FOR_nothing)
11043 /* Builtin not supported on this processor. */
11046 /* If we got invalid arguments bail out before generating bad rtl. */
11047 if (arg0 == error_mark_node || arg1 == error_mark_node)
11050 if (icode == CODE_FOR_altivec_vcfux
11051 || icode == CODE_FOR_altivec_vcfsx
11052 || icode == CODE_FOR_altivec_vctsxs
11053 || icode == CODE_FOR_altivec_vctuxs
11054 || icode == CODE_FOR_altivec_vspltb
11055 || icode == CODE_FOR_altivec_vsplth
11056 || icode == CODE_FOR_altivec_vspltw
11057 || icode == CODE_FOR_spe_evaddiw
11058 || icode == CODE_FOR_spe_evldd
11059 || icode == CODE_FOR_spe_evldh
11060 || icode == CODE_FOR_spe_evldw
11061 || icode == CODE_FOR_spe_evlhhesplat
11062 || icode == CODE_FOR_spe_evlhhossplat
11063 || icode == CODE_FOR_spe_evlhhousplat
11064 || icode == CODE_FOR_spe_evlwhe
11065 || icode == CODE_FOR_spe_evlwhos
11066 || icode == CODE_FOR_spe_evlwhou
11067 || icode == CODE_FOR_spe_evlwhsplat
11068 || icode == CODE_FOR_spe_evlwwsplat
11069 || icode == CODE_FOR_spe_evrlwi
11070 || icode == CODE_FOR_spe_evslwi
11071 || icode == CODE_FOR_spe_evsrwis
11072 || icode == CODE_FOR_spe_evsubifw
11073 || icode == CODE_FOR_spe_evsrwiu)
11075 /* Only allow 5-bit unsigned literals. */
11077 if (TREE_CODE (arg1) != INTEGER_CST
11078 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11080 error ("argument 2 must be a 5-bit unsigned literal");
11086 || GET_MODE (target) != tmode
11087 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11088 target = gen_reg_rtx (tmode);
11090 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11091 op0 = copy_to_mode_reg (mode0, op0);
11092 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11093 op1 = copy_to_mode_reg (mode1, op1);
11095 pat = GEN_FCN (icode) (target, op0, op1);
11104 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11107 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11108 tree arg0 = CALL_EXPR_ARG (exp, 1);
11109 tree arg1 = CALL_EXPR_ARG (exp, 2);
11110 rtx op0 = expand_normal (arg0);
11111 rtx op1 = expand_normal (arg1);
11112 enum machine_mode tmode = SImode;
11113 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11114 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11117 if (TREE_CODE (cr6_form) != INTEGER_CST)
11119 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11123 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11125 gcc_assert (mode0 == mode1);
11127 /* If we have invalid arguments, bail out before generating bad rtl. */
11128 if (arg0 == error_mark_node || arg1 == error_mark_node)
11132 || GET_MODE (target) != tmode
11133 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11134 target = gen_reg_rtx (tmode);
11136 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11137 op0 = copy_to_mode_reg (mode0, op0);
11138 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11139 op1 = copy_to_mode_reg (mode1, op1);
11141 scratch = gen_reg_rtx (mode0);
11143 pat = GEN_FCN (icode) (scratch, op0, op1);
11148 /* The vec_any* and vec_all* predicates use the same opcodes for two
11149 different operations, but the bits in CR6 will be different
11150 depending on what information we want. So we have to play tricks
11151 with CR6 to get the right bits out.
11153 If you think this is disgusting, look at the specs for the
11154 AltiVec predicates. */
11156 switch (cr6_form_int)
11159 emit_insn (gen_cr6_test_for_zero (target));
11162 emit_insn (gen_cr6_test_for_zero_reverse (target));
11165 emit_insn (gen_cr6_test_for_lt (target));
11168 emit_insn (gen_cr6_test_for_lt_reverse (target));
11171 error ("argument 1 of __builtin_altivec_predicate is out of range");
11179 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11182 tree arg0 = CALL_EXPR_ARG (exp, 0);
11183 tree arg1 = CALL_EXPR_ARG (exp, 1);
11184 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11185 enum machine_mode mode0 = Pmode;
11186 enum machine_mode mode1 = Pmode;
11187 rtx op0 = expand_normal (arg0);
11188 rtx op1 = expand_normal (arg1);
11190 if (icode == CODE_FOR_nothing)
11191 /* Builtin not supported on this processor. */
11194 /* If we got invalid arguments bail out before generating bad rtl. */
11195 if (arg0 == error_mark_node || arg1 == error_mark_node)
11199 || GET_MODE (target) != tmode
11200 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11201 target = gen_reg_rtx (tmode);
11203 op1 = copy_to_mode_reg (mode1, op1);
11205 if (op0 == const0_rtx)
11207 addr = gen_rtx_MEM (tmode, op1);
11211 op0 = copy_to_mode_reg (mode0, op0);
11212 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11215 pat = GEN_FCN (icode) (target, addr);
11225 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11228 tree arg0 = CALL_EXPR_ARG (exp, 0);
11229 tree arg1 = CALL_EXPR_ARG (exp, 1);
11230 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11231 enum machine_mode mode0 = Pmode;
11232 enum machine_mode mode1 = Pmode;
11233 rtx op0 = expand_normal (arg0);
11234 rtx op1 = expand_normal (arg1);
11236 if (icode == CODE_FOR_nothing)
11237 /* Builtin not supported on this processor. */
11240 /* If we got invalid arguments bail out before generating bad rtl. */
11241 if (arg0 == error_mark_node || arg1 == error_mark_node)
11245 || GET_MODE (target) != tmode
11246 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11247 target = gen_reg_rtx (tmode);
11249 op1 = copy_to_mode_reg (mode1, op1);
11251 if (op0 == const0_rtx)
11253 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11257 op0 = copy_to_mode_reg (mode0, op0);
11258 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11261 pat = GEN_FCN (icode) (target, addr);
11271 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11273 tree arg0 = CALL_EXPR_ARG (exp, 0);
11274 tree arg1 = CALL_EXPR_ARG (exp, 1);
11275 tree arg2 = CALL_EXPR_ARG (exp, 2);
11276 rtx op0 = expand_normal (arg0);
11277 rtx op1 = expand_normal (arg1);
11278 rtx op2 = expand_normal (arg2);
11280 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11281 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11282 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11284 /* Invalid arguments. Bail before doing anything stoopid! */
11285 if (arg0 == error_mark_node
11286 || arg1 == error_mark_node
11287 || arg2 == error_mark_node)
11290 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11291 op0 = copy_to_mode_reg (mode2, op0);
11292 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11293 op1 = copy_to_mode_reg (mode0, op1);
11294 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11295 op2 = copy_to_mode_reg (mode1, op2);
11297 pat = GEN_FCN (icode) (op1, op2, op0);
11304 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11306 tree arg0 = CALL_EXPR_ARG (exp, 0);
11307 tree arg1 = CALL_EXPR_ARG (exp, 1);
11308 tree arg2 = CALL_EXPR_ARG (exp, 2);
11309 rtx op0 = expand_normal (arg0);
11310 rtx op1 = expand_normal (arg1);
11311 rtx op2 = expand_normal (arg2);
11313 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11314 enum machine_mode mode1 = Pmode;
11315 enum machine_mode mode2 = Pmode;
11317 /* Invalid arguments. Bail before doing anything stoopid! */
11318 if (arg0 == error_mark_node
11319 || arg1 == error_mark_node
11320 || arg2 == error_mark_node)
11323 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11324 op0 = copy_to_mode_reg (tmode, op0);
11326 op2 = copy_to_mode_reg (mode2, op2);
11328 if (op1 == const0_rtx)
11330 addr = gen_rtx_MEM (tmode, op2);
11334 op1 = copy_to_mode_reg (mode1, op1);
11335 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11338 pat = GEN_FCN (icode) (addr, op0);
11345 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11347 tree arg0 = CALL_EXPR_ARG (exp, 0);
11348 tree arg1 = CALL_EXPR_ARG (exp, 1);
11349 tree arg2 = CALL_EXPR_ARG (exp, 2);
11350 rtx op0 = expand_normal (arg0);
11351 rtx op1 = expand_normal (arg1);
11352 rtx op2 = expand_normal (arg2);
11354 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11355 enum machine_mode smode = insn_data[icode].operand[1].mode;
11356 enum machine_mode mode1 = Pmode;
11357 enum machine_mode mode2 = Pmode;
11359 /* Invalid arguments. Bail before doing anything stoopid! */
11360 if (arg0 == error_mark_node
11361 || arg1 == error_mark_node
11362 || arg2 == error_mark_node)
11365 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11366 op0 = copy_to_mode_reg (smode, op0);
11368 op2 = copy_to_mode_reg (mode2, op2);
11370 if (op1 == const0_rtx)
11372 addr = gen_rtx_MEM (tmode, op2);
11376 op1 = copy_to_mode_reg (mode1, op1);
11377 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11380 pat = GEN_FCN (icode) (addr, op0);
11387 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11390 tree arg0 = CALL_EXPR_ARG (exp, 0);
11391 tree arg1 = CALL_EXPR_ARG (exp, 1);
11392 tree arg2 = CALL_EXPR_ARG (exp, 2);
11393 rtx op0 = expand_normal (arg0);
11394 rtx op1 = expand_normal (arg1);
11395 rtx op2 = expand_normal (arg2);
11396 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11397 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11398 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11399 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11401 if (icode == CODE_FOR_nothing)
11402 /* Builtin not supported on this processor. */
11405 /* If we got invalid arguments bail out before generating bad rtl. */
11406 if (arg0 == error_mark_node
11407 || arg1 == error_mark_node
11408 || arg2 == error_mark_node)
11411 /* Check and prepare argument depending on the instruction code.
11413 Note that a switch statement instead of the sequence of tests
11414 would be incorrect as many of the CODE_FOR values could be
11415 CODE_FOR_nothing and that would yield multiple alternatives
11416 with identical values. We'd never reach here at runtime in
11418 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11419 || icode == CODE_FOR_altivec_vsldoi_v4si
11420 || icode == CODE_FOR_altivec_vsldoi_v8hi
11421 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11423 /* Only allow 4-bit unsigned literals. */
11425 if (TREE_CODE (arg2) != INTEGER_CST
11426 || TREE_INT_CST_LOW (arg2) & ~0xf)
11428 error ("argument 3 must be a 4-bit unsigned literal");
11432 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11433 || icode == CODE_FOR_vsx_xxpermdi_v2di
11434 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11435 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11436 || icode == CODE_FOR_vsx_xxsldwi_v4si
11437 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11438 || icode == CODE_FOR_vsx_xxsldwi_v2di
11439 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11441 /* Only allow 2-bit unsigned literals. */
11443 if (TREE_CODE (arg2) != INTEGER_CST
11444 || TREE_INT_CST_LOW (arg2) & ~0x3)
11446 error ("argument 3 must be a 2-bit unsigned literal");
11450 else if (icode == CODE_FOR_vsx_set_v2df
11451 || icode == CODE_FOR_vsx_set_v2di)
11453 /* Only allow 1-bit unsigned literals. */
11455 if (TREE_CODE (arg2) != INTEGER_CST
11456 || TREE_INT_CST_LOW (arg2) & ~0x1)
11458 error ("argument 3 must be a 1-bit unsigned literal");
11464 || GET_MODE (target) != tmode
11465 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11466 target = gen_reg_rtx (tmode);
11468 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11469 op0 = copy_to_mode_reg (mode0, op0);
11470 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11471 op1 = copy_to_mode_reg (mode1, op1);
11472 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11473 op2 = copy_to_mode_reg (mode2, op2);
11475 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11476 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11478 pat = GEN_FCN (icode) (target, op0, op1, op2);
11486 /* Expand the lvx builtins. */
11488 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11490 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11491 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11493 enum machine_mode tmode, mode0;
11495 enum insn_code icode;
11499 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11500 icode = CODE_FOR_vector_altivec_load_v16qi;
11502 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11503 icode = CODE_FOR_vector_altivec_load_v8hi;
11505 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11506 icode = CODE_FOR_vector_altivec_load_v4si;
11508 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11509 icode = CODE_FOR_vector_altivec_load_v4sf;
11511 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11512 icode = CODE_FOR_vector_altivec_load_v2df;
11514 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11515 icode = CODE_FOR_vector_altivec_load_v2di;
11518 *expandedp = false;
11524 arg0 = CALL_EXPR_ARG (exp, 0);
11525 op0 = expand_normal (arg0);
11526 tmode = insn_data[icode].operand[0].mode;
11527 mode0 = insn_data[icode].operand[1].mode;
11530 || GET_MODE (target) != tmode
11531 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11532 target = gen_reg_rtx (tmode);
11534 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11535 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11537 pat = GEN_FCN (icode) (target, op0);
11544 /* Expand the stvx builtins. */
11546 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11549 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11550 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11552 enum machine_mode mode0, mode1;
11554 enum insn_code icode;
11558 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11559 icode = CODE_FOR_vector_altivec_store_v16qi;
11561 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11562 icode = CODE_FOR_vector_altivec_store_v8hi;
11564 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11565 icode = CODE_FOR_vector_altivec_store_v4si;
11567 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11568 icode = CODE_FOR_vector_altivec_store_v4sf;
11570 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11571 icode = CODE_FOR_vector_altivec_store_v2df;
11573 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11574 icode = CODE_FOR_vector_altivec_store_v2di;
11577 *expandedp = false;
11581 arg0 = CALL_EXPR_ARG (exp, 0);
11582 arg1 = CALL_EXPR_ARG (exp, 1);
11583 op0 = expand_normal (arg0);
11584 op1 = expand_normal (arg1);
11585 mode0 = insn_data[icode].operand[0].mode;
11586 mode1 = insn_data[icode].operand[1].mode;
11588 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11589 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11590 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11591 op1 = copy_to_mode_reg (mode1, op1);
11593 pat = GEN_FCN (icode) (op0, op1);
11601 /* Expand the dst builtins. */
11603 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11606 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11607 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11608 tree arg0, arg1, arg2;
11609 enum machine_mode mode0, mode1;
11610 rtx pat, op0, op1, op2;
11611 const struct builtin_description *d;
11614 *expandedp = false;
11616 /* Handle DST variants. */
11618 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11619 if (d->code == fcode)
11621 arg0 = CALL_EXPR_ARG (exp, 0);
11622 arg1 = CALL_EXPR_ARG (exp, 1);
11623 arg2 = CALL_EXPR_ARG (exp, 2);
11624 op0 = expand_normal (arg0);
11625 op1 = expand_normal (arg1);
11626 op2 = expand_normal (arg2);
11627 mode0 = insn_data[d->icode].operand[0].mode;
11628 mode1 = insn_data[d->icode].operand[1].mode;
11630 /* Invalid arguments, bail out before generating bad rtl. */
11631 if (arg0 == error_mark_node
11632 || arg1 == error_mark_node
11633 || arg2 == error_mark_node)
11638 if (TREE_CODE (arg2) != INTEGER_CST
11639 || TREE_INT_CST_LOW (arg2) & ~0x3)
11641 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11645 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11646 op0 = copy_to_mode_reg (Pmode, op0);
11647 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11648 op1 = copy_to_mode_reg (mode1, op1);
11650 pat = GEN_FCN (d->icode) (op0, op1, op2);
11660 /* Expand vec_init builtin. */
11662 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11664 enum machine_mode tmode = TYPE_MODE (type);
11665 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11666 int i, n_elt = GET_MODE_NUNITS (tmode);
11667 rtvec v = rtvec_alloc (n_elt);
11669 gcc_assert (VECTOR_MODE_P (tmode));
11670 gcc_assert (n_elt == call_expr_nargs (exp));
11672 for (i = 0; i < n_elt; ++i)
11674 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11675 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11678 if (!target || !register_operand (target, tmode))
11679 target = gen_reg_rtx (tmode);
11681 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11685 /* Return the integer constant in ARG. Constrain it to be in the range
11686 of the subparts of VEC_TYPE; issue an error if not. */
11689 get_element_number (tree vec_type, tree arg)
11691 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11693 if (!host_integerp (arg, 1)
11694 || (elt = tree_low_cst (arg, 1), elt > max))
11696 error ("selector must be an integer constant in the range 0..%wi", max);
11703 /* Expand vec_set builtin. */
11705 altivec_expand_vec_set_builtin (tree exp)
11707 enum machine_mode tmode, mode1;
11708 tree arg0, arg1, arg2;
11712 arg0 = CALL_EXPR_ARG (exp, 0);
11713 arg1 = CALL_EXPR_ARG (exp, 1);
11714 arg2 = CALL_EXPR_ARG (exp, 2);
11716 tmode = TYPE_MODE (TREE_TYPE (arg0));
11717 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11718 gcc_assert (VECTOR_MODE_P (tmode));
11720 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11721 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11722 elt = get_element_number (TREE_TYPE (arg0), arg2);
11724 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11725 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11727 op0 = force_reg (tmode, op0);
11728 op1 = force_reg (mode1, op1);
11730 rs6000_expand_vector_set (op0, op1, elt);
11735 /* Expand vec_ext builtin. */
11737 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11739 enum machine_mode tmode, mode0;
11744 arg0 = CALL_EXPR_ARG (exp, 0);
11745 arg1 = CALL_EXPR_ARG (exp, 1);
11747 op0 = expand_normal (arg0);
11748 elt = get_element_number (TREE_TYPE (arg0), arg1);
11750 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11751 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11752 gcc_assert (VECTOR_MODE_P (mode0));
11754 op0 = force_reg (mode0, op0);
11756 if (optimize || !target || !register_operand (target, tmode))
11757 target = gen_reg_rtx (tmode);
11759 rs6000_expand_vector_extract (target, op0, elt);
11764 /* Expand the builtin in EXP and store the result in TARGET. Store
11765 true in *EXPANDEDP if we found a builtin to expand. */
11767 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11769 const struct builtin_description *d;
11770 const struct builtin_description_predicates *dp;
11772 enum insn_code icode;
11773 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11776 enum machine_mode tmode, mode0;
11777 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11779 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11780 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11781 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11782 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11785 error ("unresolved overload for Altivec builtin %qF", fndecl);
11789 target = altivec_expand_ld_builtin (exp, target, expandedp);
11793 target = altivec_expand_st_builtin (exp, target, expandedp);
11797 target = altivec_expand_dst_builtin (exp, target, expandedp);
11805 case ALTIVEC_BUILTIN_STVX:
11806 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11807 case ALTIVEC_BUILTIN_STVEBX:
11808 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11809 case ALTIVEC_BUILTIN_STVEHX:
11810 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11811 case ALTIVEC_BUILTIN_STVEWX:
11812 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11813 case ALTIVEC_BUILTIN_STVXL:
11814 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11816 case ALTIVEC_BUILTIN_STVLX:
11817 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11818 case ALTIVEC_BUILTIN_STVLXL:
11819 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11820 case ALTIVEC_BUILTIN_STVRX:
11821 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11822 case ALTIVEC_BUILTIN_STVRXL:
11823 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11825 case VSX_BUILTIN_STXVD2X_V2DF:
11826 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11827 case VSX_BUILTIN_STXVD2X_V2DI:
11828 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11829 case VSX_BUILTIN_STXVW4X_V4SF:
11830 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11831 case VSX_BUILTIN_STXVW4X_V4SI:
11832 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11833 case VSX_BUILTIN_STXVW4X_V8HI:
11834 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11835 case VSX_BUILTIN_STXVW4X_V16QI:
11836 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11838 case ALTIVEC_BUILTIN_MFVSCR:
11839 icode = CODE_FOR_altivec_mfvscr;
11840 tmode = insn_data[icode].operand[0].mode;
11843 || GET_MODE (target) != tmode
11844 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11845 target = gen_reg_rtx (tmode);
11847 pat = GEN_FCN (icode) (target);
11853 case ALTIVEC_BUILTIN_MTVSCR:
11854 icode = CODE_FOR_altivec_mtvscr;
11855 arg0 = CALL_EXPR_ARG (exp, 0);
11856 op0 = expand_normal (arg0);
11857 mode0 = insn_data[icode].operand[0].mode;
11859 /* If we got invalid arguments bail out before generating bad rtl. */
11860 if (arg0 == error_mark_node)
11863 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11864 op0 = copy_to_mode_reg (mode0, op0);
11866 pat = GEN_FCN (icode) (op0);
11871 case ALTIVEC_BUILTIN_DSSALL:
11872 emit_insn (gen_altivec_dssall ());
11875 case ALTIVEC_BUILTIN_DSS:
11876 icode = CODE_FOR_altivec_dss;
11877 arg0 = CALL_EXPR_ARG (exp, 0);
11879 op0 = expand_normal (arg0);
11880 mode0 = insn_data[icode].operand[0].mode;
11882 /* If we got invalid arguments bail out before generating bad rtl. */
11883 if (arg0 == error_mark_node)
11886 if (TREE_CODE (arg0) != INTEGER_CST
11887 || TREE_INT_CST_LOW (arg0) & ~0x3)
11889 error ("argument to dss must be a 2-bit unsigned literal");
11893 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11894 op0 = copy_to_mode_reg (mode0, op0);
11896 emit_insn (gen_altivec_dss (op0));
11899 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11900 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11901 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11902 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11903 case VSX_BUILTIN_VEC_INIT_V2DF:
11904 case VSX_BUILTIN_VEC_INIT_V2DI:
11905 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11907 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11908 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11909 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11910 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11911 case VSX_BUILTIN_VEC_SET_V2DF:
11912 case VSX_BUILTIN_VEC_SET_V2DI:
11913 return altivec_expand_vec_set_builtin (exp);
11915 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11916 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11917 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11918 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11919 case VSX_BUILTIN_VEC_EXT_V2DF:
11920 case VSX_BUILTIN_VEC_EXT_V2DI:
11921 return altivec_expand_vec_ext_builtin (exp, target);
11925 /* Fall through. */
11928 /* Expand abs* operations. */
11930 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11931 if (d->code == fcode)
11932 return altivec_expand_abs_builtin (d->icode, exp, target);
11934 /* Expand the AltiVec predicates. */
11935 dp = bdesc_altivec_preds;
11936 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11937 if (dp->code == fcode)
11938 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11940 /* LV* are funky. We initialized them differently. */
11943 case ALTIVEC_BUILTIN_LVSL:
11944 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11945 exp, target, false);
11946 case ALTIVEC_BUILTIN_LVSR:
11947 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11948 exp, target, false);
11949 case ALTIVEC_BUILTIN_LVEBX:
11950 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11951 exp, target, false);
11952 case ALTIVEC_BUILTIN_LVEHX:
11953 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11954 exp, target, false);
11955 case ALTIVEC_BUILTIN_LVEWX:
11956 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11957 exp, target, false);
11958 case ALTIVEC_BUILTIN_LVXL:
11959 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11960 exp, target, false);
11961 case ALTIVEC_BUILTIN_LVX:
11962 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11963 exp, target, false);
11964 case ALTIVEC_BUILTIN_LVLX:
11965 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11966 exp, target, true);
11967 case ALTIVEC_BUILTIN_LVLXL:
11968 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11969 exp, target, true);
11970 case ALTIVEC_BUILTIN_LVRX:
11971 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11972 exp, target, true);
11973 case ALTIVEC_BUILTIN_LVRXL:
11974 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11975 exp, target, true);
11976 case VSX_BUILTIN_LXVD2X_V2DF:
11977 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11978 exp, target, false);
11979 case VSX_BUILTIN_LXVD2X_V2DI:
11980 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11981 exp, target, false);
11982 case VSX_BUILTIN_LXVW4X_V4SF:
11983 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11984 exp, target, false);
11985 case VSX_BUILTIN_LXVW4X_V4SI:
11986 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11987 exp, target, false);
11988 case VSX_BUILTIN_LXVW4X_V8HI:
11989 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11990 exp, target, false);
11991 case VSX_BUILTIN_LXVW4X_V16QI:
11992 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11993 exp, target, false);
11997 /* Fall through. */
12000 *expandedp = false;
12004 /* Expand the builtin in EXP and store the result in TARGET. Store
12005 true in *EXPANDEDP if we found a builtin to expand. */
12007 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
12009 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12010 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12011 const struct builtin_description *d;
12018 case PAIRED_BUILTIN_STX:
12019 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
12020 case PAIRED_BUILTIN_LX:
12021 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
12024 /* Fall through. */
12027 /* Expand the paired predicates. */
12028 d = bdesc_paired_preds;
12029 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
12030 if (d->code == fcode)
12031 return paired_expand_predicate_builtin (d->icode, exp, target);
12033 *expandedp = false;
12037 /* Binops that need to be initialized manually, but can be expanded
12038 automagically by rs6000_expand_binop_builtin. */
12039 static struct builtin_description bdesc_2arg_spe[] =
12041 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
12042 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
12043 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
12044 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
12045 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
12046 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
12047 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
12048 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
12049 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
12050 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
12051 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
12052 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
12053 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
12054 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
12055 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
12056 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
12057 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
12058 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
12059 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
12060 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
12061 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
12062 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
12065 /* Expand the builtin in EXP and store the result in TARGET. Store
12066 true in *EXPANDEDP if we found a builtin to expand.
12068 This expands the SPE builtins that are not simple unary and binary
12071 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
12073 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12075 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12076 enum insn_code icode;
12077 enum machine_mode tmode, mode0;
12079 struct builtin_description *d;
12084 /* Syntax check for a 5-bit unsigned immediate. */
12087 case SPE_BUILTIN_EVSTDD:
12088 case SPE_BUILTIN_EVSTDH:
12089 case SPE_BUILTIN_EVSTDW:
12090 case SPE_BUILTIN_EVSTWHE:
12091 case SPE_BUILTIN_EVSTWHO:
12092 case SPE_BUILTIN_EVSTWWE:
12093 case SPE_BUILTIN_EVSTWWO:
12094 arg1 = CALL_EXPR_ARG (exp, 2);
12095 if (TREE_CODE (arg1) != INTEGER_CST
12096 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12098 error ("argument 2 must be a 5-bit unsigned literal");
12106 /* The evsplat*i instructions are not quite generic. */
12109 case SPE_BUILTIN_EVSPLATFI:
12110 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12112 case SPE_BUILTIN_EVSPLATI:
12113 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12119 d = (struct builtin_description *) bdesc_2arg_spe;
12120 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12121 if (d->code == fcode)
12122 return rs6000_expand_binop_builtin (d->icode, exp, target);
12124 d = (struct builtin_description *) bdesc_spe_predicates;
12125 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12126 if (d->code == fcode)
12127 return spe_expand_predicate_builtin (d->icode, exp, target);
12129 d = (struct builtin_description *) bdesc_spe_evsel;
12130 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12131 if (d->code == fcode)
12132 return spe_expand_evsel_builtin (d->icode, exp, target);
12136 case SPE_BUILTIN_EVSTDDX:
12137 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12138 case SPE_BUILTIN_EVSTDHX:
12139 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12140 case SPE_BUILTIN_EVSTDWX:
12141 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12142 case SPE_BUILTIN_EVSTWHEX:
12143 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12144 case SPE_BUILTIN_EVSTWHOX:
12145 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12146 case SPE_BUILTIN_EVSTWWEX:
12147 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12148 case SPE_BUILTIN_EVSTWWOX:
12149 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12150 case SPE_BUILTIN_EVSTDD:
12151 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12152 case SPE_BUILTIN_EVSTDH:
12153 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12154 case SPE_BUILTIN_EVSTDW:
12155 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12156 case SPE_BUILTIN_EVSTWHE:
12157 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12158 case SPE_BUILTIN_EVSTWHO:
12159 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12160 case SPE_BUILTIN_EVSTWWE:
12161 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12162 case SPE_BUILTIN_EVSTWWO:
12163 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12164 case SPE_BUILTIN_MFSPEFSCR:
12165 icode = CODE_FOR_spe_mfspefscr;
12166 tmode = insn_data[icode].operand[0].mode;
12169 || GET_MODE (target) != tmode
12170 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12171 target = gen_reg_rtx (tmode);
12173 pat = GEN_FCN (icode) (target);
12178 case SPE_BUILTIN_MTSPEFSCR:
12179 icode = CODE_FOR_spe_mtspefscr;
12180 arg0 = CALL_EXPR_ARG (exp, 0);
12181 op0 = expand_normal (arg0);
12182 mode0 = insn_data[icode].operand[0].mode;
12184 if (arg0 == error_mark_node)
12187 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12188 op0 = copy_to_mode_reg (mode0, op0);
12190 pat = GEN_FCN (icode) (op0);
12198 *expandedp = false;
12203 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12205 rtx pat, scratch, tmp;
12206 tree form = CALL_EXPR_ARG (exp, 0);
12207 tree arg0 = CALL_EXPR_ARG (exp, 1);
12208 tree arg1 = CALL_EXPR_ARG (exp, 2);
12209 rtx op0 = expand_normal (arg0);
12210 rtx op1 = expand_normal (arg1);
12211 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12212 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12214 enum rtx_code code;
12216 if (TREE_CODE (form) != INTEGER_CST)
12218 error ("argument 1 of __builtin_paired_predicate must be a constant");
12222 form_int = TREE_INT_CST_LOW (form);
12224 gcc_assert (mode0 == mode1);
12226 if (arg0 == error_mark_node || arg1 == error_mark_node)
12230 || GET_MODE (target) != SImode
12231 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12232 target = gen_reg_rtx (SImode);
12233 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12234 op0 = copy_to_mode_reg (mode0, op0);
12235 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12236 op1 = copy_to_mode_reg (mode1, op1);
12238 scratch = gen_reg_rtx (CCFPmode);
12240 pat = GEN_FCN (icode) (scratch, op0, op1);
12262 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12265 error ("argument 1 of __builtin_paired_predicate is out of range");
12269 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12270 emit_move_insn (target, tmp);
12275 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12277 rtx pat, scratch, tmp;
12278 tree form = CALL_EXPR_ARG (exp, 0);
12279 tree arg0 = CALL_EXPR_ARG (exp, 1);
12280 tree arg1 = CALL_EXPR_ARG (exp, 2);
12281 rtx op0 = expand_normal (arg0);
12282 rtx op1 = expand_normal (arg1);
12283 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12284 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12286 enum rtx_code code;
12288 if (TREE_CODE (form) != INTEGER_CST)
12290 error ("argument 1 of __builtin_spe_predicate must be a constant");
12294 form_int = TREE_INT_CST_LOW (form);
12296 gcc_assert (mode0 == mode1);
12298 if (arg0 == error_mark_node || arg1 == error_mark_node)
12302 || GET_MODE (target) != SImode
12303 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12304 target = gen_reg_rtx (SImode);
12306 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12307 op0 = copy_to_mode_reg (mode0, op0);
12308 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12309 op1 = copy_to_mode_reg (mode1, op1);
12311 scratch = gen_reg_rtx (CCmode);
12313 pat = GEN_FCN (icode) (scratch, op0, op1);
12318 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12319 _lower_. We use one compare, but look in different bits of the
12320 CR for each variant.
12322 There are 2 elements in each SPE simd type (upper/lower). The CR
12323 bits are set as follows:
12325 BIT0 | BIT 1 | BIT 2 | BIT 3
12326 U | L | (U | L) | (U & L)
12328 So, for an "all" relationship, BIT 3 would be set.
12329 For an "any" relationship, BIT 2 would be set. Etc.
12331 Following traditional nomenclature, these bits map to:
12333 BIT0 | BIT 1 | BIT 2 | BIT 3
12336 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12341 /* All variant. OV bit. */
12343 /* We need to get to the OV bit, which is the ORDERED bit. We
12344 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12345 that's ugly and will make validate_condition_mode die.
12346 So let's just use another pattern. */
12347 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12349 /* Any variant. EQ bit. */
12353 /* Upper variant. LT bit. */
12357 /* Lower variant. GT bit. */
12362 error ("argument 1 of __builtin_spe_predicate is out of range");
12366 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12367 emit_move_insn (target, tmp);
12372 /* The evsel builtins look like this:
12374 e = __builtin_spe_evsel_OP (a, b, c, d);
12376 and work like this:
12378 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12379 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12383 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12386 tree arg0 = CALL_EXPR_ARG (exp, 0);
12387 tree arg1 = CALL_EXPR_ARG (exp, 1);
12388 tree arg2 = CALL_EXPR_ARG (exp, 2);
12389 tree arg3 = CALL_EXPR_ARG (exp, 3);
12390 rtx op0 = expand_normal (arg0);
12391 rtx op1 = expand_normal (arg1);
12392 rtx op2 = expand_normal (arg2);
12393 rtx op3 = expand_normal (arg3);
12394 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12395 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12397 gcc_assert (mode0 == mode1);
12399 if (arg0 == error_mark_node || arg1 == error_mark_node
12400 || arg2 == error_mark_node || arg3 == error_mark_node)
12404 || GET_MODE (target) != mode0
12405 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12406 target = gen_reg_rtx (mode0);
12408 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12409 op0 = copy_to_mode_reg (mode0, op0);
12410 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12411 op1 = copy_to_mode_reg (mode0, op1);
12412 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12413 op2 = copy_to_mode_reg (mode0, op2);
12414 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12415 op3 = copy_to_mode_reg (mode0, op3);
12417 /* Generate the compare. */
12418 scratch = gen_reg_rtx (CCmode);
12419 pat = GEN_FCN (icode) (scratch, op0, op1);
12424 if (mode0 == V2SImode)
12425 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12427 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12432 /* Expand an expression EXP that calls a built-in function,
12433 with result going to TARGET if that's convenient
12434 (and in mode MODE if that's convenient).
12435 SUBTARGET may be used as the target for computing one of EXP's operands.
12436 IGNORE is nonzero if the value is to be ignored. */
12439 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12440 enum machine_mode mode ATTRIBUTE_UNUSED,
12441 int ignore ATTRIBUTE_UNUSED)
12443 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12444 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12445 const struct builtin_description *d;
12452 case RS6000_BUILTIN_RECIP:
12453 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12455 case RS6000_BUILTIN_RECIPF:
12456 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12458 case RS6000_BUILTIN_RSQRTF:
12459 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12461 case RS6000_BUILTIN_RSQRT:
12462 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12464 case RS6000_BUILTIN_BSWAP_HI:
12465 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12467 case POWER7_BUILTIN_BPERMD:
12468 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12469 ? CODE_FOR_bpermd_di
12470 : CODE_FOR_bpermd_si), exp, target);
12472 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12473 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12475 int icode = (int) CODE_FOR_altivec_lvsr;
12476 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12477 enum machine_mode mode = insn_data[icode].operand[1].mode;
12481 gcc_assert (TARGET_ALTIVEC);
12483 arg = CALL_EXPR_ARG (exp, 0);
12484 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12485 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12486 addr = memory_address (mode, op);
12487 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12491 /* For the load case need to negate the address. */
12492 op = gen_reg_rtx (GET_MODE (addr));
12493 emit_insn (gen_rtx_SET (VOIDmode, op,
12494 gen_rtx_NEG (GET_MODE (addr), addr)));
12496 op = gen_rtx_MEM (mode, op);
12499 || GET_MODE (target) != tmode
12500 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12501 target = gen_reg_rtx (tmode);
12503 /*pat = gen_altivec_lvsr (target, op);*/
12504 pat = GEN_FCN (icode) (target, op);
12512 case ALTIVEC_BUILTIN_VCFUX:
12513 case ALTIVEC_BUILTIN_VCFSX:
12514 case ALTIVEC_BUILTIN_VCTUXS:
12515 case ALTIVEC_BUILTIN_VCTSXS:
12516 /* FIXME: There's got to be a nicer way to handle this case than
12517 constructing a new CALL_EXPR. */
12518 if (call_expr_nargs (exp) == 1)
12520 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12521 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12529 if (TARGET_ALTIVEC)
12531 ret = altivec_expand_builtin (exp, target, &success);
12538 ret = spe_expand_builtin (exp, target, &success);
12543 if (TARGET_PAIRED_FLOAT)
12545 ret = paired_expand_builtin (exp, target, &success);
12551 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12553 /* Handle simple unary operations. */
12554 d = (struct builtin_description *) bdesc_1arg;
12555 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12556 if (d->code == fcode)
12557 return rs6000_expand_unop_builtin (d->icode, exp, target);
12559 /* Handle simple binary operations. */
12560 d = (struct builtin_description *) bdesc_2arg;
12561 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12562 if (d->code == fcode)
12563 return rs6000_expand_binop_builtin (d->icode, exp, target);
12565 /* Handle simple ternary operations. */
12567 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12568 if (d->code == fcode)
12569 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12571 gcc_unreachable ();
12575 rs6000_init_builtins (void)
12580 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12581 V2SF_type_node = build_vector_type (float_type_node, 2);
12582 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12583 V2DF_type_node = build_vector_type (double_type_node, 2);
12584 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12585 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12586 V4SF_type_node = build_vector_type (float_type_node, 4);
12587 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12588 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12590 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12591 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12592 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12593 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12595 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12596 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12597 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12598 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12600 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12601 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12602 'vector unsigned short'. */
12604 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12605 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12606 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12607 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12608 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12610 long_integer_type_internal_node = long_integer_type_node;
12611 long_unsigned_type_internal_node = long_unsigned_type_node;
12612 long_long_integer_type_internal_node = long_long_integer_type_node;
12613 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12614 intQI_type_internal_node = intQI_type_node;
12615 uintQI_type_internal_node = unsigned_intQI_type_node;
12616 intHI_type_internal_node = intHI_type_node;
12617 uintHI_type_internal_node = unsigned_intHI_type_node;
12618 intSI_type_internal_node = intSI_type_node;
12619 uintSI_type_internal_node = unsigned_intSI_type_node;
12620 intDI_type_internal_node = intDI_type_node;
12621 uintDI_type_internal_node = unsigned_intDI_type_node;
12622 float_type_internal_node = float_type_node;
12623 double_type_internal_node = double_type_node;
12624 void_type_internal_node = void_type_node;
12626 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12628 builtin_mode_to_type[QImode][0] = integer_type_node;
12629 builtin_mode_to_type[HImode][0] = integer_type_node;
12630 builtin_mode_to_type[SImode][0] = intSI_type_node;
12631 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12632 builtin_mode_to_type[DImode][0] = intDI_type_node;
12633 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12634 builtin_mode_to_type[SFmode][0] = float_type_node;
12635 builtin_mode_to_type[DFmode][0] = double_type_node;
12636 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12637 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12638 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12639 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12640 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12641 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12642 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12643 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12644 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12645 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12646 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12647 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12648 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12650 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12651 get_identifier ("__bool char"),
12652 bool_char_type_node);
12653 TYPE_NAME (bool_char_type_node) = tdecl;
12654 (*lang_hooks.decls.pushdecl) (tdecl);
12655 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12656 get_identifier ("__bool short"),
12657 bool_short_type_node);
12658 TYPE_NAME (bool_short_type_node) = tdecl;
12659 (*lang_hooks.decls.pushdecl) (tdecl);
12660 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12661 get_identifier ("__bool int"),
12662 bool_int_type_node);
12663 TYPE_NAME (bool_int_type_node) = tdecl;
12664 (*lang_hooks.decls.pushdecl) (tdecl);
12665 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12667 TYPE_NAME (pixel_type_node) = tdecl;
12668 (*lang_hooks.decls.pushdecl) (tdecl);
12670 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12671 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12672 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12673 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12674 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12676 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12677 get_identifier ("__vector unsigned char"),
12678 unsigned_V16QI_type_node);
12679 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12680 (*lang_hooks.decls.pushdecl) (tdecl);
12681 tdecl = build_decl (BUILTINS_LOCATION,
12682 TYPE_DECL, get_identifier ("__vector signed char"),
12684 TYPE_NAME (V16QI_type_node) = tdecl;
12685 (*lang_hooks.decls.pushdecl) (tdecl);
12686 tdecl = build_decl (BUILTINS_LOCATION,
12687 TYPE_DECL, get_identifier ("__vector __bool char"),
12688 bool_V16QI_type_node);
12689 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12690 (*lang_hooks.decls.pushdecl) (tdecl);
12692 tdecl = build_decl (BUILTINS_LOCATION,
12693 TYPE_DECL, get_identifier ("__vector unsigned short"),
12694 unsigned_V8HI_type_node);
12695 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12696 (*lang_hooks.decls.pushdecl) (tdecl);
12697 tdecl = build_decl (BUILTINS_LOCATION,
12698 TYPE_DECL, get_identifier ("__vector signed short"),
12700 TYPE_NAME (V8HI_type_node) = tdecl;
12701 (*lang_hooks.decls.pushdecl) (tdecl);
12702 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12703 get_identifier ("__vector __bool short"),
12704 bool_V8HI_type_node);
12705 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12706 (*lang_hooks.decls.pushdecl) (tdecl);
12708 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12709 get_identifier ("__vector unsigned int"),
12710 unsigned_V4SI_type_node);
12711 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12712 (*lang_hooks.decls.pushdecl) (tdecl);
12713 tdecl = build_decl (BUILTINS_LOCATION,
12714 TYPE_DECL, get_identifier ("__vector signed int"),
12716 TYPE_NAME (V4SI_type_node) = tdecl;
12717 (*lang_hooks.decls.pushdecl) (tdecl);
12718 tdecl = build_decl (BUILTINS_LOCATION,
12719 TYPE_DECL, get_identifier ("__vector __bool int"),
12720 bool_V4SI_type_node);
12721 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12722 (*lang_hooks.decls.pushdecl) (tdecl);
12724 tdecl = build_decl (BUILTINS_LOCATION,
12725 TYPE_DECL, get_identifier ("__vector float"),
12727 TYPE_NAME (V4SF_type_node) = tdecl;
12728 (*lang_hooks.decls.pushdecl) (tdecl);
12729 tdecl = build_decl (BUILTINS_LOCATION,
12730 TYPE_DECL, get_identifier ("__vector __pixel"),
12731 pixel_V8HI_type_node);
12732 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12733 (*lang_hooks.decls.pushdecl) (tdecl);
12737 tdecl = build_decl (BUILTINS_LOCATION,
12738 TYPE_DECL, get_identifier ("__vector double"),
12740 TYPE_NAME (V2DF_type_node) = tdecl;
12741 (*lang_hooks.decls.pushdecl) (tdecl);
12743 tdecl = build_decl (BUILTINS_LOCATION,
12744 TYPE_DECL, get_identifier ("__vector long"),
12746 TYPE_NAME (V2DI_type_node) = tdecl;
12747 (*lang_hooks.decls.pushdecl) (tdecl);
12749 tdecl = build_decl (BUILTINS_LOCATION,
12750 TYPE_DECL, get_identifier ("__vector unsigned long"),
12751 unsigned_V2DI_type_node);
12752 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12753 (*lang_hooks.decls.pushdecl) (tdecl);
12755 tdecl = build_decl (BUILTINS_LOCATION,
12756 TYPE_DECL, get_identifier ("__vector __bool long"),
12757 bool_V2DI_type_node);
12758 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12759 (*lang_hooks.decls.pushdecl) (tdecl);
12762 if (TARGET_PAIRED_FLOAT)
12763 paired_init_builtins ();
12765 spe_init_builtins ();
12766 if (TARGET_ALTIVEC)
12767 altivec_init_builtins ();
12768 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12769 rs6000_common_init_builtins ();
12772 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12773 RS6000_BUILTIN_RECIP,
12774 "__builtin_recipdiv");
12775 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12776 RS6000_BUILTIN_RECIP);
12780 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12781 RS6000_BUILTIN_RECIPF,
12782 "__builtin_recipdivf");
12783 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12784 RS6000_BUILTIN_RECIPF);
12786 if (TARGET_FRSQRTE)
12788 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12789 RS6000_BUILTIN_RSQRT,
12790 "__builtin_rsqrt");
12791 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12792 RS6000_BUILTIN_RSQRT);
12794 if (TARGET_FRSQRTES)
12796 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12797 RS6000_BUILTIN_RSQRTF,
12798 "__builtin_rsqrtf");
12799 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12800 RS6000_BUILTIN_RSQRTF);
12802 if (TARGET_POPCNTD)
12804 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12805 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12806 POWER7_BUILTIN_BPERMD,
12807 "__builtin_bpermd");
12808 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12809 POWER7_BUILTIN_BPERMD);
12811 if (TARGET_POWERPC)
12813 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12814 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12815 unsigned_intHI_type_node,
12817 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12818 RS6000_BUILTIN_BSWAP_HI);
12822 /* AIX libm provides clog as __clog. */
12823 if (built_in_decls [BUILT_IN_CLOG])
12824 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12827 #ifdef SUBTARGET_INIT_BUILTINS
12828 SUBTARGET_INIT_BUILTINS;
12832 /* Returns the rs6000 builtin decl for CODE. */
12835 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12837 if (code >= RS6000_BUILTIN_COUNT)
12838 return error_mark_node;
12840 return rs6000_builtin_decls[code];
12843 /* Search through a set of builtins and enable the mask bits.
12844 DESC is an array of builtins.
12845 SIZE is the total number of builtins.
12846 START is the builtin enum at which to start.
12847 END is the builtin enum at which to end. */
12849 enable_mask_for_builtins (struct builtin_description *desc, int size,
12850 enum rs6000_builtins start,
12851 enum rs6000_builtins end)
12855 for (i = 0; i < size; ++i)
12856 if (desc[i].code == start)
12862 for (; i < size; ++i)
12864 /* Flip all the bits on. */
12865 desc[i].mask = target_flags;
12866 if (desc[i].code == end)
12872 spe_init_builtins (void)
12874 tree endlink = void_list_node;
12875 tree puint_type_node = build_pointer_type (unsigned_type_node);
12876 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12877 struct builtin_description *d;
12880 tree v2si_ftype_4_v2si
12881 = build_function_type
12882 (opaque_V2SI_type_node,
12883 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12884 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12885 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12886 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12889 tree v2sf_ftype_4_v2sf
12890 = build_function_type
12891 (opaque_V2SF_type_node,
12892 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12893 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12894 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12895 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12898 tree int_ftype_int_v2si_v2si
12899 = build_function_type
12900 (integer_type_node,
12901 tree_cons (NULL_TREE, integer_type_node,
12902 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12903 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12906 tree int_ftype_int_v2sf_v2sf
12907 = build_function_type
12908 (integer_type_node,
12909 tree_cons (NULL_TREE, integer_type_node,
12910 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12911 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12914 tree void_ftype_v2si_puint_int
12915 = build_function_type (void_type_node,
12916 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12917 tree_cons (NULL_TREE, puint_type_node,
12918 tree_cons (NULL_TREE,
12922 tree void_ftype_v2si_puint_char
12923 = build_function_type (void_type_node,
12924 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12925 tree_cons (NULL_TREE, puint_type_node,
12926 tree_cons (NULL_TREE,
12930 tree void_ftype_v2si_pv2si_int
12931 = build_function_type (void_type_node,
12932 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12933 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12934 tree_cons (NULL_TREE,
12938 tree void_ftype_v2si_pv2si_char
12939 = build_function_type (void_type_node,
12940 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12941 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12942 tree_cons (NULL_TREE,
12946 tree void_ftype_int
12947 = build_function_type (void_type_node,
12948 tree_cons (NULL_TREE, integer_type_node, endlink));
12950 tree int_ftype_void
12951 = build_function_type (integer_type_node, endlink);
12953 tree v2si_ftype_pv2si_int
12954 = build_function_type (opaque_V2SI_type_node,
12955 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12956 tree_cons (NULL_TREE, integer_type_node,
12959 tree v2si_ftype_puint_int
12960 = build_function_type (opaque_V2SI_type_node,
12961 tree_cons (NULL_TREE, puint_type_node,
12962 tree_cons (NULL_TREE, integer_type_node,
12965 tree v2si_ftype_pushort_int
12966 = build_function_type (opaque_V2SI_type_node,
12967 tree_cons (NULL_TREE, pushort_type_node,
12968 tree_cons (NULL_TREE, integer_type_node,
12971 tree v2si_ftype_signed_char
12972 = build_function_type (opaque_V2SI_type_node,
12973 tree_cons (NULL_TREE, signed_char_type_node,
12976 /* The initialization of the simple binary and unary builtins is
12977 done in rs6000_common_init_builtins, but we have to enable the
12978 mask bits here manually because we have run out of `target_flags'
12979 bits. We really need to redesign this mask business. */
12981 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12982 ARRAY_SIZE (bdesc_2arg),
12983 SPE_BUILTIN_EVADDW,
12984 SPE_BUILTIN_EVXOR);
12985 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12986 ARRAY_SIZE (bdesc_1arg),
12988 SPE_BUILTIN_EVSUBFUSIAAW);
12989 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12990 ARRAY_SIZE (bdesc_spe_predicates),
12991 SPE_BUILTIN_EVCMPEQ,
12992 SPE_BUILTIN_EVFSTSTLT);
12993 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12994 ARRAY_SIZE (bdesc_spe_evsel),
12995 SPE_BUILTIN_EVSEL_CMPGTS,
12996 SPE_BUILTIN_EVSEL_FSTSTEQ);
12998 (*lang_hooks.decls.pushdecl)
12999 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
13000 get_identifier ("__ev64_opaque__"),
13001 opaque_V2SI_type_node));
13003 /* Initialize irregular SPE builtins. */
13005 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
13006 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
13007 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
13008 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
13009 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
13010 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
13011 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
13012 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
13013 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
13014 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
13015 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
13016 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
13017 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
13018 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
13019 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
13020 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
13021 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
13022 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
13025 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
13026 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
13027 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
13028 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
13029 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
13030 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
13031 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
13032 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
13033 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
13034 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
13035 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
13036 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
13037 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
13038 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
13039 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
13040 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
13041 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
13042 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
13043 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
13044 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
13045 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
13046 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
13049 d = (struct builtin_description *) bdesc_spe_predicates;
13050 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
13054 switch (insn_data[d->icode].operand[1].mode)
13057 type = int_ftype_int_v2si_v2si;
13060 type = int_ftype_int_v2sf_v2sf;
13063 gcc_unreachable ();
13066 def_builtin (d->mask, d->name, type, d->code);
13069 /* Evsel predicates. */
13070 d = (struct builtin_description *) bdesc_spe_evsel;
13071 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
13075 switch (insn_data[d->icode].operand[1].mode)
13078 type = v2si_ftype_4_v2si;
13081 type = v2sf_ftype_4_v2sf;
13084 gcc_unreachable ();
13087 def_builtin (d->mask, d->name, type, d->code);
13092 paired_init_builtins (void)
13094 const struct builtin_description *d;
13096 tree endlink = void_list_node;
13098 tree int_ftype_int_v2sf_v2sf
13099 = build_function_type
13100 (integer_type_node,
13101 tree_cons (NULL_TREE, integer_type_node,
13102 tree_cons (NULL_TREE, V2SF_type_node,
13103 tree_cons (NULL_TREE, V2SF_type_node,
13105 tree pcfloat_type_node =
13106 build_pointer_type (build_qualified_type
13107 (float_type_node, TYPE_QUAL_CONST));
13109 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13110 long_integer_type_node,
13113 tree void_ftype_v2sf_long_pcfloat =
13114 build_function_type_list (void_type_node,
13116 long_integer_type_node,
13121 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13122 PAIRED_BUILTIN_LX);
13125 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13126 PAIRED_BUILTIN_STX);
13129 d = bdesc_paired_preds;
13130 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13134 switch (insn_data[d->icode].operand[1].mode)
13137 type = int_ftype_int_v2sf_v2sf;
13140 gcc_unreachable ();
13143 def_builtin (d->mask, d->name, type, d->code);
13148 altivec_init_builtins (void)
13150 const struct builtin_description *d;
13151 const struct builtin_description_predicates *dp;
13155 tree pvoid_type_node = build_pointer_type (void_type_node);
13157 tree pcvoid_type_node
13158 = build_pointer_type (build_qualified_type (void_type_node,
13161 tree int_ftype_opaque
13162 = build_function_type_list (integer_type_node,
13163 opaque_V4SI_type_node, NULL_TREE);
13164 tree opaque_ftype_opaque
13165 = build_function_type (integer_type_node,
13167 tree opaque_ftype_opaque_int
13168 = build_function_type_list (opaque_V4SI_type_node,
13169 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13170 tree opaque_ftype_opaque_opaque_int
13171 = build_function_type_list (opaque_V4SI_type_node,
13172 opaque_V4SI_type_node, opaque_V4SI_type_node,
13173 integer_type_node, NULL_TREE);
13174 tree int_ftype_int_opaque_opaque
13175 = build_function_type_list (integer_type_node,
13176 integer_type_node, opaque_V4SI_type_node,
13177 opaque_V4SI_type_node, NULL_TREE);
13178 tree int_ftype_int_v4si_v4si
13179 = build_function_type_list (integer_type_node,
13180 integer_type_node, V4SI_type_node,
13181 V4SI_type_node, NULL_TREE);
13182 tree void_ftype_v4si
13183 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13184 tree v8hi_ftype_void
13185 = build_function_type (V8HI_type_node, void_list_node);
13186 tree void_ftype_void
13187 = build_function_type (void_type_node, void_list_node);
13188 tree void_ftype_int
13189 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13191 tree opaque_ftype_long_pcvoid
13192 = build_function_type_list (opaque_V4SI_type_node,
13193 long_integer_type_node, pcvoid_type_node,
13195 tree v16qi_ftype_long_pcvoid
13196 = build_function_type_list (V16QI_type_node,
13197 long_integer_type_node, pcvoid_type_node,
13199 tree v8hi_ftype_long_pcvoid
13200 = build_function_type_list (V8HI_type_node,
13201 long_integer_type_node, pcvoid_type_node,
13203 tree v4si_ftype_long_pcvoid
13204 = build_function_type_list (V4SI_type_node,
13205 long_integer_type_node, pcvoid_type_node,
13207 tree v4sf_ftype_long_pcvoid
13208 = build_function_type_list (V4SF_type_node,
13209 long_integer_type_node, pcvoid_type_node,
13211 tree v2df_ftype_long_pcvoid
13212 = build_function_type_list (V2DF_type_node,
13213 long_integer_type_node, pcvoid_type_node,
13215 tree v2di_ftype_long_pcvoid
13216 = build_function_type_list (V2DI_type_node,
13217 long_integer_type_node, pcvoid_type_node,
13220 tree void_ftype_opaque_long_pvoid
13221 = build_function_type_list (void_type_node,
13222 opaque_V4SI_type_node, long_integer_type_node,
13223 pvoid_type_node, NULL_TREE);
13224 tree void_ftype_v4si_long_pvoid
13225 = build_function_type_list (void_type_node,
13226 V4SI_type_node, long_integer_type_node,
13227 pvoid_type_node, NULL_TREE);
13228 tree void_ftype_v16qi_long_pvoid
13229 = build_function_type_list (void_type_node,
13230 V16QI_type_node, long_integer_type_node,
13231 pvoid_type_node, NULL_TREE);
13232 tree void_ftype_v8hi_long_pvoid
13233 = build_function_type_list (void_type_node,
13234 V8HI_type_node, long_integer_type_node,
13235 pvoid_type_node, NULL_TREE);
13236 tree void_ftype_v4sf_long_pvoid
13237 = build_function_type_list (void_type_node,
13238 V4SF_type_node, long_integer_type_node,
13239 pvoid_type_node, NULL_TREE);
13240 tree void_ftype_v2df_long_pvoid
13241 = build_function_type_list (void_type_node,
13242 V2DF_type_node, long_integer_type_node,
13243 pvoid_type_node, NULL_TREE);
13244 tree void_ftype_v2di_long_pvoid
13245 = build_function_type_list (void_type_node,
13246 V2DI_type_node, long_integer_type_node,
13247 pvoid_type_node, NULL_TREE);
13248 tree int_ftype_int_v8hi_v8hi
13249 = build_function_type_list (integer_type_node,
13250 integer_type_node, V8HI_type_node,
13251 V8HI_type_node, NULL_TREE);
13252 tree int_ftype_int_v16qi_v16qi
13253 = build_function_type_list (integer_type_node,
13254 integer_type_node, V16QI_type_node,
13255 V16QI_type_node, NULL_TREE);
13256 tree int_ftype_int_v4sf_v4sf
13257 = build_function_type_list (integer_type_node,
13258 integer_type_node, V4SF_type_node,
13259 V4SF_type_node, NULL_TREE);
13260 tree int_ftype_int_v2df_v2df
13261 = build_function_type_list (integer_type_node,
13262 integer_type_node, V2DF_type_node,
13263 V2DF_type_node, NULL_TREE);
13264 tree v4si_ftype_v4si
13265 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13266 tree v8hi_ftype_v8hi
13267 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13268 tree v16qi_ftype_v16qi
13269 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13270 tree v4sf_ftype_v4sf
13271 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13272 tree v2df_ftype_v2df
13273 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13274 tree void_ftype_pcvoid_int_int
13275 = build_function_type_list (void_type_node,
13276 pcvoid_type_node, integer_type_node,
13277 integer_type_node, NULL_TREE);
13279 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13280 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13281 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13282 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13283 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13284 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13285 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13286 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13287 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13288 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13289 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13290 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13291 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13292 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13293 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13294 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13295 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13296 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13297 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13298 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13299 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13300 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13301 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13302 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13303 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13304 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13305 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13306 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13307 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13308 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13310 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13311 VSX_BUILTIN_LXVD2X_V2DF);
13312 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13313 VSX_BUILTIN_LXVD2X_V2DI);
13314 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13315 VSX_BUILTIN_LXVW4X_V4SF);
13316 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13317 VSX_BUILTIN_LXVW4X_V4SI);
13318 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13319 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13320 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13321 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13322 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13323 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13324 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13325 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13326 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13327 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13328 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13329 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13330 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13331 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13332 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13333 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13334 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13335 VSX_BUILTIN_VEC_LD);
13336 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13337 VSX_BUILTIN_VEC_ST);
13339 if (rs6000_cpu == PROCESSOR_CELL)
13341 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13342 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13343 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13344 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13346 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13347 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13348 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13349 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13351 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13352 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13353 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13354 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13356 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13357 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13358 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13359 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13361 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13362 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13363 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13365 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13366 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13367 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13368 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13369 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13370 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13371 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13372 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13373 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13374 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13375 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13376 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13378 /* Add the DST variants. */
13380 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13381 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13383 /* Initialize the predicates. */
13384 dp = bdesc_altivec_preds;
13385 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13387 enum machine_mode mode1;
13389 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13390 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13391 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13392 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13397 mode1 = insn_data[dp->icode].operand[1].mode;
13402 type = int_ftype_int_opaque_opaque;
13405 type = int_ftype_int_v4si_v4si;
13408 type = int_ftype_int_v8hi_v8hi;
13411 type = int_ftype_int_v16qi_v16qi;
13414 type = int_ftype_int_v4sf_v4sf;
13417 type = int_ftype_int_v2df_v2df;
13420 gcc_unreachable ();
13423 def_builtin (dp->mask, dp->name, type, dp->code);
13426 /* Initialize the abs* operators. */
13428 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13430 enum machine_mode mode0;
13433 mode0 = insn_data[d->icode].operand[0].mode;
13438 type = v4si_ftype_v4si;
13441 type = v8hi_ftype_v8hi;
13444 type = v16qi_ftype_v16qi;
13447 type = v4sf_ftype_v4sf;
13450 type = v2df_ftype_v2df;
13453 gcc_unreachable ();
13456 def_builtin (d->mask, d->name, type, d->code);
13459 if (TARGET_ALTIVEC)
13463 /* Initialize target builtin that implements
13464 targetm.vectorize.builtin_mask_for_load. */
13466 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13467 v16qi_ftype_long_pcvoid,
13468 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13469 BUILT_IN_MD, NULL, NULL_TREE);
13470 TREE_READONLY (decl) = 1;
13471 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13472 altivec_builtin_mask_for_load = decl;
13475 /* Access to the vec_init patterns. */
13476 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13477 integer_type_node, integer_type_node,
13478 integer_type_node, NULL_TREE);
13479 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13480 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13482 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13483 short_integer_type_node,
13484 short_integer_type_node,
13485 short_integer_type_node,
13486 short_integer_type_node,
13487 short_integer_type_node,
13488 short_integer_type_node,
13489 short_integer_type_node, NULL_TREE);
13490 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13491 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13493 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13494 char_type_node, char_type_node,
13495 char_type_node, char_type_node,
13496 char_type_node, char_type_node,
13497 char_type_node, char_type_node,
13498 char_type_node, char_type_node,
13499 char_type_node, char_type_node,
13500 char_type_node, char_type_node,
13501 char_type_node, NULL_TREE);
13502 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13503 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13505 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13506 float_type_node, float_type_node,
13507 float_type_node, NULL_TREE);
13508 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13509 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13513 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13514 double_type_node, NULL_TREE);
13515 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13516 VSX_BUILTIN_VEC_INIT_V2DF);
13518 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13519 intDI_type_node, NULL_TREE);
13520 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13521 VSX_BUILTIN_VEC_INIT_V2DI);
13524 /* Access to the vec_set patterns. */
13525 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13527 integer_type_node, NULL_TREE);
13528 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13529 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13531 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13533 integer_type_node, NULL_TREE);
13534 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13535 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13537 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13539 integer_type_node, NULL_TREE);
13540 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13541 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13543 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13545 integer_type_node, NULL_TREE);
13546 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13547 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13551 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13553 integer_type_node, NULL_TREE);
13554 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13555 VSX_BUILTIN_VEC_SET_V2DF);
13557 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13559 integer_type_node, NULL_TREE);
13560 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13561 VSX_BUILTIN_VEC_SET_V2DI);
13564 /* Access to the vec_extract patterns. */
13565 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13566 integer_type_node, NULL_TREE);
13567 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13568 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13570 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13571 integer_type_node, NULL_TREE);
13572 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13573 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13575 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13576 integer_type_node, NULL_TREE);
13577 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13578 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13580 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13581 integer_type_node, NULL_TREE);
13582 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13583 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13587 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13588 integer_type_node, NULL_TREE);
13589 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13590 VSX_BUILTIN_VEC_EXT_V2DF);
13592 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13593 integer_type_node, NULL_TREE);
13594 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13595 VSX_BUILTIN_VEC_EXT_V2DI);
13599 /* Hash function for builtin functions with up to 3 arguments and a return
13602 builtin_hash_function (const void *hash_entry)
13606 const struct builtin_hash_struct *bh =
13607 (const struct builtin_hash_struct *) hash_entry;
13609 for (i = 0; i < 4; i++)
13611 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13612 ret = (ret * 2) + bh->uns_p[i];
13618 /* Compare builtin hash entries H1 and H2 for equivalence. */
13620 builtin_hash_eq (const void *h1, const void *h2)
13622 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13623 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13625 return ((p1->mode[0] == p2->mode[0])
13626 && (p1->mode[1] == p2->mode[1])
13627 && (p1->mode[2] == p2->mode[2])
13628 && (p1->mode[3] == p2->mode[3])
13629 && (p1->uns_p[0] == p2->uns_p[0])
13630 && (p1->uns_p[1] == p2->uns_p[1])
13631 && (p1->uns_p[2] == p2->uns_p[2])
13632 && (p1->uns_p[3] == p2->uns_p[3]));
13635 /* Map types for builtin functions with an explicit return type and up to 3
13636 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13637 of the argument. */
13639 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13640 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13641 enum rs6000_builtins builtin, const char *name)
13643 struct builtin_hash_struct h;
13644 struct builtin_hash_struct *h2;
13648 tree ret_type = NULL_TREE;
13649 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13652 /* Create builtin_hash_table. */
13653 if (builtin_hash_table == NULL)
13654 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13655 builtin_hash_eq, NULL);
13657 h.type = NULL_TREE;
13658 h.mode[0] = mode_ret;
13659 h.mode[1] = mode_arg0;
13660 h.mode[2] = mode_arg1;
13661 h.mode[3] = mode_arg2;
13667 /* If the builtin is a type that produces unsigned results or takes unsigned
13668 arguments, and it is returned as a decl for the vectorizer (such as
13669 widening multiplies, permute), make sure the arguments and return value
13670 are type correct. */
13673 /* unsigned 2 argument functions. */
13674 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13675 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13676 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13677 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13683 /* unsigned 3 argument functions. */
13684 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13685 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13686 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13687 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13688 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13689 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13690 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13691 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13692 case VSX_BUILTIN_VPERM_16QI_UNS:
13693 case VSX_BUILTIN_VPERM_8HI_UNS:
13694 case VSX_BUILTIN_VPERM_4SI_UNS:
13695 case VSX_BUILTIN_VPERM_2DI_UNS:
13696 case VSX_BUILTIN_XXSEL_16QI_UNS:
13697 case VSX_BUILTIN_XXSEL_8HI_UNS:
13698 case VSX_BUILTIN_XXSEL_4SI_UNS:
13699 case VSX_BUILTIN_XXSEL_2DI_UNS:
13706 /* signed permute functions with unsigned char mask. */
13707 case ALTIVEC_BUILTIN_VPERM_16QI:
13708 case ALTIVEC_BUILTIN_VPERM_8HI:
13709 case ALTIVEC_BUILTIN_VPERM_4SI:
13710 case ALTIVEC_BUILTIN_VPERM_4SF:
13711 case ALTIVEC_BUILTIN_VPERM_2DI:
13712 case ALTIVEC_BUILTIN_VPERM_2DF:
13713 case VSX_BUILTIN_VPERM_16QI:
13714 case VSX_BUILTIN_VPERM_8HI:
13715 case VSX_BUILTIN_VPERM_4SI:
13716 case VSX_BUILTIN_VPERM_4SF:
13717 case VSX_BUILTIN_VPERM_2DI:
13718 case VSX_BUILTIN_VPERM_2DF:
13722 /* unsigned args, signed return. */
13723 case VSX_BUILTIN_XVCVUXDDP_UNS:
13724 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13728 /* signed args, unsigned return. */
13729 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13730 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13738 /* Figure out how many args are present. */
13739 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13743 fatal_error ("internal error: builtin function %s had no type", name);
13745 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13746 if (!ret_type && h.uns_p[0])
13747 ret_type = builtin_mode_to_type[h.mode[0]][0];
13750 fatal_error ("internal error: builtin function %s had an unexpected "
13751 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13753 for (i = 0; i < num_args; i++)
13755 int m = (int) h.mode[i+1];
13756 int uns_p = h.uns_p[i+1];
13758 arg_type[i] = builtin_mode_to_type[m][uns_p];
13759 if (!arg_type[i] && uns_p)
13760 arg_type[i] = builtin_mode_to_type[m][0];
13763 fatal_error ("internal error: builtin function %s, argument %d "
13764 "had unexpected argument type %s", name, i,
13765 GET_MODE_NAME (m));
13768 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13769 if (*found == NULL)
13771 h2 = ggc_alloc_builtin_hash_struct ();
13773 *found = (void *)h2;
13774 args = void_list_node;
13776 for (i = num_args - 1; i >= 0; i--)
13777 args = tree_cons (NULL_TREE, arg_type[i], args);
13779 h2->type = build_function_type (ret_type, args);
13782 return ((struct builtin_hash_struct *)(*found))->type;
13786 rs6000_common_init_builtins (void)
13788 const struct builtin_description *d;
13791 tree opaque_ftype_opaque = NULL_TREE;
13792 tree opaque_ftype_opaque_opaque = NULL_TREE;
13793 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13794 tree v2si_ftype_qi = NULL_TREE;
13795 tree v2si_ftype_v2si_qi = NULL_TREE;
13796 tree v2si_ftype_int_qi = NULL_TREE;
13798 if (!TARGET_PAIRED_FLOAT)
13800 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13801 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13804 /* Add the ternary operators. */
13806 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13809 int mask = d->mask;
13811 if ((mask != 0 && (mask & target_flags) == 0)
13812 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13815 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13816 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13817 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13818 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13820 if (! (type = opaque_ftype_opaque_opaque_opaque))
13821 type = opaque_ftype_opaque_opaque_opaque
13822 = build_function_type_list (opaque_V4SI_type_node,
13823 opaque_V4SI_type_node,
13824 opaque_V4SI_type_node,
13825 opaque_V4SI_type_node,
13830 enum insn_code icode = d->icode;
13831 if (d->name == 0 || icode == CODE_FOR_nothing)
13834 type = builtin_function_type (insn_data[icode].operand[0].mode,
13835 insn_data[icode].operand[1].mode,
13836 insn_data[icode].operand[2].mode,
13837 insn_data[icode].operand[3].mode,
13841 def_builtin (d->mask, d->name, type, d->code);
13844 /* Add the binary operators. */
13846 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13848 enum machine_mode mode0, mode1, mode2;
13850 int mask = d->mask;
13852 if ((mask != 0 && (mask & target_flags) == 0)
13853 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13856 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13857 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13858 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13859 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13861 if (! (type = opaque_ftype_opaque_opaque))
13862 type = opaque_ftype_opaque_opaque
13863 = build_function_type_list (opaque_V4SI_type_node,
13864 opaque_V4SI_type_node,
13865 opaque_V4SI_type_node,
13870 enum insn_code icode = d->icode;
13871 if (d->name == 0 || icode == CODE_FOR_nothing)
13874 mode0 = insn_data[icode].operand[0].mode;
13875 mode1 = insn_data[icode].operand[1].mode;
13876 mode2 = insn_data[icode].operand[2].mode;
13878 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13880 if (! (type = v2si_ftype_v2si_qi))
13881 type = v2si_ftype_v2si_qi
13882 = build_function_type_list (opaque_V2SI_type_node,
13883 opaque_V2SI_type_node,
13888 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13889 && mode2 == QImode)
13891 if (! (type = v2si_ftype_int_qi))
13892 type = v2si_ftype_int_qi
13893 = build_function_type_list (opaque_V2SI_type_node,
13900 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13904 def_builtin (d->mask, d->name, type, d->code);
13907 /* Add the simple unary operators. */
13908 d = (struct builtin_description *) bdesc_1arg;
13909 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13911 enum machine_mode mode0, mode1;
13913 int mask = d->mask;
13915 if ((mask != 0 && (mask & target_flags) == 0)
13916 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13919 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13920 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13921 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13922 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13924 if (! (type = opaque_ftype_opaque))
13925 type = opaque_ftype_opaque
13926 = build_function_type_list (opaque_V4SI_type_node,
13927 opaque_V4SI_type_node,
13932 enum insn_code icode = d->icode;
13933 if (d->name == 0 || icode == CODE_FOR_nothing)
13936 mode0 = insn_data[icode].operand[0].mode;
13937 mode1 = insn_data[icode].operand[1].mode;
13939 if (mode0 == V2SImode && mode1 == QImode)
13941 if (! (type = v2si_ftype_qi))
13942 type = v2si_ftype_qi
13943 = build_function_type_list (opaque_V2SI_type_node,
13949 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13953 def_builtin (d->mask, d->name, type, d->code);
13958 rs6000_init_libfuncs (void)
13960 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13961 && !TARGET_POWER2 && !TARGET_POWERPC)
13963 /* AIX library routines for float->int conversion. */
13964 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13965 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13966 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13967 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13970 if (!TARGET_IEEEQUAD)
13971 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13972 if (!TARGET_XL_COMPAT)
13974 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13975 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13976 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13977 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13979 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13981 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13982 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13983 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13984 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13985 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13986 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13987 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13989 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13990 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13991 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13992 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13993 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13994 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13995 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13996 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13999 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
14000 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
14004 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
14005 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
14006 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
14007 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
14011 /* 32-bit SVR4 quad floating point routines. */
14013 set_optab_libfunc (add_optab, TFmode, "_q_add");
14014 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
14015 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
14016 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
14017 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
14018 if (TARGET_PPC_GPOPT || TARGET_POWER2)
14019 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
14021 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
14022 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
14023 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
14024 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
14025 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
14026 set_optab_libfunc (le_optab, TFmode, "_q_fle");
14028 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
14029 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
14030 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
14031 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
14032 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
14033 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
14034 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
14035 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
14040 /* Expand a block clear operation, and return 1 if successful. Return 0
14041 if we should let the compiler generate normal code.
14043 operands[0] is the destination
14044 operands[1] is the length
14045 operands[3] is the alignment */
14048 expand_block_clear (rtx operands[])
14050 rtx orig_dest = operands[0];
14051 rtx bytes_rtx = operands[1];
14052 rtx align_rtx = operands[3];
14053 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
14054 HOST_WIDE_INT align;
14055 HOST_WIDE_INT bytes;
14060 /* If this is not a fixed size move, just call memcpy */
14064 /* This must be a fixed size alignment */
14065 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14066 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14068 /* Anything to clear? */
14069 bytes = INTVAL (bytes_rtx);
14073 /* Use the builtin memset after a point, to avoid huge code bloat.
14074 When optimize_size, avoid any significant code bloat; calling
14075 memset is about 4 instructions, so allow for one instruction to
14076 load zero and three to do clearing. */
14077 if (TARGET_ALTIVEC && align >= 128)
14079 else if (TARGET_POWERPC64 && align >= 32)
14081 else if (TARGET_SPE && align >= 64)
14086 if (optimize_size && bytes > 3 * clear_step)
14088 if (! optimize_size && bytes > 8 * clear_step)
14091 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14093 enum machine_mode mode = BLKmode;
14096 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14101 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14106 else if (bytes >= 8 && TARGET_POWERPC64
14107 /* 64-bit loads and stores require word-aligned
14109 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14114 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14115 { /* move 4 bytes */
14119 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14120 { /* move 2 bytes */
14124 else /* move 1 byte at a time */
14130 dest = adjust_address (orig_dest, mode, offset);
14132 emit_move_insn (dest, CONST0_RTX (mode));
14139 /* Expand a block move operation, and return 1 if successful. Return 0
14140 if we should let the compiler generate normal code.
14142 operands[0] is the destination
14143 operands[1] is the source
14144 operands[2] is the length
14145 operands[3] is the alignment */
14147 #define MAX_MOVE_REG 4
14150 expand_block_move (rtx operands[])
14152 rtx orig_dest = operands[0];
14153 rtx orig_src = operands[1];
14154 rtx bytes_rtx = operands[2];
14155 rtx align_rtx = operands[3];
14156 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14161 rtx stores[MAX_MOVE_REG];
14164 /* If this is not a fixed size move, just call memcpy */
14168 /* This must be a fixed size alignment */
14169 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14170 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14172 /* Anything to move? */
14173 bytes = INTVAL (bytes_rtx);
14177 if (bytes > rs6000_block_move_inline_limit)
14180 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14183 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14184 rtx (*mov) (rtx, rtx);
14186 enum machine_mode mode = BLKmode;
14189 /* Altivec first, since it will be faster than a string move
14190 when it applies, and usually not significantly larger. */
14191 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14195 gen_func.mov = gen_movv4si;
14197 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14201 gen_func.mov = gen_movv2si;
14203 else if (TARGET_STRING
14204 && bytes > 24 /* move up to 32 bytes at a time */
14210 && ! fixed_regs[10]
14211 && ! fixed_regs[11]
14212 && ! fixed_regs[12])
14214 move_bytes = (bytes > 32) ? 32 : bytes;
14215 gen_func.movmemsi = gen_movmemsi_8reg;
14217 else if (TARGET_STRING
14218 && bytes > 16 /* move up to 24 bytes at a time */
14224 && ! fixed_regs[10])
14226 move_bytes = (bytes > 24) ? 24 : bytes;
14227 gen_func.movmemsi = gen_movmemsi_6reg;
14229 else if (TARGET_STRING
14230 && bytes > 8 /* move up to 16 bytes at a time */
14234 && ! fixed_regs[8])
14236 move_bytes = (bytes > 16) ? 16 : bytes;
14237 gen_func.movmemsi = gen_movmemsi_4reg;
14239 else if (bytes >= 8 && TARGET_POWERPC64
14240 /* 64-bit loads and stores require word-aligned
14242 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14246 gen_func.mov = gen_movdi;
14248 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14249 { /* move up to 8 bytes at a time */
14250 move_bytes = (bytes > 8) ? 8 : bytes;
14251 gen_func.movmemsi = gen_movmemsi_2reg;
14253 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14254 { /* move 4 bytes */
14257 gen_func.mov = gen_movsi;
14259 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14260 { /* move 2 bytes */
14263 gen_func.mov = gen_movhi;
14265 else if (TARGET_STRING && bytes > 1)
14266 { /* move up to 4 bytes at a time */
14267 move_bytes = (bytes > 4) ? 4 : bytes;
14268 gen_func.movmemsi = gen_movmemsi_1reg;
14270 else /* move 1 byte at a time */
14274 gen_func.mov = gen_movqi;
14277 src = adjust_address (orig_src, mode, offset);
14278 dest = adjust_address (orig_dest, mode, offset);
14280 if (mode != BLKmode)
14282 rtx tmp_reg = gen_reg_rtx (mode);
14284 emit_insn ((*gen_func.mov) (tmp_reg, src));
14285 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14288 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14291 for (i = 0; i < num_reg; i++)
14292 emit_insn (stores[i]);
14296 if (mode == BLKmode)
14298 /* Move the address into scratch registers. The movmemsi
14299 patterns require zero offset. */
14300 if (!REG_P (XEXP (src, 0)))
14302 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14303 src = replace_equiv_address (src, src_reg);
14305 set_mem_size (src, GEN_INT (move_bytes));
14307 if (!REG_P (XEXP (dest, 0)))
14309 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14310 dest = replace_equiv_address (dest, dest_reg);
14312 set_mem_size (dest, GEN_INT (move_bytes));
14314 emit_insn ((*gen_func.movmemsi) (dest, src,
14315 GEN_INT (move_bytes & 31),
14324 /* Return a string to perform a load_multiple operation.
14325 operands[0] is the vector.
14326 operands[1] is the source address.
14327 operands[2] is the first destination register. */
14330 rs6000_output_load_multiple (rtx operands[3])
14332 /* We have to handle the case where the pseudo used to contain the address
14333 is assigned to one of the output registers. */
14335 int words = XVECLEN (operands[0], 0);
14338 if (XVECLEN (operands[0], 0) == 1)
14339 return "{l|lwz} %2,0(%1)";
14341 for (i = 0; i < words; i++)
14342 if (refers_to_regno_p (REGNO (operands[2]) + i,
14343 REGNO (operands[2]) + i + 1, operands[1], 0))
14347 xop[0] = GEN_INT (4 * (words-1));
14348 xop[1] = operands[1];
14349 xop[2] = operands[2];
14350 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14355 xop[0] = GEN_INT (4 * (words-1));
14356 xop[1] = operands[1];
14357 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14358 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);
14363 for (j = 0; j < words; j++)
14366 xop[0] = GEN_INT (j * 4);
14367 xop[1] = operands[1];
14368 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14369 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14371 xop[0] = GEN_INT (i * 4);
14372 xop[1] = operands[1];
14373 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14378 return "{lsi|lswi} %2,%1,%N0";
14382 /* A validation routine: say whether CODE, a condition code, and MODE
14383 match. The other alternatives either don't make sense or should
14384 never be generated. */
14387 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14389 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14390 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14391 && GET_MODE_CLASS (mode) == MODE_CC);
14393 /* These don't make sense. */
14394 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14395 || mode != CCUNSmode);
14397 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14398 || mode == CCUNSmode);
14400 gcc_assert (mode == CCFPmode
14401 || (code != ORDERED && code != UNORDERED
14402 && code != UNEQ && code != LTGT
14403 && code != UNGT && code != UNLT
14404 && code != UNGE && code != UNLE));
14406 /* These should never be generated except for
14407 flag_finite_math_only. */
14408 gcc_assert (mode != CCFPmode
14409 || flag_finite_math_only
14410 || (code != LE && code != GE
14411 && code != UNEQ && code != LTGT
14412 && code != UNGT && code != UNLT));
14414 /* These are invalid; the information is not there. */
14415 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14419 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14420 mask required to convert the result of a rotate insn into a shift
14421 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14424 includes_lshift_p (rtx shiftop, rtx andop)
14426 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14428 shift_mask <<= INTVAL (shiftop);
14430 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14433 /* Similar, but for right shift. */
14436 includes_rshift_p (rtx shiftop, rtx andop)
14438 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14440 shift_mask >>= INTVAL (shiftop);
14442 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14445 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14446 to perform a left shift. It must have exactly SHIFTOP least
14447 significant 0's, then one or more 1's, then zero or more 0's. */
14450 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14452 if (GET_CODE (andop) == CONST_INT)
14454 HOST_WIDE_INT c, lsb, shift_mask;
14456 c = INTVAL (andop);
14457 if (c == 0 || c == ~0)
14461 shift_mask <<= INTVAL (shiftop);
14463 /* Find the least significant one bit. */
14466 /* It must coincide with the LSB of the shift mask. */
14467 if (-lsb != shift_mask)
14470 /* Invert to look for the next transition (if any). */
14473 /* Remove the low group of ones (originally low group of zeros). */
14476 /* Again find the lsb, and check we have all 1's above. */
14480 else if (GET_CODE (andop) == CONST_DOUBLE
14481 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14483 HOST_WIDE_INT low, high, lsb;
14484 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14486 low = CONST_DOUBLE_LOW (andop);
14487 if (HOST_BITS_PER_WIDE_INT < 64)
14488 high = CONST_DOUBLE_HIGH (andop);
14490 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14491 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14494 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14496 shift_mask_high = ~0;
14497 if (INTVAL (shiftop) > 32)
14498 shift_mask_high <<= INTVAL (shiftop) - 32;
14500 lsb = high & -high;
14502 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14508 lsb = high & -high;
14509 return high == -lsb;
14512 shift_mask_low = ~0;
14513 shift_mask_low <<= INTVAL (shiftop);
14517 if (-lsb != shift_mask_low)
14520 if (HOST_BITS_PER_WIDE_INT < 64)
14525 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14527 lsb = high & -high;
14528 return high == -lsb;
14532 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14538 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14539 to perform a left shift. It must have SHIFTOP or more least
14540 significant 0's, with the remainder of the word 1's. */
14543 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14545 if (GET_CODE (andop) == CONST_INT)
14547 HOST_WIDE_INT c, lsb, shift_mask;
14550 shift_mask <<= INTVAL (shiftop);
14551 c = INTVAL (andop);
14553 /* Find the least significant one bit. */
14556 /* It must be covered by the shift mask.
14557 This test also rejects c == 0. */
14558 if ((lsb & shift_mask) == 0)
14561 /* Check we have all 1's above the transition, and reject all 1's. */
14562 return c == -lsb && lsb != 1;
14564 else if (GET_CODE (andop) == CONST_DOUBLE
14565 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14567 HOST_WIDE_INT low, lsb, shift_mask_low;
14569 low = CONST_DOUBLE_LOW (andop);
14571 if (HOST_BITS_PER_WIDE_INT < 64)
14573 HOST_WIDE_INT high, shift_mask_high;
14575 high = CONST_DOUBLE_HIGH (andop);
14579 shift_mask_high = ~0;
14580 if (INTVAL (shiftop) > 32)
14581 shift_mask_high <<= INTVAL (shiftop) - 32;
14583 lsb = high & -high;
14585 if ((lsb & shift_mask_high) == 0)
14588 return high == -lsb;
14594 shift_mask_low = ~0;
14595 shift_mask_low <<= INTVAL (shiftop);
14599 if ((lsb & shift_mask_low) == 0)
14602 return low == -lsb && lsb != 1;
14608 /* Return 1 if operands will generate a valid arguments to rlwimi
14609 instruction for insert with right shift in 64-bit mode. The mask may
14610 not start on the first bit or stop on the last bit because wrap-around
14611 effects of instruction do not correspond to semantics of RTL insn. */
14614 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14616 if (INTVAL (startop) > 32
14617 && INTVAL (startop) < 64
14618 && INTVAL (sizeop) > 1
14619 && INTVAL (sizeop) + INTVAL (startop) < 64
14620 && INTVAL (shiftop) > 0
14621 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14622 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14628 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14629 for lfq and stfq insns iff the registers are hard registers. */
14632 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14634 /* We might have been passed a SUBREG. */
14635 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14638 /* We might have been passed non floating point registers. */
14639 if (!FP_REGNO_P (REGNO (reg1))
14640 || !FP_REGNO_P (REGNO (reg2)))
14643 return (REGNO (reg1) == REGNO (reg2) - 1);
14646 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14647 addr1 and addr2 must be in consecutive memory locations
14648 (addr2 == addr1 + 8). */
14651 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14654 unsigned int reg1, reg2;
14655 int offset1, offset2;
14657 /* The mems cannot be volatile. */
14658 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14661 addr1 = XEXP (mem1, 0);
14662 addr2 = XEXP (mem2, 0);
14664 /* Extract an offset (if used) from the first addr. */
14665 if (GET_CODE (addr1) == PLUS)
14667 /* If not a REG, return zero. */
14668 if (GET_CODE (XEXP (addr1, 0)) != REG)
14672 reg1 = REGNO (XEXP (addr1, 0));
14673 /* The offset must be constant! */
14674 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14676 offset1 = INTVAL (XEXP (addr1, 1));
14679 else if (GET_CODE (addr1) != REG)
14683 reg1 = REGNO (addr1);
14684 /* This was a simple (mem (reg)) expression. Offset is 0. */
14688 /* And now for the second addr. */
14689 if (GET_CODE (addr2) == PLUS)
14691 /* If not a REG, return zero. */
14692 if (GET_CODE (XEXP (addr2, 0)) != REG)
14696 reg2 = REGNO (XEXP (addr2, 0));
14697 /* The offset must be constant. */
14698 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14700 offset2 = INTVAL (XEXP (addr2, 1));
14703 else if (GET_CODE (addr2) != REG)
14707 reg2 = REGNO (addr2);
14708 /* This was a simple (mem (reg)) expression. Offset is 0. */
14712 /* Both of these must have the same base register. */
14716 /* The offset for the second addr must be 8 more than the first addr. */
14717 if (offset2 != offset1 + 8)
14720 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14727 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14729 static bool eliminated = false;
14732 if (mode != SDmode)
14733 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14736 rtx mem = cfun->machine->sdmode_stack_slot;
14737 gcc_assert (mem != NULL_RTX);
14741 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14742 cfun->machine->sdmode_stack_slot = mem;
14748 if (TARGET_DEBUG_ADDR)
14750 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14751 GET_MODE_NAME (mode));
14753 fprintf (stderr, "\tNULL_RTX\n");
14762 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14764 /* Don't walk into types. */
14765 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14767 *walk_subtrees = 0;
14771 switch (TREE_CODE (*tp))
14780 case VIEW_CONVERT_EXPR:
14781 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14791 enum reload_reg_type {
14793 VECTOR_REGISTER_TYPE,
14794 OTHER_REGISTER_TYPE
14797 static enum reload_reg_type
14798 rs6000_reload_register_type (enum reg_class rclass)
14804 return GPR_REGISTER_TYPE;
14809 return VECTOR_REGISTER_TYPE;
14812 return OTHER_REGISTER_TYPE;
14816 /* Inform reload about cases where moving X with a mode MODE to a register in
14817 RCLASS requires an extra scratch or immediate register. Return the class
14818 needed for the immediate register.
14820 For VSX and Altivec, we may need a register to convert sp+offset into
14824 rs6000_secondary_reload (bool in_p,
14826 reg_class_t rclass_i,
14827 enum machine_mode mode,
14828 secondary_reload_info *sri)
14830 enum reg_class rclass = (enum reg_class) rclass_i;
14831 reg_class_t ret = ALL_REGS;
14832 enum insn_code icode;
14833 bool default_p = false;
14835 sri->icode = CODE_FOR_nothing;
14837 /* Convert vector loads and stores into gprs to use an additional base
14839 icode = rs6000_vector_reload[mode][in_p != false];
14840 if (icode != CODE_FOR_nothing)
14843 sri->icode = CODE_FOR_nothing;
14844 sri->extra_cost = 0;
14846 if (GET_CODE (x) == MEM)
14848 rtx addr = XEXP (x, 0);
14850 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14851 an extra register in that case, but it would need an extra
14852 register if the addressing is reg+reg or (reg+reg)&(-16). */
14853 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14855 if (!legitimate_indirect_address_p (addr, false)
14856 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14858 sri->icode = icode;
14859 /* account for splitting the loads, and converting the
14860 address from reg+reg to reg. */
14861 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14862 + ((GET_CODE (addr) == AND) ? 1 : 0));
14865 /* Loads to and stores from vector registers can only do reg+reg
14866 addressing. Altivec registers can also do (reg+reg)&(-16). */
14867 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14868 || rclass == FLOAT_REGS || rclass == NO_REGS)
14870 if (!VECTOR_MEM_ALTIVEC_P (mode)
14871 && GET_CODE (addr) == AND
14872 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14873 && INTVAL (XEXP (addr, 1)) == -16
14874 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14875 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14877 sri->icode = icode;
14878 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14881 else if (!legitimate_indirect_address_p (addr, false)
14882 && (rclass == NO_REGS
14883 || !legitimate_indexed_address_p (addr, false)))
14885 sri->icode = icode;
14886 sri->extra_cost = 1;
14889 icode = CODE_FOR_nothing;
14891 /* Any other loads, including to pseudo registers which haven't been
14892 assigned to a register yet, default to require a scratch
14896 sri->icode = icode;
14897 sri->extra_cost = 2;
14900 else if (REG_P (x))
14902 int regno = true_regnum (x);
14904 icode = CODE_FOR_nothing;
14905 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14909 enum reg_class xclass = REGNO_REG_CLASS (regno);
14910 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14911 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14913 /* If memory is needed, use default_secondary_reload to create the
14915 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14928 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14930 gcc_assert (ret != ALL_REGS);
14932 if (TARGET_DEBUG_ADDR)
14935 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14937 reg_class_names[ret],
14938 in_p ? "true" : "false",
14939 reg_class_names[rclass],
14940 GET_MODE_NAME (mode));
14943 fprintf (stderr, ", default secondary reload");
14945 if (sri->icode != CODE_FOR_nothing)
14946 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14947 insn_data[sri->icode].name, sri->extra_cost);
14949 fprintf (stderr, "\n");
14957 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14958 to SP+reg addressing. */
14961 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14963 int regno = true_regnum (reg);
14964 enum machine_mode mode = GET_MODE (reg);
14965 enum reg_class rclass;
14967 rtx and_op2 = NULL_RTX;
14970 rtx scratch_or_premodify = scratch;
14974 if (TARGET_DEBUG_ADDR)
14976 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14977 store_p ? "store" : "load");
14978 fprintf (stderr, "reg:\n");
14980 fprintf (stderr, "mem:\n");
14982 fprintf (stderr, "scratch:\n");
14983 debug_rtx (scratch);
14986 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14987 gcc_assert (GET_CODE (mem) == MEM);
14988 rclass = REGNO_REG_CLASS (regno);
14989 addr = XEXP (mem, 0);
14993 /* GPRs can handle reg + small constant, all other addresses need to use
14994 the scratch register. */
14997 if (GET_CODE (addr) == AND)
14999 and_op2 = XEXP (addr, 1);
15000 addr = XEXP (addr, 0);
15003 if (GET_CODE (addr) == PRE_MODIFY)
15005 scratch_or_premodify = XEXP (addr, 0);
15006 gcc_assert (REG_P (scratch_or_premodify));
15007 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15008 addr = XEXP (addr, 1);
15011 if (GET_CODE (addr) == PLUS
15012 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
15013 || and_op2 != NULL_RTX))
15015 addr_op1 = XEXP (addr, 0);
15016 addr_op2 = XEXP (addr, 1);
15017 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
15019 if (!REG_P (addr_op2)
15020 && (GET_CODE (addr_op2) != CONST_INT
15021 || !satisfies_constraint_I (addr_op2)))
15023 if (TARGET_DEBUG_ADDR)
15026 "\nMove plus addr to register %s, mode = %s: ",
15027 rs6000_reg_names[REGNO (scratch)],
15028 GET_MODE_NAME (mode));
15029 debug_rtx (addr_op2);
15031 rs6000_emit_move (scratch, addr_op2, Pmode);
15032 addr_op2 = scratch;
15035 emit_insn (gen_rtx_SET (VOIDmode,
15036 scratch_or_premodify,
15037 gen_rtx_PLUS (Pmode,
15041 addr = scratch_or_premodify;
15042 scratch_or_premodify = scratch;
15044 else if (!legitimate_indirect_address_p (addr, false)
15045 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
15047 if (TARGET_DEBUG_ADDR)
15049 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15050 rs6000_reg_names[REGNO (scratch_or_premodify)],
15051 GET_MODE_NAME (mode));
15054 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15055 addr = scratch_or_premodify;
15056 scratch_or_premodify = scratch;
15060 /* Float/Altivec registers can only handle reg+reg addressing. Move
15061 other addresses into a scratch register. */
15066 /* With float regs, we need to handle the AND ourselves, since we can't
15067 use the Altivec instruction with an implicit AND -16. Allow scalar
15068 loads to float registers to use reg+offset even if VSX. */
15069 if (GET_CODE (addr) == AND
15070 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
15071 || GET_CODE (XEXP (addr, 1)) != CONST_INT
15072 || INTVAL (XEXP (addr, 1)) != -16
15073 || !VECTOR_MEM_ALTIVEC_P (mode)))
15075 and_op2 = XEXP (addr, 1);
15076 addr = XEXP (addr, 0);
15079 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15080 as the address later. */
15081 if (GET_CODE (addr) == PRE_MODIFY
15082 && (!VECTOR_MEM_VSX_P (mode)
15083 || and_op2 != NULL_RTX
15084 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
15086 scratch_or_premodify = XEXP (addr, 0);
15087 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
15089 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15090 addr = XEXP (addr, 1);
15093 if (legitimate_indirect_address_p (addr, false) /* reg */
15094 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15095 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15096 || (GET_CODE (addr) == AND /* Altivec memory */
15097 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15098 && INTVAL (XEXP (addr, 1)) == -16
15099 && VECTOR_MEM_ALTIVEC_P (mode))
15100 || (rclass == FLOAT_REGS /* legacy float mem */
15101 && GET_MODE_SIZE (mode) == 8
15102 && and_op2 == NULL_RTX
15103 && scratch_or_premodify == scratch
15104 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15107 else if (GET_CODE (addr) == PLUS)
15109 addr_op1 = XEXP (addr, 0);
15110 addr_op2 = XEXP (addr, 1);
15111 gcc_assert (REG_P (addr_op1));
15113 if (TARGET_DEBUG_ADDR)
15115 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15116 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15117 debug_rtx (addr_op2);
15119 rs6000_emit_move (scratch, addr_op2, Pmode);
15120 emit_insn (gen_rtx_SET (VOIDmode,
15121 scratch_or_premodify,
15122 gen_rtx_PLUS (Pmode,
15125 addr = scratch_or_premodify;
15126 scratch_or_premodify = scratch;
15129 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15130 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15132 if (TARGET_DEBUG_ADDR)
15134 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15135 rs6000_reg_names[REGNO (scratch_or_premodify)],
15136 GET_MODE_NAME (mode));
15140 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15141 addr = scratch_or_premodify;
15142 scratch_or_premodify = scratch;
15146 gcc_unreachable ();
15151 gcc_unreachable ();
15154 /* If the original address involved a pre-modify that we couldn't use the VSX
15155 memory instruction with update, and we haven't taken care of already,
15156 store the address in the pre-modify register and use that as the
15158 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15160 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15161 addr = scratch_or_premodify;
15164 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15165 memory instruction, recreate the AND now, including the clobber which is
15166 generated by the general ANDSI3/ANDDI3 patterns for the
15167 andi. instruction. */
15168 if (and_op2 != NULL_RTX)
15170 if (! legitimate_indirect_address_p (addr, false))
15172 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15176 if (TARGET_DEBUG_ADDR)
15178 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15179 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15180 debug_rtx (and_op2);
15183 and_rtx = gen_rtx_SET (VOIDmode,
15185 gen_rtx_AND (Pmode,
15189 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15190 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15191 gen_rtvec (2, and_rtx, cc_clobber)));
15195 /* Adjust the address if it changed. */
15196 if (addr != XEXP (mem, 0))
15198 mem = change_address (mem, mode, addr);
15199 if (TARGET_DEBUG_ADDR)
15200 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15203 /* Now create the move. */
15205 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15207 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15212 /* Target hook to return the cover classes for Integrated Register Allocator.
15213 Cover classes is a set of non-intersected register classes covering all hard
15214 registers used for register allocation purpose. Any move between two
15215 registers of a cover class should be cheaper than load or store of the
15216 registers. The value is array of register classes with LIM_REG_CLASSES used
15219 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
15220 account for the Altivec and Floating registers being subsets of the VSX
15221 register set under VSX, but distinct register sets on pre-VSX machines. */
15223 static const reg_class_t *
15224 rs6000_ira_cover_classes (void)
15226 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
15227 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
15229 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
15232 /* Allocate a 64-bit stack slot to be used for copying SDmode
15233 values through if this function has any SDmode references. */
15236 rs6000_alloc_sdmode_stack_slot (void)
15240 gimple_stmt_iterator gsi;
15242 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15245 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15247 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15250 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15251 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15257 /* Check for any SDmode parameters of the function. */
15258 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15260 if (TREE_TYPE (t) == error_mark_node)
15263 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15264 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15266 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15267 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15275 rs6000_instantiate_decls (void)
15277 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15278 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15281 /* Given an rtx X being reloaded into a reg required to be
15282 in class CLASS, return the class of reg to actually use.
15283 In general this is just CLASS; but on some machines
15284 in some cases it is preferable to use a more restrictive class.
15286 On the RS/6000, we have to return NO_REGS when we want to reload a
15287 floating-point CONST_DOUBLE to force it to be copied to memory.
15289 We also don't want to reload integer values into floating-point
15290 registers if we can at all help it. In fact, this can
15291 cause reload to die, if it tries to generate a reload of CTR
15292 into a FP register and discovers it doesn't have the memory location
15295 ??? Would it be a good idea to have reload do the converse, that is
15296 try to reload floating modes into FP registers if possible?
15299 static enum reg_class
15300 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15302 enum machine_mode mode = GET_MODE (x);
15304 if (VECTOR_UNIT_VSX_P (mode)
15305 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15308 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15309 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15310 && easy_vector_constant (x, mode))
15311 return ALTIVEC_REGS;
15313 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15316 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15317 return GENERAL_REGS;
15319 /* For VSX, prefer the traditional registers for 64-bit values because we can
15320 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15321 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15322 prefer Altivec loads.. */
15323 if (rclass == VSX_REGS)
15325 if (GET_MODE_SIZE (mode) <= 8)
15328 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15329 return ALTIVEC_REGS;
15337 /* Debug version of rs6000_preferred_reload_class. */
15338 static enum reg_class
15339 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15341 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15344 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15346 reg_class_names[ret], reg_class_names[rclass],
15347 GET_MODE_NAME (GET_MODE (x)));
15353 /* If we are copying between FP or AltiVec registers and anything else, we need
15354 a memory location. The exception is when we are targeting ppc64 and the
15355 move to/from fpr to gpr instructions are available. Also, under VSX, you
15356 can copy vector registers from the FP register set to the Altivec register
15357 set and vice versa. */
15360 rs6000_secondary_memory_needed (enum reg_class class1,
15361 enum reg_class class2,
15362 enum machine_mode mode)
15364 if (class1 == class2)
15367 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15368 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15369 between these classes. But we need memory for other things that can go in
15370 FLOAT_REGS like SFmode. */
15372 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15373 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15374 || class1 == FLOAT_REGS))
15375 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15376 && class2 != FLOAT_REGS);
15378 if (class1 == VSX_REGS || class2 == VSX_REGS)
15381 if (class1 == FLOAT_REGS
15382 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15383 || ((mode != DFmode)
15384 && (mode != DDmode)
15385 && (mode != DImode))))
15388 if (class2 == FLOAT_REGS
15389 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15390 || ((mode != DFmode)
15391 && (mode != DDmode)
15392 && (mode != DImode))))
15395 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15401 /* Debug version of rs6000_secondary_memory_needed. */
15403 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15404 enum reg_class class2,
15405 enum machine_mode mode)
15407 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15410 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15411 "class2 = %s, mode = %s\n",
15412 ret ? "true" : "false", reg_class_names[class1],
15413 reg_class_names[class2], GET_MODE_NAME (mode));
15418 /* Return the register class of a scratch register needed to copy IN into
15419 or out of a register in RCLASS in MODE. If it can be done directly,
15420 NO_REGS is returned. */
15422 static enum reg_class
15423 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15428 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15430 && MACHOPIC_INDIRECT
15434 /* We cannot copy a symbolic operand directly into anything
15435 other than BASE_REGS for TARGET_ELF. So indicate that a
15436 register from BASE_REGS is needed as an intermediate
15439 On Darwin, pic addresses require a load from memory, which
15440 needs a base register. */
15441 if (rclass != BASE_REGS
15442 && (GET_CODE (in) == SYMBOL_REF
15443 || GET_CODE (in) == HIGH
15444 || GET_CODE (in) == LABEL_REF
15445 || GET_CODE (in) == CONST))
15449 if (GET_CODE (in) == REG)
15451 regno = REGNO (in);
15452 if (regno >= FIRST_PSEUDO_REGISTER)
15454 regno = true_regnum (in);
15455 if (regno >= FIRST_PSEUDO_REGISTER)
15459 else if (GET_CODE (in) == SUBREG)
15461 regno = true_regnum (in);
15462 if (regno >= FIRST_PSEUDO_REGISTER)
15468 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15470 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15471 || (regno >= 0 && INT_REGNO_P (regno)))
15474 /* Constants, memory, and FP registers can go into FP registers. */
15475 if ((regno == -1 || FP_REGNO_P (regno))
15476 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15477 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15479 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15482 && (regno == -1 || VSX_REGNO_P (regno))
15483 && VSX_REG_CLASS_P (rclass))
15486 /* Memory, and AltiVec registers can go into AltiVec registers. */
15487 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15488 && rclass == ALTIVEC_REGS)
15491 /* We can copy among the CR registers. */
15492 if ((rclass == CR_REGS || rclass == CR0_REGS)
15493 && regno >= 0 && CR_REGNO_P (regno))
15496 /* Otherwise, we need GENERAL_REGS. */
15497 return GENERAL_REGS;
15500 /* Debug version of rs6000_secondary_reload_class. */
15501 static enum reg_class
15502 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15503 enum machine_mode mode, rtx in)
15505 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15507 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15508 "mode = %s, input rtx:\n",
15509 reg_class_names[ret], reg_class_names[rclass],
15510 GET_MODE_NAME (mode));
15516 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15519 rs6000_cannot_change_mode_class (enum machine_mode from,
15520 enum machine_mode to,
15521 enum reg_class rclass)
15523 unsigned from_size = GET_MODE_SIZE (from);
15524 unsigned to_size = GET_MODE_SIZE (to);
15526 if (from_size != to_size)
15528 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15529 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15530 && reg_classes_intersect_p (xclass, rclass));
15533 if (TARGET_E500_DOUBLE
15534 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15535 || (((to) == TFmode) + ((from) == TFmode)) == 1
15536 || (((to) == DDmode) + ((from) == DDmode)) == 1
15537 || (((to) == TDmode) + ((from) == TDmode)) == 1
15538 || (((to) == DImode) + ((from) == DImode)) == 1))
15541 /* Since the VSX register set includes traditional floating point registers
15542 and altivec registers, just check for the size being different instead of
15543 trying to check whether the modes are vector modes. Otherwise it won't
15544 allow say DF and DI to change classes. */
15545 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15546 return (from_size != 8 && from_size != 16);
15548 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15549 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15552 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15553 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15559 /* Debug version of rs6000_cannot_change_mode_class. */
15561 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15562 enum machine_mode to,
15563 enum reg_class rclass)
15565 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15568 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15569 "to = %s, rclass = %s\n",
15570 ret ? "true" : "false",
15571 GET_MODE_NAME (from), GET_MODE_NAME (to),
15572 reg_class_names[rclass]);
15577 /* Given a comparison operation, return the bit number in CCR to test. We
15578 know this is a valid comparison.
15580 SCC_P is 1 if this is for an scc. That means that %D will have been
15581 used instead of %C, so the bits will be in different places.
15583 Return -1 if OP isn't a valid comparison for some reason. */
15586 ccr_bit (rtx op, int scc_p)
15588 enum rtx_code code = GET_CODE (op);
15589 enum machine_mode cc_mode;
15594 if (!COMPARISON_P (op))
15597 reg = XEXP (op, 0);
15599 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15601 cc_mode = GET_MODE (reg);
15602 cc_regnum = REGNO (reg);
15603 base_bit = 4 * (cc_regnum - CR0_REGNO);
15605 validate_condition_mode (code, cc_mode);
15607 /* When generating a sCOND operation, only positive conditions are
15610 || code == EQ || code == GT || code == LT || code == UNORDERED
15611 || code == GTU || code == LTU);
15616 return scc_p ? base_bit + 3 : base_bit + 2;
15618 return base_bit + 2;
15619 case GT: case GTU: case UNLE:
15620 return base_bit + 1;
15621 case LT: case LTU: case UNGE:
15623 case ORDERED: case UNORDERED:
15624 return base_bit + 3;
15627 /* If scc, we will have done a cror to put the bit in the
15628 unordered position. So test that bit. For integer, this is ! LT
15629 unless this is an scc insn. */
15630 return scc_p ? base_bit + 3 : base_bit;
15633 return scc_p ? base_bit + 3 : base_bit + 1;
15636 gcc_unreachable ();
15640 /* Return the GOT register. */
15643 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15645 /* The second flow pass currently (June 1999) can't update
15646 regs_ever_live without disturbing other parts of the compiler, so
15647 update it here to make the prolog/epilogue code happy. */
15648 if (!can_create_pseudo_p ()
15649 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15650 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15652 crtl->uses_pic_offset_table = 1;
15654 return pic_offset_table_rtx;
15657 static rs6000_stack_t stack_info;
15659 /* Function to init struct machine_function.
15660 This will be called, via a pointer variable,
15661 from push_function_context. */
15663 static struct machine_function *
15664 rs6000_init_machine_status (void)
15666 stack_info.reload_completed = 0;
15667 return ggc_alloc_cleared_machine_function ();
15670 /* These macros test for integers and extract the low-order bits. */
15672 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15673 && GET_MODE (X) == VOIDmode)
15675 #define INT_LOWPART(X) \
15676 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15679 extract_MB (rtx op)
15682 unsigned long val = INT_LOWPART (op);
15684 /* If the high bit is zero, the value is the first 1 bit we find
15686 if ((val & 0x80000000) == 0)
15688 gcc_assert (val & 0xffffffff);
15691 while (((val <<= 1) & 0x80000000) == 0)
15696 /* If the high bit is set and the low bit is not, or the mask is all
15697 1's, the value is zero. */
15698 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15701 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15704 while (((val >>= 1) & 1) != 0)
15711 extract_ME (rtx op)
15714 unsigned long val = INT_LOWPART (op);
15716 /* If the low bit is zero, the value is the first 1 bit we find from
15718 if ((val & 1) == 0)
15720 gcc_assert (val & 0xffffffff);
15723 while (((val >>= 1) & 1) == 0)
15729 /* If the low bit is set and the high bit is not, or the mask is all
15730 1's, the value is 31. */
15731 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15734 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15737 while (((val <<= 1) & 0x80000000) != 0)
15743 /* Locate some local-dynamic symbol still in use by this function
15744 so that we can print its name in some tls_ld pattern. */
15746 static const char *
15747 rs6000_get_some_local_dynamic_name (void)
15751 if (cfun->machine->some_ld_name)
15752 return cfun->machine->some_ld_name;
15754 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15756 && for_each_rtx (&PATTERN (insn),
15757 rs6000_get_some_local_dynamic_name_1, 0))
15758 return cfun->machine->some_ld_name;
15760 gcc_unreachable ();
15763 /* Helper function for rs6000_get_some_local_dynamic_name. */
15766 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15770 if (GET_CODE (x) == SYMBOL_REF)
15772 const char *str = XSTR (x, 0);
15773 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15775 cfun->machine->some_ld_name = str;
15783 /* Write out a function code label. */
15786 rs6000_output_function_entry (FILE *file, const char *fname)
15788 if (fname[0] != '.')
15790 switch (DEFAULT_ABI)
15793 gcc_unreachable ();
15799 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15808 RS6000_OUTPUT_BASENAME (file, fname);
15811 /* Print an operand. Recognize special options, documented below. */
15814 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15815 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15817 #define SMALL_DATA_RELOC "sda21"
15818 #define SMALL_DATA_REG 0
15822 print_operand (FILE *file, rtx x, int code)
15825 unsigned HOST_WIDE_INT uval;
15830 /* Write out an instruction after the call which may be replaced
15831 with glue code by the loader. This depends on the AIX version. */
15832 asm_fprintf (file, RS6000_CALL_GLUE);
15835 /* %a is output_address. */
15838 /* If X is a constant integer whose low-order 5 bits are zero,
15839 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15840 in the AIX assembler where "sri" with a zero shift count
15841 writes a trash instruction. */
15842 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15849 /* If constant, low-order 16 bits of constant, unsigned.
15850 Otherwise, write normally. */
15852 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15854 print_operand (file, x, 0);
15858 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15859 for 64-bit mask direction. */
15860 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15863 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15867 /* X is a CR register. Print the number of the GT bit of the CR. */
15868 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15869 output_operand_lossage ("invalid %%c value");
15871 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15875 /* Like 'J' but get to the GT bit only. */
15876 gcc_assert (GET_CODE (x) == REG);
15878 /* Bit 1 is GT bit. */
15879 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15881 /* Add one for shift count in rlinm for scc. */
15882 fprintf (file, "%d", i + 1);
15886 /* X is a CR register. Print the number of the EQ bit of the CR */
15887 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15888 output_operand_lossage ("invalid %%E value");
15890 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15894 /* X is a CR register. Print the shift count needed to move it
15895 to the high-order four bits. */
15896 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15897 output_operand_lossage ("invalid %%f value");
15899 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15903 /* Similar, but print the count for the rotate in the opposite
15905 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15906 output_operand_lossage ("invalid %%F value");
15908 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15912 /* X is a constant integer. If it is negative, print "m",
15913 otherwise print "z". This is to make an aze or ame insn. */
15914 if (GET_CODE (x) != CONST_INT)
15915 output_operand_lossage ("invalid %%G value");
15916 else if (INTVAL (x) >= 0)
15923 /* If constant, output low-order five bits. Otherwise, write
15926 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15928 print_operand (file, x, 0);
15932 /* If constant, output low-order six bits. Otherwise, write
15935 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15937 print_operand (file, x, 0);
15941 /* Print `i' if this is a constant, else nothing. */
15947 /* Write the bit number in CCR for jump. */
15948 i = ccr_bit (x, 0);
15950 output_operand_lossage ("invalid %%j code");
15952 fprintf (file, "%d", i);
15956 /* Similar, but add one for shift count in rlinm for scc and pass
15957 scc flag to `ccr_bit'. */
15958 i = ccr_bit (x, 1);
15960 output_operand_lossage ("invalid %%J code");
15962 /* If we want bit 31, write a shift count of zero, not 32. */
15963 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15967 /* X must be a constant. Write the 1's complement of the
15970 output_operand_lossage ("invalid %%k value");
15972 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15976 /* X must be a symbolic constant on ELF. Write an
15977 expression suitable for an 'addi' that adds in the low 16
15978 bits of the MEM. */
15979 if (GET_CODE (x) == CONST)
15981 if (GET_CODE (XEXP (x, 0)) != PLUS
15982 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15983 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15984 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15985 output_operand_lossage ("invalid %%K value");
15987 print_operand_address (file, x);
15988 fputs ("@l", file);
15991 /* %l is output_asm_label. */
15994 /* Write second word of DImode or DFmode reference. Works on register
15995 or non-indexed memory only. */
15996 if (GET_CODE (x) == REG)
15997 fputs (reg_names[REGNO (x) + 1], file);
15998 else if (GET_CODE (x) == MEM)
16000 /* Handle possible auto-increment. Since it is pre-increment and
16001 we have already done it, we can just use an offset of word. */
16002 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16003 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16004 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16006 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16007 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16010 output_address (XEXP (adjust_address_nv (x, SImode,
16014 if (small_data_operand (x, GET_MODE (x)))
16015 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16016 reg_names[SMALL_DATA_REG]);
16021 /* MB value for a mask operand. */
16022 if (! mask_operand (x, SImode))
16023 output_operand_lossage ("invalid %%m value");
16025 fprintf (file, "%d", extract_MB (x));
16029 /* ME value for a mask operand. */
16030 if (! mask_operand (x, SImode))
16031 output_operand_lossage ("invalid %%M value");
16033 fprintf (file, "%d", extract_ME (x));
16036 /* %n outputs the negative of its operand. */
16039 /* Write the number of elements in the vector times 4. */
16040 if (GET_CODE (x) != PARALLEL)
16041 output_operand_lossage ("invalid %%N value");
16043 fprintf (file, "%d", XVECLEN (x, 0) * 4);
16047 /* Similar, but subtract 1 first. */
16048 if (GET_CODE (x) != PARALLEL)
16049 output_operand_lossage ("invalid %%O value");
16051 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
16055 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16057 || INT_LOWPART (x) < 0
16058 || (i = exact_log2 (INT_LOWPART (x))) < 0)
16059 output_operand_lossage ("invalid %%p value");
16061 fprintf (file, "%d", i);
16065 /* The operand must be an indirect memory reference. The result
16066 is the register name. */
16067 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
16068 || REGNO (XEXP (x, 0)) >= 32)
16069 output_operand_lossage ("invalid %%P value");
16071 fputs (reg_names[REGNO (XEXP (x, 0))], file);
16075 /* This outputs the logical code corresponding to a boolean
16076 expression. The expression may have one or both operands
16077 negated (if one, only the first one). For condition register
16078 logical operations, it will also treat the negated
16079 CR codes as NOTs, but not handle NOTs of them. */
16081 const char *const *t = 0;
16083 enum rtx_code code = GET_CODE (x);
16084 static const char * const tbl[3][3] = {
16085 { "and", "andc", "nor" },
16086 { "or", "orc", "nand" },
16087 { "xor", "eqv", "xor" } };
16091 else if (code == IOR)
16093 else if (code == XOR)
16096 output_operand_lossage ("invalid %%q value");
16098 if (GET_CODE (XEXP (x, 0)) != NOT)
16102 if (GET_CODE (XEXP (x, 1)) == NOT)
16120 /* X is a CR register. Print the mask for `mtcrf'. */
16121 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16122 output_operand_lossage ("invalid %%R value");
16124 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16128 /* Low 5 bits of 32 - value */
16130 output_operand_lossage ("invalid %%s value");
16132 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16136 /* PowerPC64 mask position. All 0's is excluded.
16137 CONST_INT 32-bit mask is considered sign-extended so any
16138 transition must occur within the CONST_INT, not on the boundary. */
16139 if (! mask64_operand (x, DImode))
16140 output_operand_lossage ("invalid %%S value");
16142 uval = INT_LOWPART (x);
16144 if (uval & 1) /* Clear Left */
16146 #if HOST_BITS_PER_WIDE_INT > 64
16147 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16151 else /* Clear Right */
16154 #if HOST_BITS_PER_WIDE_INT > 64
16155 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16161 gcc_assert (i >= 0);
16162 fprintf (file, "%d", i);
16166 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16167 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16169 /* Bit 3 is OV bit. */
16170 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16172 /* If we want bit 31, write a shift count of zero, not 32. */
16173 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16177 /* Print the symbolic name of a branch target register. */
16178 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16179 && REGNO (x) != CTR_REGNO))
16180 output_operand_lossage ("invalid %%T value");
16181 else if (REGNO (x) == LR_REGNO)
16182 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16184 fputs ("ctr", file);
16188 /* High-order 16 bits of constant for use in unsigned operand. */
16190 output_operand_lossage ("invalid %%u value");
16192 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16193 (INT_LOWPART (x) >> 16) & 0xffff);
16197 /* High-order 16 bits of constant for use in signed operand. */
16199 output_operand_lossage ("invalid %%v value");
16201 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16202 (INT_LOWPART (x) >> 16) & 0xffff);
16206 /* Print `u' if this has an auto-increment or auto-decrement. */
16207 if (GET_CODE (x) == MEM
16208 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16209 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16210 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16215 /* Print the trap code for this operand. */
16216 switch (GET_CODE (x))
16219 fputs ("eq", file); /* 4 */
16222 fputs ("ne", file); /* 24 */
16225 fputs ("lt", file); /* 16 */
16228 fputs ("le", file); /* 20 */
16231 fputs ("gt", file); /* 8 */
16234 fputs ("ge", file); /* 12 */
16237 fputs ("llt", file); /* 2 */
16240 fputs ("lle", file); /* 6 */
16243 fputs ("lgt", file); /* 1 */
16246 fputs ("lge", file); /* 5 */
16249 gcc_unreachable ();
16254 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16257 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16258 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16260 print_operand (file, x, 0);
16264 /* MB value for a PowerPC64 rldic operand. */
16265 i = clz_hwi (GET_CODE (x) == CONST_INT
16266 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16268 #if HOST_BITS_PER_WIDE_INT == 32
16269 if (GET_CODE (x) == CONST_INT && i > 0)
16270 i += 32; /* zero-extend high-part was all 0's */
16271 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16272 i = clz_hwi (CONST_DOUBLE_LOW (x)) + 32;
16275 fprintf (file, "%d", i);
16279 /* X is a FPR or Altivec register used in a VSX context. */
16280 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16281 output_operand_lossage ("invalid %%x value");
16284 int reg = REGNO (x);
16285 int vsx_reg = (FP_REGNO_P (reg)
16287 : reg - FIRST_ALTIVEC_REGNO + 32);
16289 #ifdef TARGET_REGNAMES
16290 if (TARGET_REGNAMES)
16291 fprintf (file, "%%vs%d", vsx_reg);
16294 fprintf (file, "%d", vsx_reg);
16299 if (GET_CODE (x) == MEM
16300 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16301 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16302 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16307 /* Like 'L', for third word of TImode */
16308 if (GET_CODE (x) == REG)
16309 fputs (reg_names[REGNO (x) + 2], file);
16310 else if (GET_CODE (x) == MEM)
16312 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16313 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16314 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16315 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16316 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16318 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16319 if (small_data_operand (x, GET_MODE (x)))
16320 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16321 reg_names[SMALL_DATA_REG]);
16326 /* X is a SYMBOL_REF. Write out the name preceded by a
16327 period and without any trailing data in brackets. Used for function
16328 names. If we are configured for System V (or the embedded ABI) on
16329 the PowerPC, do not emit the period, since those systems do not use
16330 TOCs and the like. */
16331 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16333 /* Mark the decl as referenced so that cgraph will output the
16335 if (SYMBOL_REF_DECL (x))
16336 mark_decl_referenced (SYMBOL_REF_DECL (x));
16338 /* For macho, check to see if we need a stub. */
16341 const char *name = XSTR (x, 0);
16343 if (darwin_emit_branch_islands
16344 && MACHOPIC_INDIRECT
16345 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16346 name = machopic_indirection_name (x, /*stub_p=*/true);
16348 assemble_name (file, name);
16350 else if (!DOT_SYMBOLS)
16351 assemble_name (file, XSTR (x, 0));
16353 rs6000_output_function_entry (file, XSTR (x, 0));
16357 /* Like 'L', for last word of TImode. */
16358 if (GET_CODE (x) == REG)
16359 fputs (reg_names[REGNO (x) + 3], file);
16360 else if (GET_CODE (x) == MEM)
16362 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16363 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16364 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16365 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16366 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16368 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16369 if (small_data_operand (x, GET_MODE (x)))
16370 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16371 reg_names[SMALL_DATA_REG]);
16375 /* Print AltiVec or SPE memory operand. */
16380 gcc_assert (GET_CODE (x) == MEM);
16384 /* Ugly hack because %y is overloaded. */
16385 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16386 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16387 || GET_MODE (x) == TFmode
16388 || GET_MODE (x) == TImode))
16390 /* Handle [reg]. */
16391 if (GET_CODE (tmp) == REG)
16393 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16396 /* Handle [reg+UIMM]. */
16397 else if (GET_CODE (tmp) == PLUS &&
16398 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16402 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16404 x = INTVAL (XEXP (tmp, 1));
16405 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16409 /* Fall through. Must be [reg+reg]. */
16411 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16412 && GET_CODE (tmp) == AND
16413 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16414 && INTVAL (XEXP (tmp, 1)) == -16)
16415 tmp = XEXP (tmp, 0);
16416 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16417 && GET_CODE (tmp) == PRE_MODIFY)
16418 tmp = XEXP (tmp, 1);
16419 if (GET_CODE (tmp) == REG)
16420 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16423 if (!GET_CODE (tmp) == PLUS
16424 || !REG_P (XEXP (tmp, 0))
16425 || !REG_P (XEXP (tmp, 1)))
16427 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16431 if (REGNO (XEXP (tmp, 0)) == 0)
16432 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16433 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16435 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16436 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16442 if (GET_CODE (x) == REG)
16443 fprintf (file, "%s", reg_names[REGNO (x)]);
16444 else if (GET_CODE (x) == MEM)
16446 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16447 know the width from the mode. */
16448 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16449 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16450 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16451 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16452 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16453 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16454 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16455 output_address (XEXP (XEXP (x, 0), 1));
16457 output_address (XEXP (x, 0));
16461 if (toc_relative_expr_p (x))
16462 /* This hack along with a corresponding hack in
16463 rs6000_output_addr_const_extra arranges to output addends
16464 where the assembler expects to find them. eg.
16465 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16466 without this hack would be output as "x@toc+4". We
16468 output_addr_const (file, tocrel_base);
16470 output_addr_const (file, x);
16475 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16479 output_operand_lossage ("invalid %%xn code");
16483 /* Print the address of an operand. */
16486 print_operand_address (FILE *file, rtx x)
16488 if (GET_CODE (x) == REG)
16489 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16490 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16491 || GET_CODE (x) == LABEL_REF)
16493 output_addr_const (file, x);
16494 if (small_data_operand (x, GET_MODE (x)))
16495 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16496 reg_names[SMALL_DATA_REG]);
16498 gcc_assert (!TARGET_TOC);
16500 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16502 gcc_assert (REG_P (XEXP (x, 0)));
16503 if (REGNO (XEXP (x, 0)) == 0)
16504 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16505 reg_names[ REGNO (XEXP (x, 0)) ]);
16507 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16508 reg_names[ REGNO (XEXP (x, 1)) ]);
16510 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16511 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16512 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16514 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16515 && CONSTANT_P (XEXP (x, 1)))
16517 fprintf (file, "lo16(");
16518 output_addr_const (file, XEXP (x, 1));
16519 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16522 else if (legitimate_constant_pool_address_p (x, QImode, true))
16524 /* This hack along with a corresponding hack in
16525 rs6000_output_addr_const_extra arranges to output addends
16526 where the assembler expects to find them. eg.
16528 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16529 without this hack would be output as "x@toc+8@l(9)". We
16530 want "x+8@toc@l(9)". */
16531 output_addr_const (file, tocrel_base);
16532 if (GET_CODE (x) == LO_SUM)
16533 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16535 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16538 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16539 && CONSTANT_P (XEXP (x, 1)))
16541 output_addr_const (file, XEXP (x, 1));
16542 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16546 gcc_unreachable ();
16549 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16552 rs6000_output_addr_const_extra (FILE *file, rtx x)
16554 if (GET_CODE (x) == UNSPEC)
16555 switch (XINT (x, 1))
16557 case UNSPEC_TOCREL:
16558 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16559 output_addr_const (file, XVECEXP (x, 0, 0));
16560 if (x == tocrel_base && tocrel_offset != const0_rtx)
16562 if (INTVAL (tocrel_offset) >= 0)
16563 fprintf (file, "+");
16564 output_addr_const (file, tocrel_offset);
16566 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16569 assemble_name (file, toc_label_name);
16571 else if (TARGET_ELF)
16572 fputs ("@toc", file);
16576 case UNSPEC_MACHOPIC_OFFSET:
16577 output_addr_const (file, XVECEXP (x, 0, 0));
16579 machopic_output_function_base_name (file);
16586 /* Target hook for assembling integer objects. The PowerPC version has
16587 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16588 is defined. It also needs to handle DI-mode objects on 64-bit
16592 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16594 #ifdef RELOCATABLE_NEEDS_FIXUP
16595 /* Special handling for SI values. */
16596 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16598 static int recurse = 0;
16600 /* For -mrelocatable, we mark all addresses that need to be fixed up
16601 in the .fixup section. */
16602 if (TARGET_RELOCATABLE
16603 && in_section != toc_section
16604 && in_section != text_section
16605 && (in_section && (in_section->common.flags & SECTION_CODE)) == 0
16607 && GET_CODE (x) != CONST_INT
16608 && GET_CODE (x) != CONST_DOUBLE
16614 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16616 ASM_OUTPUT_LABEL (asm_out_file, buf);
16617 fprintf (asm_out_file, "\t.long\t(");
16618 output_addr_const (asm_out_file, x);
16619 fprintf (asm_out_file, ")@fixup\n");
16620 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16621 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16622 fprintf (asm_out_file, "\t.long\t");
16623 assemble_name (asm_out_file, buf);
16624 fprintf (asm_out_file, "\n\t.previous\n");
16628 /* Remove initial .'s to turn a -mcall-aixdesc function
16629 address into the address of the descriptor, not the function
16631 else if (GET_CODE (x) == SYMBOL_REF
16632 && XSTR (x, 0)[0] == '.'
16633 && DEFAULT_ABI == ABI_AIX)
16635 const char *name = XSTR (x, 0);
16636 while (*name == '.')
16639 fprintf (asm_out_file, "\t.long\t%s\n", name);
16643 #endif /* RELOCATABLE_NEEDS_FIXUP */
16644 return default_assemble_integer (x, size, aligned_p);
16647 #ifdef HAVE_GAS_HIDDEN
16648 /* Emit an assembler directive to set symbol visibility for DECL to
16649 VISIBILITY_TYPE. */
16652 rs6000_assemble_visibility (tree decl, int vis)
16654 /* Functions need to have their entry point symbol visibility set as
16655 well as their descriptor symbol visibility. */
16656 if (DEFAULT_ABI == ABI_AIX
16658 && TREE_CODE (decl) == FUNCTION_DECL)
16660 static const char * const visibility_types[] = {
16661 NULL, "internal", "hidden", "protected"
16664 const char *name, *type;
16666 name = ((* targetm.strip_name_encoding)
16667 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16668 type = visibility_types[vis];
16670 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16671 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16674 default_assemble_visibility (decl, vis);
16679 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16681 /* Reversal of FP compares takes care -- an ordered compare
16682 becomes an unordered compare and vice versa. */
16683 if (mode == CCFPmode
16684 && (!flag_finite_math_only
16685 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16686 || code == UNEQ || code == LTGT))
16687 return reverse_condition_maybe_unordered (code);
16689 return reverse_condition (code);
16692 /* Generate a compare for CODE. Return a brand-new rtx that
16693 represents the result of the compare. */
16696 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16698 enum machine_mode comp_mode;
16699 rtx compare_result;
16700 enum rtx_code code = GET_CODE (cmp);
16701 rtx op0 = XEXP (cmp, 0);
16702 rtx op1 = XEXP (cmp, 1);
16704 if (FLOAT_MODE_P (mode))
16705 comp_mode = CCFPmode;
16706 else if (code == GTU || code == LTU
16707 || code == GEU || code == LEU)
16708 comp_mode = CCUNSmode;
16709 else if ((code == EQ || code == NE)
16710 && GET_CODE (op0) == SUBREG
16711 && GET_CODE (op1) == SUBREG
16712 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16713 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16714 /* These are unsigned values, perhaps there will be a later
16715 ordering compare that can be shared with this one.
16716 Unfortunately we cannot detect the signedness of the operands
16717 for non-subregs. */
16718 comp_mode = CCUNSmode;
16720 comp_mode = CCmode;
16722 /* First, the compare. */
16723 compare_result = gen_reg_rtx (comp_mode);
16725 /* E500 FP compare instructions on the GPRs. Yuck! */
16726 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16727 && FLOAT_MODE_P (mode))
16729 rtx cmp, or_result, compare_result2;
16730 enum machine_mode op_mode = GET_MODE (op0);
16732 if (op_mode == VOIDmode)
16733 op_mode = GET_MODE (op1);
16735 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16736 This explains the following mess. */
16740 case EQ: case UNEQ: case NE: case LTGT:
16744 cmp = (flag_finite_math_only && !flag_trapping_math)
16745 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16746 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16750 cmp = (flag_finite_math_only && !flag_trapping_math)
16751 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16752 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16756 cmp = (flag_finite_math_only && !flag_trapping_math)
16757 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16758 : gen_cmptfeq_gpr (compare_result, op0, op1);
16762 gcc_unreachable ();
16766 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16770 cmp = (flag_finite_math_only && !flag_trapping_math)
16771 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16772 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16776 cmp = (flag_finite_math_only && !flag_trapping_math)
16777 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16778 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16782 cmp = (flag_finite_math_only && !flag_trapping_math)
16783 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16784 : gen_cmptfgt_gpr (compare_result, op0, op1);
16788 gcc_unreachable ();
16792 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16796 cmp = (flag_finite_math_only && !flag_trapping_math)
16797 ? gen_tstsflt_gpr (compare_result, op0, op1)
16798 : gen_cmpsflt_gpr (compare_result, op0, op1);
16802 cmp = (flag_finite_math_only && !flag_trapping_math)
16803 ? gen_tstdflt_gpr (compare_result, op0, op1)
16804 : gen_cmpdflt_gpr (compare_result, op0, op1);
16808 cmp = (flag_finite_math_only && !flag_trapping_math)
16809 ? gen_tsttflt_gpr (compare_result, op0, op1)
16810 : gen_cmptflt_gpr (compare_result, op0, op1);
16814 gcc_unreachable ();
16818 gcc_unreachable ();
16821 /* Synthesize LE and GE from LT/GT || EQ. */
16822 if (code == LE || code == GE || code == LEU || code == GEU)
16828 case LE: code = LT; break;
16829 case GE: code = GT; break;
16830 case LEU: code = LT; break;
16831 case GEU: code = GT; break;
16832 default: gcc_unreachable ();
16835 compare_result2 = gen_reg_rtx (CCFPmode);
16841 cmp = (flag_finite_math_only && !flag_trapping_math)
16842 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16843 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16847 cmp = (flag_finite_math_only && !flag_trapping_math)
16848 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16849 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16853 cmp = (flag_finite_math_only && !flag_trapping_math)
16854 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16855 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16859 gcc_unreachable ();
16863 /* OR them together. */
16864 or_result = gen_reg_rtx (CCFPmode);
16865 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16867 compare_result = or_result;
16872 if (code == NE || code == LTGT)
16882 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16883 CLOBBERs to match cmptf_internal2 pattern. */
16884 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16885 && GET_MODE (op0) == TFmode
16886 && !TARGET_IEEEQUAD
16887 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16888 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16890 gen_rtx_SET (VOIDmode,
16892 gen_rtx_COMPARE (comp_mode, op0, op1)),
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 (DFmode)),
16901 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16902 else if (GET_CODE (op1) == UNSPEC
16903 && XINT (op1, 1) == UNSPEC_SP_TEST)
16905 rtx op1b = XVECEXP (op1, 0, 0);
16906 comp_mode = CCEQmode;
16907 compare_result = gen_reg_rtx (CCEQmode);
16909 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16911 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16914 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16915 gen_rtx_COMPARE (comp_mode, op0, op1)));
16918 /* Some kinds of FP comparisons need an OR operation;
16919 under flag_finite_math_only we don't bother. */
16920 if (FLOAT_MODE_P (mode)
16921 && !flag_finite_math_only
16922 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16923 && (code == LE || code == GE
16924 || code == UNEQ || code == LTGT
16925 || code == UNGT || code == UNLT))
16927 enum rtx_code or1, or2;
16928 rtx or1_rtx, or2_rtx, compare2_rtx;
16929 rtx or_result = gen_reg_rtx (CCEQmode);
16933 case LE: or1 = LT; or2 = EQ; break;
16934 case GE: or1 = GT; or2 = EQ; break;
16935 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16936 case LTGT: or1 = LT; or2 = GT; break;
16937 case UNGT: or1 = UNORDERED; or2 = GT; break;
16938 case UNLT: or1 = UNORDERED; or2 = LT; break;
16939 default: gcc_unreachable ();
16941 validate_condition_mode (or1, comp_mode);
16942 validate_condition_mode (or2, comp_mode);
16943 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16944 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16945 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16946 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16948 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16950 compare_result = or_result;
16954 validate_condition_mode (code, GET_MODE (compare_result));
16956 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16960 /* Emit the RTL for an sISEL pattern. */
16963 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16965 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16969 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16972 enum machine_mode op_mode;
16973 enum rtx_code cond_code;
16974 rtx result = operands[0];
16976 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16978 rs6000_emit_sISEL (mode, operands);
16982 condition_rtx = rs6000_generate_compare (operands[1], mode);
16983 cond_code = GET_CODE (condition_rtx);
16985 if (FLOAT_MODE_P (mode)
16986 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16990 PUT_MODE (condition_rtx, SImode);
16991 t = XEXP (condition_rtx, 0);
16993 gcc_assert (cond_code == NE || cond_code == EQ);
16995 if (cond_code == NE)
16996 emit_insn (gen_e500_flip_gt_bit (t, t));
16998 emit_insn (gen_move_from_CR_gt_bit (result, t));
17002 if (cond_code == NE
17003 || cond_code == GE || cond_code == LE
17004 || cond_code == GEU || cond_code == LEU
17005 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
17007 rtx not_result = gen_reg_rtx (CCEQmode);
17008 rtx not_op, rev_cond_rtx;
17009 enum machine_mode cc_mode;
17011 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
17013 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
17014 SImode, XEXP (condition_rtx, 0), const0_rtx);
17015 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
17016 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
17017 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
17020 op_mode = GET_MODE (XEXP (operands[1], 0));
17021 if (op_mode == VOIDmode)
17022 op_mode = GET_MODE (XEXP (operands[1], 1));
17024 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
17026 PUT_MODE (condition_rtx, DImode);
17027 convert_move (result, condition_rtx, 0);
17031 PUT_MODE (condition_rtx, SImode);
17032 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
17036 /* Emit a branch of kind CODE to location LOC. */
17039 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
17041 rtx condition_rtx, loc_ref;
17043 condition_rtx = rs6000_generate_compare (operands[0], mode);
17044 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
17045 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
17046 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
17047 loc_ref, pc_rtx)));
17050 /* Return the string to output a conditional branch to LABEL, which is
17051 the operand number of the label, or -1 if the branch is really a
17052 conditional return.
17054 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17055 condition code register and its mode specifies what kind of
17056 comparison we made.
17058 REVERSED is nonzero if we should reverse the sense of the comparison.
17060 INSN is the insn. */
17063 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
17065 static char string[64];
17066 enum rtx_code code = GET_CODE (op);
17067 rtx cc_reg = XEXP (op, 0);
17068 enum machine_mode mode = GET_MODE (cc_reg);
17069 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
17070 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
17071 int really_reversed = reversed ^ need_longbranch;
17077 validate_condition_mode (code, mode);
17079 /* Work out which way this really branches. We could use
17080 reverse_condition_maybe_unordered here always but this
17081 makes the resulting assembler clearer. */
17082 if (really_reversed)
17084 /* Reversal of FP compares takes care -- an ordered compare
17085 becomes an unordered compare and vice versa. */
17086 if (mode == CCFPmode)
17087 code = reverse_condition_maybe_unordered (code);
17089 code = reverse_condition (code);
17092 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17094 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17099 /* Opposite of GT. */
17108 gcc_unreachable ();
17114 /* Not all of these are actually distinct opcodes, but
17115 we distinguish them for clarity of the resulting assembler. */
17116 case NE: case LTGT:
17117 ccode = "ne"; break;
17118 case EQ: case UNEQ:
17119 ccode = "eq"; break;
17121 ccode = "ge"; break;
17122 case GT: case GTU: case UNGT:
17123 ccode = "gt"; break;
17125 ccode = "le"; break;
17126 case LT: case LTU: case UNLT:
17127 ccode = "lt"; break;
17128 case UNORDERED: ccode = "un"; break;
17129 case ORDERED: ccode = "nu"; break;
17130 case UNGE: ccode = "nl"; break;
17131 case UNLE: ccode = "ng"; break;
17133 gcc_unreachable ();
17136 /* Maybe we have a guess as to how likely the branch is.
17137 The old mnemonics don't have a way to specify this information. */
17139 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17140 if (note != NULL_RTX)
17142 /* PROB is the difference from 50%. */
17143 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17145 /* Only hint for highly probable/improbable branches on newer
17146 cpus as static prediction overrides processor dynamic
17147 prediction. For older cpus we may as well always hint, but
17148 assume not taken for branches that are very close to 50% as a
17149 mispredicted taken branch is more expensive than a
17150 mispredicted not-taken branch. */
17151 if (rs6000_always_hint
17152 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17153 && br_prob_note_reliable_p (note)))
17155 if (abs (prob) > REG_BR_PROB_BASE / 20
17156 && ((prob > 0) ^ need_longbranch))
17164 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17166 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17168 /* We need to escape any '%' characters in the reg_names string.
17169 Assume they'd only be the first character.... */
17170 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17172 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17176 /* If the branch distance was too far, we may have to use an
17177 unconditional branch to go the distance. */
17178 if (need_longbranch)
17179 s += sprintf (s, ",$+8\n\tb %s", label);
17181 s += sprintf (s, ",%s", label);
17187 /* Return the string to flip the GT bit on a CR. */
17189 output_e500_flip_gt_bit (rtx dst, rtx src)
17191 static char string[64];
17194 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17195 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17198 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17199 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17201 sprintf (string, "crnot %d,%d", a, b);
17205 /* Return insn for VSX or Altivec comparisons. */
17208 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17211 enum machine_mode mode = GET_MODE (op0);
17219 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17229 mask = gen_reg_rtx (mode);
17230 emit_insn (gen_rtx_SET (VOIDmode,
17232 gen_rtx_fmt_ee (code, mode, op0, op1)));
17239 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17240 DMODE is expected destination mode. This is a recursive function. */
17243 rs6000_emit_vector_compare (enum rtx_code rcode,
17245 enum machine_mode dmode)
17248 bool swap_operands = false;
17249 bool try_again = false;
17251 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17252 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17254 /* See if the comparison works as is. */
17255 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17263 swap_operands = true;
17268 swap_operands = true;
17276 /* Invert condition and try again.
17277 e.g., A != B becomes ~(A==B). */
17279 enum rtx_code rev_code;
17280 enum insn_code nor_code;
17283 rev_code = reverse_condition_maybe_unordered (rcode);
17284 if (rev_code == UNKNOWN)
17287 nor_code = optab_handler (one_cmpl_optab, dmode);
17288 if (nor_code == CODE_FOR_nothing)
17291 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17295 mask = gen_reg_rtx (dmode);
17296 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17304 /* Try GT/GTU/LT/LTU OR EQ */
17307 enum insn_code ior_code;
17308 enum rtx_code new_code;
17329 gcc_unreachable ();
17332 ior_code = optab_handler (ior_optab, dmode);
17333 if (ior_code == CODE_FOR_nothing)
17336 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17340 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17344 mask = gen_reg_rtx (dmode);
17345 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17363 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17368 /* You only get two chances. */
17372 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17373 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17374 operands for the relation operation COND. */
17377 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17378 rtx cond, rtx cc_op0, rtx cc_op1)
17380 enum machine_mode dest_mode = GET_MODE (dest);
17381 enum rtx_code rcode = GET_CODE (cond);
17382 enum machine_mode cc_mode = CCmode;
17386 bool invert_move = false;
17388 if (VECTOR_UNIT_NONE_P (dest_mode))
17393 /* Swap operands if we can, and fall back to doing the operation as
17394 specified, and doing a NOR to invert the test. */
17400 /* Invert condition and try again.
17401 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17402 invert_move = true;
17403 rcode = reverse_condition_maybe_unordered (rcode);
17404 if (rcode == UNKNOWN)
17408 /* Mark unsigned tests with CCUNSmode. */
17413 cc_mode = CCUNSmode;
17420 /* Get the vector mask for the given relational operations. */
17421 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17429 op_true = op_false;
17433 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, CONST0_RTX (dest_mode));
17434 emit_insn (gen_rtx_SET (VOIDmode,
17436 gen_rtx_IF_THEN_ELSE (dest_mode,
17443 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17444 operands of the last comparison is nonzero/true, FALSE_COND if it
17445 is zero/false. Return 0 if the hardware has no such operation. */
17448 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17450 enum rtx_code code = GET_CODE (op);
17451 rtx op0 = XEXP (op, 0);
17452 rtx op1 = XEXP (op, 1);
17453 REAL_VALUE_TYPE c1;
17454 enum machine_mode compare_mode = GET_MODE (op0);
17455 enum machine_mode result_mode = GET_MODE (dest);
17457 bool is_against_zero;
17459 /* These modes should always match. */
17460 if (GET_MODE (op1) != compare_mode
17461 /* In the isel case however, we can use a compare immediate, so
17462 op1 may be a small constant. */
17463 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17465 if (GET_MODE (true_cond) != result_mode)
17467 if (GET_MODE (false_cond) != result_mode)
17470 /* First, work out if the hardware can do this at all, or
17471 if it's too slow.... */
17472 if (!FLOAT_MODE_P (compare_mode))
17475 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17478 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17479 && SCALAR_FLOAT_MODE_P (compare_mode))
17482 is_against_zero = op1 == CONST0_RTX (compare_mode);
17484 /* A floating-point subtract might overflow, underflow, or produce
17485 an inexact result, thus changing the floating-point flags, so it
17486 can't be generated if we care about that. It's safe if one side
17487 of the construct is zero, since then no subtract will be
17489 if (SCALAR_FLOAT_MODE_P (compare_mode)
17490 && flag_trapping_math && ! is_against_zero)
17493 /* Eliminate half of the comparisons by switching operands, this
17494 makes the remaining code simpler. */
17495 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17496 || code == LTGT || code == LT || code == UNLE)
17498 code = reverse_condition_maybe_unordered (code);
17500 true_cond = false_cond;
17504 /* UNEQ and LTGT take four instructions for a comparison with zero,
17505 it'll probably be faster to use a branch here too. */
17506 if (code == UNEQ && HONOR_NANS (compare_mode))
17509 if (GET_CODE (op1) == CONST_DOUBLE)
17510 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17512 /* We're going to try to implement comparisons by performing
17513 a subtract, then comparing against zero. Unfortunately,
17514 Inf - Inf is NaN which is not zero, and so if we don't
17515 know that the operand is finite and the comparison
17516 would treat EQ different to UNORDERED, we can't do it. */
17517 if (HONOR_INFINITIES (compare_mode)
17518 && code != GT && code != UNGE
17519 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17520 /* Constructs of the form (a OP b ? a : b) are safe. */
17521 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17522 || (! rtx_equal_p (op0, true_cond)
17523 && ! rtx_equal_p (op1, true_cond))))
17526 /* At this point we know we can use fsel. */
17528 /* Reduce the comparison to a comparison against zero. */
17529 if (! is_against_zero)
17531 temp = gen_reg_rtx (compare_mode);
17532 emit_insn (gen_rtx_SET (VOIDmode, temp,
17533 gen_rtx_MINUS (compare_mode, op0, op1)));
17535 op1 = CONST0_RTX (compare_mode);
17538 /* If we don't care about NaNs we can reduce some of the comparisons
17539 down to faster ones. */
17540 if (! HONOR_NANS (compare_mode))
17546 true_cond = false_cond;
17559 /* Now, reduce everything down to a GE. */
17566 temp = gen_reg_rtx (compare_mode);
17567 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17572 temp = gen_reg_rtx (compare_mode);
17573 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17578 temp = gen_reg_rtx (compare_mode);
17579 emit_insn (gen_rtx_SET (VOIDmode, temp,
17580 gen_rtx_NEG (compare_mode,
17581 gen_rtx_ABS (compare_mode, op0))));
17586 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17587 temp = gen_reg_rtx (result_mode);
17588 emit_insn (gen_rtx_SET (VOIDmode, temp,
17589 gen_rtx_IF_THEN_ELSE (result_mode,
17590 gen_rtx_GE (VOIDmode,
17592 true_cond, false_cond)));
17593 false_cond = true_cond;
17596 temp = gen_reg_rtx (compare_mode);
17597 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17602 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17603 temp = gen_reg_rtx (result_mode);
17604 emit_insn (gen_rtx_SET (VOIDmode, temp,
17605 gen_rtx_IF_THEN_ELSE (result_mode,
17606 gen_rtx_GE (VOIDmode,
17608 true_cond, false_cond)));
17609 true_cond = false_cond;
17612 temp = gen_reg_rtx (compare_mode);
17613 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17618 gcc_unreachable ();
17621 emit_insn (gen_rtx_SET (VOIDmode, dest,
17622 gen_rtx_IF_THEN_ELSE (result_mode,
17623 gen_rtx_GE (VOIDmode,
17625 true_cond, false_cond)));
17629 /* Same as above, but for ints (isel). */
17632 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17634 rtx condition_rtx, cr;
17635 enum machine_mode mode = GET_MODE (dest);
17636 enum rtx_code cond_code;
17637 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17640 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17643 /* We still have to do the compare, because isel doesn't do a
17644 compare, it just looks at the CRx bits set by a previous compare
17646 condition_rtx = rs6000_generate_compare (op, mode);
17647 cond_code = GET_CODE (condition_rtx);
17648 cr = XEXP (condition_rtx, 0);
17649 signedp = GET_MODE (cr) == CCmode;
17651 isel_func = (mode == SImode
17652 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17653 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17657 case LT: case GT: case LTU: case GTU: case EQ:
17658 /* isel handles these directly. */
17662 /* We need to swap the sense of the comparison. */
17665 true_cond = false_cond;
17667 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17672 false_cond = force_reg (mode, false_cond);
17673 if (true_cond != const0_rtx)
17674 true_cond = force_reg (mode, true_cond);
17676 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17682 output_isel (rtx *operands)
17684 enum rtx_code code;
17686 code = GET_CODE (operands[1]);
17688 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17690 gcc_assert (GET_CODE (operands[2]) == REG
17691 && GET_CODE (operands[3]) == REG);
17692 PUT_CODE (operands[1], reverse_condition (code));
17693 return "isel %0,%3,%2,%j1";
17696 return "isel %0,%2,%3,%j1";
17700 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17702 enum machine_mode mode = GET_MODE (op0);
17706 /* VSX/altivec have direct min/max insns. */
17707 if ((code == SMAX || code == SMIN)
17708 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17709 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17711 emit_insn (gen_rtx_SET (VOIDmode,
17713 gen_rtx_fmt_ee (code, mode, op0, op1)));
17717 if (code == SMAX || code == SMIN)
17722 if (code == SMAX || code == UMAX)
17723 target = emit_conditional_move (dest, c, op0, op1, mode,
17724 op0, op1, mode, 0);
17726 target = emit_conditional_move (dest, c, op0, op1, mode,
17727 op1, op0, mode, 0);
17728 gcc_assert (target);
17729 if (target != dest)
17730 emit_move_insn (dest, target);
17733 /* Emit instructions to perform a load-reserved/store-conditional operation.
17734 The operation performed is an atomic
17735 (set M (CODE:MODE M OP))
17736 If not NULL, BEFORE is atomically set to M before the operation, and
17737 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17738 If SYNC_P then a memory barrier is emitted before the operation.
17739 Either OP or M may be wrapped in a NOT operation. */
17742 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17743 rtx m, rtx op, rtx before_param, rtx after_param,
17746 enum machine_mode used_mode;
17747 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17750 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17751 rtx shift = NULL_RTX;
17754 emit_insn (gen_lwsync ());
17758 /* If this is smaller than SImode, we'll have to use SImode with
17760 if (mode == QImode || mode == HImode)
17764 if (MEM_ALIGN (used_m) >= 32)
17767 if (BYTES_BIG_ENDIAN)
17768 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17770 shift = GEN_INT (ishift);
17771 used_m = change_address (used_m, SImode, 0);
17775 rtx addrSI, aligned_addr;
17776 int shift_mask = mode == QImode ? 0x18 : 0x10;
17778 addrSI = gen_lowpart_common (SImode,
17779 force_reg (Pmode, XEXP (used_m, 0)));
17780 addrSI = force_reg (SImode, addrSI);
17781 shift = gen_reg_rtx (SImode);
17783 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17784 GEN_INT (shift_mask)));
17785 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17787 aligned_addr = expand_binop (Pmode, and_optab,
17789 GEN_INT (-4), NULL_RTX,
17790 1, OPTAB_LIB_WIDEN);
17791 used_m = change_address (used_m, SImode, aligned_addr);
17792 set_mem_align (used_m, 32);
17794 /* It's safe to keep the old alias set of USED_M, because
17795 the operation is atomic and only affects the original
17799 if (GET_CODE (op) == NOT)
17801 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17802 oldop = gen_rtx_NOT (SImode, oldop);
17805 oldop = lowpart_subreg (SImode, op, mode);
17811 newop = expand_binop (SImode, and_optab,
17812 oldop, GEN_INT (imask), NULL_RTX,
17813 1, OPTAB_LIB_WIDEN);
17814 emit_insn (gen_ashlsi3 (newop, newop, shift));
17817 case NOT: /* NAND */
17818 newop = expand_binop (SImode, ior_optab,
17819 oldop, GEN_INT (~imask), NULL_RTX,
17820 1, OPTAB_LIB_WIDEN);
17821 emit_insn (gen_rotlsi3 (newop, newop, shift));
17825 newop = expand_binop (SImode, ior_optab,
17826 oldop, GEN_INT (~imask), NULL_RTX,
17827 1, OPTAB_LIB_WIDEN);
17828 emit_insn (gen_rotlsi3 (newop, newop, shift));
17836 newop = expand_binop (SImode, and_optab,
17837 oldop, GEN_INT (imask), NULL_RTX,
17838 1, OPTAB_LIB_WIDEN);
17839 emit_insn (gen_ashlsi3 (newop, newop, shift));
17841 mask = gen_reg_rtx (SImode);
17842 emit_move_insn (mask, GEN_INT (imask));
17843 emit_insn (gen_ashlsi3 (mask, mask, shift));
17846 newop = gen_rtx_PLUS (SImode, m, newop);
17848 newop = gen_rtx_MINUS (SImode, m, newop);
17849 newop = gen_rtx_AND (SImode, newop, mask);
17850 newop = gen_rtx_IOR (SImode, newop,
17851 gen_rtx_AND (SImode,
17852 gen_rtx_NOT (SImode, mask),
17858 gcc_unreachable ();
17862 used_mode = SImode;
17863 before = gen_reg_rtx (used_mode);
17864 after = gen_reg_rtx (used_mode);
17869 before = before_param;
17870 after = after_param;
17872 if (before == NULL_RTX)
17873 before = gen_reg_rtx (used_mode);
17874 if (after == NULL_RTX)
17875 after = gen_reg_rtx (used_mode);
17878 if ((code == PLUS || code == MINUS)
17879 && used_mode != mode)
17880 the_op = op; /* Computed above. */
17881 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17882 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17883 else if (code == NOT)
17884 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17885 gen_rtx_NOT (used_mode, m),
17886 gen_rtx_NOT (used_mode, op));
17888 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17890 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17891 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17892 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17893 gen_rtx_UNSPEC (used_mode,
17894 gen_rtvec (1, the_op),
17896 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17898 if ((code == PLUS || code == MINUS) && used_mode != mode)
17899 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17900 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17902 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17903 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17905 /* Shift and mask the return values properly. */
17906 if (used_mode != mode && before_param)
17908 emit_insn (gen_lshrsi3 (before, before, shift));
17909 convert_move (before_param, before, 1);
17912 if (used_mode != mode && after_param)
17914 emit_insn (gen_lshrsi3 (after, after, shift));
17915 convert_move (after_param, after, 1);
17918 /* The previous sequence will end with a branch that's dependent on
17919 the conditional store, so placing an isync will ensure that no
17920 other instructions (especially, no load or store instructions)
17921 can start before the atomic operation completes. */
17923 emit_insn (gen_isync ());
17926 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17927 COND is true. Mark the jump as unlikely to be taken. */
17930 emit_unlikely_jump (rtx cond, rtx label)
17932 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17935 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17936 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17937 add_reg_note (x, REG_BR_PROB, very_unlikely);
17940 /* A subroutine of the atomic operation splitters. Emit a load-locked
17941 instruction in MODE. */
17944 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17946 rtx (*fn) (rtx, rtx) = NULL;
17947 if (mode == SImode)
17948 fn = gen_load_locked_si;
17949 else if (mode == DImode)
17950 fn = gen_load_locked_di;
17951 emit_insn (fn (reg, mem));
17954 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17955 instruction in MODE. */
17958 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17960 rtx (*fn) (rtx, rtx, rtx) = NULL;
17961 if (mode == SImode)
17962 fn = gen_store_conditional_si;
17963 else if (mode == DImode)
17964 fn = gen_store_conditional_di;
17966 /* Emit sync before stwcx. to address PPC405 Erratum. */
17967 if (PPC405_ERRATUM77)
17968 emit_insn (gen_memory_barrier ());
17970 emit_insn (fn (res, mem, val));
17973 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17974 to perform. MEM is the memory on which to operate. VAL is the second
17975 operand of the binary operator. BEFORE and AFTER are optional locations to
17976 return the value of MEM either before of after the operation. SCRATCH is
17977 a scratch register. */
17980 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17981 rtx before, rtx after, rtx scratch)
17983 enum machine_mode mode = GET_MODE (mem);
17984 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17986 emit_insn (gen_lwsync ());
17988 label = gen_label_rtx ();
17989 emit_label (label);
17990 label = gen_rtx_LABEL_REF (VOIDmode, label);
17992 if (before == NULL_RTX)
17994 emit_load_locked (mode, before, mem);
17997 x = gen_rtx_IOR (mode,
17998 gen_rtx_NOT (mode, before),
17999 gen_rtx_NOT (mode, val));
18000 else if (code == AND)
18001 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
18003 x = gen_rtx_fmt_ee (code, mode, before, val);
18005 if (after != NULL_RTX)
18006 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
18007 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
18009 emit_store_conditional (mode, cond, mem, scratch);
18011 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18012 emit_unlikely_jump (x, label);
18014 emit_insn (gen_isync ());
18017 /* Expand an atomic compare and swap operation. MEM is the memory on which
18018 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18019 value to be stored. SCRATCH is a scratch GPR. */
18022 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
18025 enum machine_mode mode = GET_MODE (mem);
18026 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18028 emit_insn (gen_lwsync ());
18030 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18031 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18032 emit_label (XEXP (label1, 0));
18034 emit_load_locked (mode, retval, mem);
18036 x = gen_rtx_COMPARE (CCmode, retval, oldval);
18037 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18039 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18040 emit_unlikely_jump (x, label2);
18042 emit_move_insn (scratch, newval);
18043 emit_store_conditional (mode, cond, mem, scratch);
18045 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18046 emit_unlikely_jump (x, label1);
18048 emit_insn (gen_isync ());
18049 emit_label (XEXP (label2, 0));
18052 /* Expand an atomic test and set operation. MEM is the memory on which
18053 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18056 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
18058 enum machine_mode mode = GET_MODE (mem);
18059 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18061 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18062 emit_label (XEXP (label, 0));
18064 emit_load_locked (mode, retval, mem);
18065 emit_move_insn (scratch, val);
18066 emit_store_conditional (mode, cond, mem, scratch);
18068 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18069 emit_unlikely_jump (x, label);
18071 emit_insn (gen_isync ());
18075 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
18077 enum machine_mode mode = GET_MODE (mem);
18078 rtx addrSI, align, wdst, shift, mask;
18079 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18080 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18082 /* Shift amount for subword relative to aligned word. */
18083 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18084 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18085 shift = gen_reg_rtx (SImode);
18086 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18087 GEN_INT (shift_mask)));
18088 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18090 /* Shift and mask old value into position within word. */
18091 oldval = convert_modes (SImode, mode, oldval, 1);
18092 oldval = expand_binop (SImode, and_optab,
18093 oldval, GEN_INT (imask), NULL_RTX,
18094 1, OPTAB_LIB_WIDEN);
18095 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18097 /* Shift and mask new value into position within word. */
18098 newval = convert_modes (SImode, mode, newval, 1);
18099 newval = expand_binop (SImode, and_optab,
18100 newval, GEN_INT (imask), NULL_RTX,
18101 1, OPTAB_LIB_WIDEN);
18102 emit_insn (gen_ashlsi3 (newval, newval, shift));
18104 /* Mask for insertion. */
18105 mask = gen_reg_rtx (SImode);
18106 emit_move_insn (mask, GEN_INT (imask));
18107 emit_insn (gen_ashlsi3 (mask, mask, shift));
18109 /* Address of aligned word containing subword. */
18110 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18111 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18112 mem = change_address (mem, SImode, align);
18113 set_mem_align (mem, 32);
18114 MEM_VOLATILE_P (mem) = 1;
18116 wdst = gen_reg_rtx (SImode);
18117 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18118 oldval, newval, mem));
18120 /* Shift the result back. */
18121 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18123 emit_move_insn (dst, gen_lowpart (mode, wdst));
18127 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18128 rtx oldval, rtx newval, rtx mem,
18131 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18133 emit_insn (gen_lwsync ());
18134 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18135 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18136 emit_label (XEXP (label1, 0));
18138 emit_load_locked (SImode, scratch, mem);
18140 /* Mask subword within loaded value for comparison with oldval.
18141 Use UNSPEC_AND to avoid clobber.*/
18142 emit_insn (gen_rtx_SET (SImode, dest,
18143 gen_rtx_UNSPEC (SImode,
18144 gen_rtvec (2, scratch, mask),
18147 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18148 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18150 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18151 emit_unlikely_jump (x, label2);
18153 /* Clear subword within loaded value for insertion of new value. */
18154 emit_insn (gen_rtx_SET (SImode, scratch,
18155 gen_rtx_AND (SImode,
18156 gen_rtx_NOT (SImode, mask), scratch)));
18157 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18158 emit_store_conditional (SImode, cond, mem, scratch);
18160 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18161 emit_unlikely_jump (x, label1);
18163 emit_insn (gen_isync ());
18164 emit_label (XEXP (label2, 0));
18168 /* Emit instructions to move SRC to DST. Called by splitters for
18169 multi-register moves. It will emit at most one instruction for
18170 each register that is accessed; that is, it won't emit li/lis pairs
18171 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18175 rs6000_split_multireg_move (rtx dst, rtx src)
18177 /* The register number of the first register being moved. */
18179 /* The mode that is to be moved. */
18180 enum machine_mode mode;
18181 /* The mode that the move is being done in, and its size. */
18182 enum machine_mode reg_mode;
18184 /* The number of registers that will be moved. */
18187 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18188 mode = GET_MODE (dst);
18189 nregs = hard_regno_nregs[reg][mode];
18190 if (FP_REGNO_P (reg))
18191 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18192 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18193 else if (ALTIVEC_REGNO_P (reg))
18194 reg_mode = V16QImode;
18195 else if (TARGET_E500_DOUBLE && mode == TFmode)
18198 reg_mode = word_mode;
18199 reg_mode_size = GET_MODE_SIZE (reg_mode);
18201 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18203 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18205 /* Move register range backwards, if we might have destructive
18208 for (i = nregs - 1; i >= 0; i--)
18209 emit_insn (gen_rtx_SET (VOIDmode,
18210 simplify_gen_subreg (reg_mode, dst, mode,
18211 i * reg_mode_size),
18212 simplify_gen_subreg (reg_mode, src, mode,
18213 i * reg_mode_size)));
18219 bool used_update = false;
18220 rtx restore_basereg = NULL_RTX;
18222 if (MEM_P (src) && INT_REGNO_P (reg))
18226 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18227 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18230 breg = XEXP (XEXP (src, 0), 0);
18231 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18232 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18233 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18234 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18235 src = replace_equiv_address (src, breg);
18237 else if (! rs6000_offsettable_memref_p (src))
18239 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18241 rtx basereg = XEXP (XEXP (src, 0), 0);
18244 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18245 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18246 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18247 used_update = true;
18250 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18251 XEXP (XEXP (src, 0), 1)));
18252 src = replace_equiv_address (src, basereg);
18256 rtx basereg = gen_rtx_REG (Pmode, reg);
18257 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18258 src = replace_equiv_address (src, basereg);
18262 breg = XEXP (src, 0);
18263 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18264 breg = XEXP (breg, 0);
18266 /* If the base register we are using to address memory is
18267 also a destination reg, then change that register last. */
18269 && REGNO (breg) >= REGNO (dst)
18270 && REGNO (breg) < REGNO (dst) + nregs)
18271 j = REGNO (breg) - REGNO (dst);
18273 else if (MEM_P (dst) && INT_REGNO_P (reg))
18277 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18278 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18281 breg = XEXP (XEXP (dst, 0), 0);
18282 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18283 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18284 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18286 /* We have to update the breg before doing the store.
18287 Use store with update, if available. */
18291 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18292 emit_insn (TARGET_32BIT
18293 ? (TARGET_POWERPC64
18294 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18295 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18296 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18297 used_update = true;
18300 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18301 dst = replace_equiv_address (dst, breg);
18303 else if (!rs6000_offsettable_memref_p (dst)
18304 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18306 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18308 rtx basereg = XEXP (XEXP (dst, 0), 0);
18311 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18312 emit_insn (gen_rtx_SET (VOIDmode,
18313 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18314 used_update = true;
18317 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18318 XEXP (XEXP (dst, 0), 1)));
18319 dst = replace_equiv_address (dst, basereg);
18323 rtx basereg = XEXP (XEXP (dst, 0), 0);
18324 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18325 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18327 && REG_P (offsetreg)
18328 && REGNO (basereg) != REGNO (offsetreg));
18329 if (REGNO (basereg) == 0)
18331 rtx tmp = offsetreg;
18332 offsetreg = basereg;
18335 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18336 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18337 dst = replace_equiv_address (dst, basereg);
18340 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18341 gcc_assert (rs6000_offsettable_memref_p (dst));
18344 for (i = 0; i < nregs; i++)
18346 /* Calculate index to next subword. */
18351 /* If compiler already emitted move of first word by
18352 store with update, no need to do anything. */
18353 if (j == 0 && used_update)
18356 emit_insn (gen_rtx_SET (VOIDmode,
18357 simplify_gen_subreg (reg_mode, dst, mode,
18358 j * reg_mode_size),
18359 simplify_gen_subreg (reg_mode, src, mode,
18360 j * reg_mode_size)));
18362 if (restore_basereg != NULL_RTX)
18363 emit_insn (restore_basereg);
18368 /* This page contains routines that are used to determine what the
18369 function prologue and epilogue code will do and write them out. */
18371 /* Return the first fixed-point register that is required to be
18372 saved. 32 if none. */
18375 first_reg_to_save (void)
18379 /* Find lowest numbered live register. */
18380 for (first_reg = 13; first_reg <= 31; first_reg++)
18381 if (df_regs_ever_live_p (first_reg)
18382 && (! call_used_regs[first_reg]
18383 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18384 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18385 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18386 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18391 && crtl->uses_pic_offset_table
18392 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18393 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18399 /* Similar, for FP regs. */
18402 first_fp_reg_to_save (void)
18406 /* Find lowest numbered live register. */
18407 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18408 if (df_regs_ever_live_p (first_reg))
18414 /* Similar, for AltiVec regs. */
18417 first_altivec_reg_to_save (void)
18421 /* Stack frame remains as is unless we are in AltiVec ABI. */
18422 if (! TARGET_ALTIVEC_ABI)
18423 return LAST_ALTIVEC_REGNO + 1;
18425 /* On Darwin, the unwind routines are compiled without
18426 TARGET_ALTIVEC, and use save_world to save/restore the
18427 altivec registers when necessary. */
18428 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18429 && ! TARGET_ALTIVEC)
18430 return FIRST_ALTIVEC_REGNO + 20;
18432 /* Find lowest numbered live register. */
18433 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18434 if (df_regs_ever_live_p (i))
18440 /* Return a 32-bit mask of the AltiVec registers we need to set in
18441 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18442 the 32-bit word is 0. */
18444 static unsigned int
18445 compute_vrsave_mask (void)
18447 unsigned int i, mask = 0;
18449 /* On Darwin, the unwind routines are compiled without
18450 TARGET_ALTIVEC, and use save_world to save/restore the
18451 call-saved altivec registers when necessary. */
18452 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18453 && ! TARGET_ALTIVEC)
18456 /* First, find out if we use _any_ altivec registers. */
18457 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18458 if (df_regs_ever_live_p (i))
18459 mask |= ALTIVEC_REG_BIT (i);
18464 /* Next, remove the argument registers from the set. These must
18465 be in the VRSAVE mask set by the caller, so we don't need to add
18466 them in again. More importantly, the mask we compute here is
18467 used to generate CLOBBERs in the set_vrsave insn, and we do not
18468 wish the argument registers to die. */
18469 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18470 mask &= ~ALTIVEC_REG_BIT (i);
18472 /* Similarly, remove the return value from the set. */
18475 diddle_return_value (is_altivec_return_reg, &yes);
18477 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18483 /* For a very restricted set of circumstances, we can cut down the
18484 size of prologues/epilogues by calling our own save/restore-the-world
18488 compute_save_world_info (rs6000_stack_t *info_ptr)
18490 info_ptr->world_save_p = 1;
18491 info_ptr->world_save_p
18492 = (WORLD_SAVE_P (info_ptr)
18493 && DEFAULT_ABI == ABI_DARWIN
18494 && !cfun->has_nonlocal_label
18495 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18496 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18497 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18498 && info_ptr->cr_save_p);
18500 /* This will not work in conjunction with sibcalls. Make sure there
18501 are none. (This check is expensive, but seldom executed.) */
18502 if (WORLD_SAVE_P (info_ptr))
18505 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18506 if ( GET_CODE (insn) == CALL_INSN
18507 && SIBLING_CALL_P (insn))
18509 info_ptr->world_save_p = 0;
18514 if (WORLD_SAVE_P (info_ptr))
18516 /* Even if we're not touching VRsave, make sure there's room on the
18517 stack for it, if it looks like we're calling SAVE_WORLD, which
18518 will attempt to save it. */
18519 info_ptr->vrsave_size = 4;
18521 /* If we are going to save the world, we need to save the link register too. */
18522 info_ptr->lr_save_p = 1;
18524 /* "Save" the VRsave register too if we're saving the world. */
18525 if (info_ptr->vrsave_mask == 0)
18526 info_ptr->vrsave_mask = compute_vrsave_mask ();
18528 /* Because the Darwin register save/restore routines only handle
18529 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18531 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18532 && (info_ptr->first_altivec_reg_save
18533 >= FIRST_SAVED_ALTIVEC_REGNO));
18540 is_altivec_return_reg (rtx reg, void *xyes)
18542 bool *yes = (bool *) xyes;
18543 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18548 /* Determine the strategy for savings/restoring registers. */
18551 SAVRES_MULTIPLE = 0x1,
18552 SAVE_INLINE_FPRS = 0x2,
18553 SAVE_INLINE_GPRS = 0x4,
18554 REST_INLINE_FPRS = 0x8,
18555 REST_INLINE_GPRS = 0x10,
18556 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18557 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18558 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18562 rs6000_savres_strategy (rs6000_stack_t *info,
18563 bool using_static_chain_p)
18567 if (TARGET_MULTIPLE
18568 && !TARGET_POWERPC64
18569 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18570 && info->first_gp_reg_save < 31
18571 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18572 strategy |= SAVRES_MULTIPLE;
18574 if (crtl->calls_eh_return
18575 || cfun->machine->ra_need_lr
18576 || info->total_size > 32767)
18577 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18578 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18580 if (info->first_fp_reg_save == 64
18581 || FP_SAVE_INLINE (info->first_fp_reg_save)
18582 /* The out-of-line FP routines use double-precision stores;
18583 we can't use those routines if we don't have such stores. */
18584 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18585 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18586 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18588 if (info->first_gp_reg_save == 32
18589 || GP_SAVE_INLINE (info->first_gp_reg_save)
18590 || !((strategy & SAVRES_MULTIPLE)
18591 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18592 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18594 /* Don't bother to try to save things out-of-line if r11 is occupied
18595 by the static chain. It would require too much fiddling and the
18596 static chain is rarely used anyway. */
18597 if (using_static_chain_p)
18598 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18600 /* If we are going to use store multiple, then don't even bother
18601 with the out-of-line routines, since the store-multiple
18602 instruction will always be smaller. */
18603 if ((strategy & SAVRES_MULTIPLE))
18604 strategy |= SAVE_INLINE_GPRS;
18606 /* The situation is more complicated with load multiple. We'd
18607 prefer to use the out-of-line routines for restores, since the
18608 "exit" out-of-line routines can handle the restore of LR and the
18609 frame teardown. However if doesn't make sense to use the
18610 out-of-line routine if that is the only reason we'd need to save
18611 LR, and we can't use the "exit" out-of-line gpr restore if we
18612 have saved some fprs; In those cases it is advantageous to use
18613 load multiple when available. */
18614 if ((strategy & SAVRES_MULTIPLE)
18615 && (!info->lr_save_p
18616 || info->first_fp_reg_save != 64))
18617 strategy |= REST_INLINE_GPRS;
18619 /* We can only use load multiple or the out-of-line routines to
18620 restore if we've used store multiple or out-of-line routines
18621 in the prologue, i.e. if we've saved all the registers from
18622 first_gp_reg_save. Otherwise, we risk loading garbage. */
18623 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18624 strategy |= REST_INLINE_GPRS;
18626 /* Saving CR interferes with the exit routines used on the SPE, so
18629 && info->spe_64bit_regs_used
18630 && info->cr_save_p)
18631 strategy |= REST_INLINE_GPRS;
18633 #ifdef POWERPC_LINUX
18636 if (!(strategy & SAVE_INLINE_FPRS))
18637 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18638 else if (!(strategy & SAVE_INLINE_GPRS)
18639 && info->first_fp_reg_save == 64)
18640 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18643 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18644 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18649 /* Calculate the stack information for the current function. This is
18650 complicated by having two separate calling sequences, the AIX calling
18651 sequence and the V.4 calling sequence.
18653 AIX (and Darwin/Mac OS X) stack frames look like:
18655 SP----> +---------------------------------------+
18656 | back chain to caller | 0 0
18657 +---------------------------------------+
18658 | saved CR | 4 8 (8-11)
18659 +---------------------------------------+
18661 +---------------------------------------+
18662 | reserved for compilers | 12 24
18663 +---------------------------------------+
18664 | reserved for binders | 16 32
18665 +---------------------------------------+
18666 | saved TOC pointer | 20 40
18667 +---------------------------------------+
18668 | Parameter save area (P) | 24 48
18669 +---------------------------------------+
18670 | Alloca space (A) | 24+P etc.
18671 +---------------------------------------+
18672 | Local variable space (L) | 24+P+A
18673 +---------------------------------------+
18674 | Float/int conversion temporary (X) | 24+P+A+L
18675 +---------------------------------------+
18676 | Save area for AltiVec registers (W) | 24+P+A+L+X
18677 +---------------------------------------+
18678 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18679 +---------------------------------------+
18680 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18681 +---------------------------------------+
18682 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18683 +---------------------------------------+
18684 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18685 +---------------------------------------+
18686 old SP->| back chain to caller's caller |
18687 +---------------------------------------+
18689 The required alignment for AIX configurations is two words (i.e., 8
18693 V.4 stack frames look like:
18695 SP----> +---------------------------------------+
18696 | back chain to caller | 0
18697 +---------------------------------------+
18698 | caller's saved LR | 4
18699 +---------------------------------------+
18700 | Parameter save area (P) | 8
18701 +---------------------------------------+
18702 | Alloca space (A) | 8+P
18703 +---------------------------------------+
18704 | Varargs save area (V) | 8+P+A
18705 +---------------------------------------+
18706 | Local variable space (L) | 8+P+A+V
18707 +---------------------------------------+
18708 | Float/int conversion temporary (X) | 8+P+A+V+L
18709 +---------------------------------------+
18710 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18711 +---------------------------------------+
18712 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18713 +---------------------------------------+
18714 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18715 +---------------------------------------+
18716 | SPE: area for 64-bit GP registers |
18717 +---------------------------------------+
18718 | SPE alignment padding |
18719 +---------------------------------------+
18720 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18721 +---------------------------------------+
18722 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18723 +---------------------------------------+
18724 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18725 +---------------------------------------+
18726 old SP->| back chain to caller's caller |
18727 +---------------------------------------+
18729 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18730 given. (But note below and in sysv4.h that we require only 8 and
18731 may round up the size of our stack frame anyways. The historical
18732 reason is early versions of powerpc-linux which didn't properly
18733 align the stack at program startup. A happy side-effect is that
18734 -mno-eabi libraries can be used with -meabi programs.)
18736 The EABI configuration defaults to the V.4 layout. However,
18737 the stack alignment requirements may differ. If -mno-eabi is not
18738 given, the required stack alignment is 8 bytes; if -mno-eabi is
18739 given, the required alignment is 16 bytes. (But see V.4 comment
18742 #ifndef ABI_STACK_BOUNDARY
18743 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18746 static rs6000_stack_t *
18747 rs6000_stack_info (void)
18749 #ifdef ENABLE_CHECKING
18750 static rs6000_stack_t info_save;
18752 rs6000_stack_t *info_ptr = &stack_info;
18753 int reg_size = TARGET_32BIT ? 4 : 8;
18757 HOST_WIDE_INT non_fixed_size;
18758 bool using_static_chain_p;
18760 #ifdef ENABLE_CHECKING
18761 memcpy (&info_save, &stack_info, sizeof stack_info);
18763 if (reload_completed && info_ptr->reload_completed)
18767 memset (&stack_info, 0, sizeof (stack_info));
18768 info_ptr->reload_completed = reload_completed;
18772 /* Cache value so we don't rescan instruction chain over and over. */
18773 if (cfun->machine->insn_chain_scanned_p == 0)
18774 cfun->machine->insn_chain_scanned_p
18775 = spe_func_has_64bit_regs_p () + 1;
18776 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18779 /* Select which calling sequence. */
18780 info_ptr->abi = DEFAULT_ABI;
18782 /* Calculate which registers need to be saved & save area size. */
18783 info_ptr->first_gp_reg_save = first_reg_to_save ();
18784 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18785 even if it currently looks like we won't. Reload may need it to
18786 get at a constant; if so, it will have already created a constant
18787 pool entry for it. */
18788 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18789 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18790 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18791 && crtl->uses_const_pool
18792 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18793 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18795 first_gp = info_ptr->first_gp_reg_save;
18797 info_ptr->gp_size = reg_size * (32 - first_gp);
18799 /* For the SPE, we have an additional upper 32-bits on each GPR.
18800 Ideally we should save the entire 64-bits only when the upper
18801 half is used in SIMD instructions. Since we only record
18802 registers live (not the size they are used in), this proves
18803 difficult because we'd have to traverse the instruction chain at
18804 the right time, taking reload into account. This is a real pain,
18805 so we opt to save the GPRs in 64-bits always if but one register
18806 gets used in 64-bits. Otherwise, all the registers in the frame
18807 get saved in 32-bits.
18809 So... since when we save all GPRs (except the SP) in 64-bits, the
18810 traditional GP save area will be empty. */
18811 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18812 info_ptr->gp_size = 0;
18814 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18815 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18817 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18818 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18819 - info_ptr->first_altivec_reg_save);
18821 /* Does this function call anything? */
18822 info_ptr->calls_p = (! current_function_is_leaf
18823 || cfun->machine->ra_needs_full_frame);
18825 /* Determine if we need to save the condition code registers. */
18826 if (df_regs_ever_live_p (CR2_REGNO)
18827 || df_regs_ever_live_p (CR3_REGNO)
18828 || df_regs_ever_live_p (CR4_REGNO))
18830 info_ptr->cr_save_p = 1;
18831 if (DEFAULT_ABI == ABI_V4)
18832 info_ptr->cr_size = reg_size;
18835 /* If the current function calls __builtin_eh_return, then we need
18836 to allocate stack space for registers that will hold data for
18837 the exception handler. */
18838 if (crtl->calls_eh_return)
18841 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18844 /* SPE saves EH registers in 64-bits. */
18845 ehrd_size = i * (TARGET_SPE_ABI
18846 && info_ptr->spe_64bit_regs_used != 0
18847 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18852 /* Determine various sizes. */
18853 info_ptr->reg_size = reg_size;
18854 info_ptr->fixed_size = RS6000_SAVE_AREA;
18855 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18856 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18857 TARGET_ALTIVEC ? 16 : 8);
18858 if (FRAME_GROWS_DOWNWARD)
18859 info_ptr->vars_size
18860 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18861 + info_ptr->parm_size,
18862 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18863 - (info_ptr->fixed_size + info_ptr->vars_size
18864 + info_ptr->parm_size);
18866 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18867 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18869 info_ptr->spe_gp_size = 0;
18871 if (TARGET_ALTIVEC_ABI)
18872 info_ptr->vrsave_mask = compute_vrsave_mask ();
18874 info_ptr->vrsave_mask = 0;
18876 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18877 info_ptr->vrsave_size = 4;
18879 info_ptr->vrsave_size = 0;
18881 compute_save_world_info (info_ptr);
18883 /* Calculate the offsets. */
18884 switch (DEFAULT_ABI)
18888 gcc_unreachable ();
18892 info_ptr->fp_save_offset = - info_ptr->fp_size;
18893 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18895 if (TARGET_ALTIVEC_ABI)
18897 info_ptr->vrsave_save_offset
18898 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18900 /* Align stack so vector save area is on a quadword boundary.
18901 The padding goes above the vectors. */
18902 if (info_ptr->altivec_size != 0)
18903 info_ptr->altivec_padding_size
18904 = info_ptr->vrsave_save_offset & 0xF;
18906 info_ptr->altivec_padding_size = 0;
18908 info_ptr->altivec_save_offset
18909 = info_ptr->vrsave_save_offset
18910 - info_ptr->altivec_padding_size
18911 - info_ptr->altivec_size;
18912 gcc_assert (info_ptr->altivec_size == 0
18913 || info_ptr->altivec_save_offset % 16 == 0);
18915 /* Adjust for AltiVec case. */
18916 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18919 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18920 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18921 info_ptr->lr_save_offset = 2*reg_size;
18925 info_ptr->fp_save_offset = - info_ptr->fp_size;
18926 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18927 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18929 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18931 /* Align stack so SPE GPR save area is aligned on a
18932 double-word boundary. */
18933 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18934 info_ptr->spe_padding_size
18935 = 8 - (-info_ptr->cr_save_offset % 8);
18937 info_ptr->spe_padding_size = 0;
18939 info_ptr->spe_gp_save_offset
18940 = info_ptr->cr_save_offset
18941 - info_ptr->spe_padding_size
18942 - info_ptr->spe_gp_size;
18944 /* Adjust for SPE case. */
18945 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18947 else if (TARGET_ALTIVEC_ABI)
18949 info_ptr->vrsave_save_offset
18950 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18952 /* Align stack so vector save area is on a quadword boundary. */
18953 if (info_ptr->altivec_size != 0)
18954 info_ptr->altivec_padding_size
18955 = 16 - (-info_ptr->vrsave_save_offset % 16);
18957 info_ptr->altivec_padding_size = 0;
18959 info_ptr->altivec_save_offset
18960 = info_ptr->vrsave_save_offset
18961 - info_ptr->altivec_padding_size
18962 - info_ptr->altivec_size;
18964 /* Adjust for AltiVec case. */
18965 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18968 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18969 info_ptr->ehrd_offset -= ehrd_size;
18970 info_ptr->lr_save_offset = reg_size;
18974 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18975 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18976 + info_ptr->gp_size
18977 + info_ptr->altivec_size
18978 + info_ptr->altivec_padding_size
18979 + info_ptr->spe_gp_size
18980 + info_ptr->spe_padding_size
18982 + info_ptr->cr_size
18983 + info_ptr->vrsave_size,
18986 non_fixed_size = (info_ptr->vars_size
18987 + info_ptr->parm_size
18988 + info_ptr->save_size);
18990 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18991 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18993 /* Determine if we need to save the link register. */
18994 if (info_ptr->calls_p
18995 || (DEFAULT_ABI == ABI_AIX
18997 && !TARGET_PROFILE_KERNEL)
18998 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18999 #ifdef TARGET_RELOCATABLE
19000 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
19002 || rs6000_ra_ever_killed ())
19003 info_ptr->lr_save_p = 1;
19005 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19006 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19007 && call_used_regs[STATIC_CHAIN_REGNUM]);
19008 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
19009 using_static_chain_p);
19011 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
19012 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
19013 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
19014 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
19015 info_ptr->lr_save_p = 1;
19017 if (info_ptr->lr_save_p)
19018 df_set_regs_ever_live (LR_REGNO, true);
19020 /* Determine if we need to allocate any stack frame:
19022 For AIX we need to push the stack if a frame pointer is needed
19023 (because the stack might be dynamically adjusted), if we are
19024 debugging, if we make calls, or if the sum of fp_save, gp_save,
19025 and local variables are more than the space needed to save all
19026 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19027 + 18*8 = 288 (GPR13 reserved).
19029 For V.4 we don't have the stack cushion that AIX uses, but assume
19030 that the debugger can handle stackless frames. */
19032 if (info_ptr->calls_p)
19033 info_ptr->push_p = 1;
19035 else if (DEFAULT_ABI == ABI_V4)
19036 info_ptr->push_p = non_fixed_size != 0;
19038 else if (frame_pointer_needed)
19039 info_ptr->push_p = 1;
19041 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
19042 info_ptr->push_p = 1;
19045 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
19047 /* Zero offsets if we're not saving those registers. */
19048 if (info_ptr->fp_size == 0)
19049 info_ptr->fp_save_offset = 0;
19051 if (info_ptr->gp_size == 0)
19052 info_ptr->gp_save_offset = 0;
19054 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
19055 info_ptr->altivec_save_offset = 0;
19057 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
19058 info_ptr->vrsave_save_offset = 0;
19060 if (! TARGET_SPE_ABI
19061 || info_ptr->spe_64bit_regs_used == 0
19062 || info_ptr->spe_gp_size == 0)
19063 info_ptr->spe_gp_save_offset = 0;
19065 if (! info_ptr->lr_save_p)
19066 info_ptr->lr_save_offset = 0;
19068 if (! info_ptr->cr_save_p)
19069 info_ptr->cr_save_offset = 0;
19071 #ifdef ENABLE_CHECKING
19072 gcc_assert (!(reload_completed && info_save.reload_completed)
19073 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
19078 /* Return true if the current function uses any GPRs in 64-bit SIMD
19082 spe_func_has_64bit_regs_p (void)
19086 /* Functions that save and restore all the call-saved registers will
19087 need to save/restore the registers in 64-bits. */
19088 if (crtl->calls_eh_return
19089 || cfun->calls_setjmp
19090 || crtl->has_nonlocal_goto)
19093 insns = get_insns ();
19095 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19101 /* FIXME: This should be implemented with attributes...
19103 (set_attr "spe64" "true")....then,
19104 if (get_spe64(insn)) return true;
19106 It's the only reliable way to do the stuff below. */
19108 i = PATTERN (insn);
19109 if (GET_CODE (i) == SET)
19111 enum machine_mode mode = GET_MODE (SET_SRC (i));
19113 if (SPE_VECTOR_MODE (mode))
19115 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19125 debug_stack_info (rs6000_stack_t *info)
19127 const char *abi_string;
19130 info = rs6000_stack_info ();
19132 fprintf (stderr, "\nStack information for function %s:\n",
19133 ((current_function_decl && DECL_NAME (current_function_decl))
19134 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19139 default: abi_string = "Unknown"; break;
19140 case ABI_NONE: abi_string = "NONE"; break;
19141 case ABI_AIX: abi_string = "AIX"; break;
19142 case ABI_DARWIN: abi_string = "Darwin"; break;
19143 case ABI_V4: abi_string = "V.4"; break;
19146 fprintf (stderr, "\tABI = %5s\n", abi_string);
19148 if (TARGET_ALTIVEC_ABI)
19149 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19151 if (TARGET_SPE_ABI)
19152 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19154 if (info->first_gp_reg_save != 32)
19155 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19157 if (info->first_fp_reg_save != 64)
19158 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19160 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19161 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19162 info->first_altivec_reg_save);
19164 if (info->lr_save_p)
19165 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19167 if (info->cr_save_p)
19168 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19170 if (info->vrsave_mask)
19171 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19174 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19177 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19179 if (info->gp_save_offset)
19180 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19182 if (info->fp_save_offset)
19183 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19185 if (info->altivec_save_offset)
19186 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19187 info->altivec_save_offset);
19189 if (info->spe_gp_save_offset)
19190 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19191 info->spe_gp_save_offset);
19193 if (info->vrsave_save_offset)
19194 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19195 info->vrsave_save_offset);
19197 if (info->lr_save_offset)
19198 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19200 if (info->cr_save_offset)
19201 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19203 if (info->varargs_save_offset)
19204 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19206 if (info->total_size)
19207 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19210 if (info->vars_size)
19211 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19214 if (info->parm_size)
19215 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19217 if (info->fixed_size)
19218 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19221 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19223 if (info->spe_gp_size)
19224 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19227 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19229 if (info->altivec_size)
19230 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19232 if (info->vrsave_size)
19233 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19235 if (info->altivec_padding_size)
19236 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19237 info->altivec_padding_size);
19239 if (info->spe_padding_size)
19240 fprintf (stderr, "\tspe_padding_size = %5d\n",
19241 info->spe_padding_size);
19244 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19246 if (info->save_size)
19247 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19249 if (info->reg_size != 4)
19250 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19252 fprintf (stderr, "\n");
19256 rs6000_return_addr (int count, rtx frame)
19258 /* Currently we don't optimize very well between prolog and body
19259 code and for PIC code the code can be actually quite bad, so
19260 don't try to be too clever here. */
19261 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19263 cfun->machine->ra_needs_full_frame = 1;
19270 plus_constant (copy_to_reg
19271 (gen_rtx_MEM (Pmode,
19272 memory_address (Pmode, frame))),
19273 RETURN_ADDRESS_OFFSET)));
19276 cfun->machine->ra_need_lr = 1;
19277 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19280 /* Say whether a function is a candidate for sibcall handling or not.
19281 We do not allow indirect calls to be optimized into sibling calls.
19282 Also, we can't do it if there are any vector parameters; there's
19283 nowhere to put the VRsave code so it works; note that functions with
19284 vector parameters are required to have a prototype, so the argument
19285 type info must be available here. (The tail recursion case can work
19286 with vector parameters, but there's no way to distinguish here.) */
19288 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19293 if (TARGET_ALTIVEC_VRSAVE)
19295 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19296 type; type = TREE_CHAIN (type))
19298 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19302 if (DEFAULT_ABI == ABI_DARWIN
19303 || ((*targetm.binds_local_p) (decl)
19304 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19306 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19308 if (!lookup_attribute ("longcall", attr_list)
19309 || lookup_attribute ("shortcall", attr_list))
19316 /* NULL if INSN insn is valid within a low-overhead loop.
19317 Otherwise return why doloop cannot be applied.
19318 PowerPC uses the COUNT register for branch on table instructions. */
19320 static const char *
19321 rs6000_invalid_within_doloop (const_rtx insn)
19324 return "Function call in the loop.";
19327 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19328 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19329 return "Computed branch in the loop.";
19335 rs6000_ra_ever_killed (void)
19341 if (cfun->is_thunk)
19344 if (cfun->machine->lr_save_state)
19345 return cfun->machine->lr_save_state - 1;
19347 /* regs_ever_live has LR marked as used if any sibcalls are present,
19348 but this should not force saving and restoring in the
19349 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19350 clobbers LR, so that is inappropriate. */
19352 /* Also, the prologue can generate a store into LR that
19353 doesn't really count, like this:
19356 bcl to set PIC register
19360 When we're called from the epilogue, we need to avoid counting
19361 this as a store. */
19363 push_topmost_sequence ();
19364 top = get_insns ();
19365 pop_topmost_sequence ();
19366 reg = gen_rtx_REG (Pmode, LR_REGNO);
19368 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19374 if (!SIBLING_CALL_P (insn))
19377 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19379 else if (set_of (reg, insn) != NULL_RTX
19380 && !prologue_epilogue_contains (insn))
19387 /* Emit instructions needed to load the TOC register.
19388 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19389 a constant pool; or for SVR4 -fpic. */
19392 rs6000_emit_load_toc_table (int fromprolog)
19395 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19397 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19400 rtx lab, tmp1, tmp2, got;
19402 lab = gen_label_rtx ();
19403 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19404 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19406 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19408 got = rs6000_got_sym ();
19409 tmp1 = tmp2 = dest;
19412 tmp1 = gen_reg_rtx (Pmode);
19413 tmp2 = gen_reg_rtx (Pmode);
19415 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19416 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19417 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19418 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19420 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19422 emit_insn (gen_load_toc_v4_pic_si ());
19423 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19425 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19428 rtx temp0 = (fromprolog
19429 ? gen_rtx_REG (Pmode, 0)
19430 : gen_reg_rtx (Pmode));
19436 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19437 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19439 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19440 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19442 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19443 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19444 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19450 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19451 lab = gen_label_rtx ();
19452 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19453 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19454 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19456 emit_insn (gen_addsi3 (dest, temp0, dest));
19458 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19460 /* This is for AIX code running in non-PIC ELF32. */
19463 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19464 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19466 emit_insn (gen_elf_high (dest, realsym));
19467 emit_insn (gen_elf_low (dest, dest, realsym));
19471 gcc_assert (DEFAULT_ABI == ABI_AIX);
19474 emit_insn (gen_load_toc_aix_si (dest));
19476 emit_insn (gen_load_toc_aix_di (dest));
19480 /* Emit instructions to restore the link register after determining where
19481 its value has been stored. */
19484 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19486 rs6000_stack_t *info = rs6000_stack_info ();
19489 operands[0] = source;
19490 operands[1] = scratch;
19492 if (info->lr_save_p)
19494 rtx frame_rtx = stack_pointer_rtx;
19495 HOST_WIDE_INT sp_offset = 0;
19498 if (frame_pointer_needed
19499 || cfun->calls_alloca
19500 || info->total_size > 32767)
19502 tmp = gen_frame_mem (Pmode, frame_rtx);
19503 emit_move_insn (operands[1], tmp);
19504 frame_rtx = operands[1];
19506 else if (info->push_p)
19507 sp_offset = info->total_size;
19509 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19510 tmp = gen_frame_mem (Pmode, tmp);
19511 emit_move_insn (tmp, operands[0]);
19514 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19516 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19517 state of lr_save_p so any change from here on would be a bug. In
19518 particular, stop rs6000_ra_ever_killed from considering the SET
19519 of lr we may have added just above. */
19520 cfun->machine->lr_save_state = info->lr_save_p + 1;
19523 static GTY(()) alias_set_type set = -1;
19526 get_TOC_alias_set (void)
19529 set = new_alias_set ();
19533 /* This returns nonzero if the current function uses the TOC. This is
19534 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19535 is generated by the ABI_V4 load_toc_* patterns. */
19542 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19545 rtx pat = PATTERN (insn);
19548 if (GET_CODE (pat) == PARALLEL)
19549 for (i = 0; i < XVECLEN (pat, 0); i++)
19551 rtx sub = XVECEXP (pat, 0, i);
19552 if (GET_CODE (sub) == USE)
19554 sub = XEXP (sub, 0);
19555 if (GET_CODE (sub) == UNSPEC
19556 && XINT (sub, 1) == UNSPEC_TOC)
19566 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19568 rtx tocrel, tocreg;
19570 if (TARGET_DEBUG_ADDR)
19572 if (GET_CODE (symbol) == SYMBOL_REF)
19573 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19577 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19578 GET_RTX_NAME (GET_CODE (symbol)));
19579 debug_rtx (symbol);
19583 if (!can_create_pseudo_p ())
19584 df_set_regs_ever_live (TOC_REGISTER, true);
19586 tocrel = gen_rtx_CONST (Pmode,
19587 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19589 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19590 if (TARGET_CMODEL != CMODEL_SMALL)
19592 rtx hi = gen_rtx_CONST (Pmode,
19593 gen_rtx_PLUS (Pmode, tocreg,
19594 gen_rtx_HIGH (Pmode, tocrel)));
19595 if (largetoc_reg != NULL)
19597 emit_move_insn (largetoc_reg, hi);
19600 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19603 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19606 /* Issue assembly directives that create a reference to the given DWARF
19607 FRAME_TABLE_LABEL from the current function section. */
19609 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19611 fprintf (asm_out_file, "\t.ref %s\n",
19612 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19615 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19616 and the change to the stack pointer. */
19619 rs6000_emit_stack_tie (void)
19621 rtx mem = gen_frame_mem (BLKmode,
19622 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19624 emit_insn (gen_stack_tie (mem));
19627 /* Emit the correct code for allocating stack space, as insns.
19628 If COPY_REG, make sure a copy of the old frame is left there.
19629 The generated code may use hard register 0 as a temporary. */
19632 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19635 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19636 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19637 rtx todec = gen_int_mode (-size, Pmode);
19640 if (INTVAL (todec) != -size)
19642 warning (0, "stack frame too large");
19643 emit_insn (gen_trap ());
19647 if (crtl->limit_stack)
19649 if (REG_P (stack_limit_rtx)
19650 && REGNO (stack_limit_rtx) > 1
19651 && REGNO (stack_limit_rtx) <= 31)
19653 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19654 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19657 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19659 && DEFAULT_ABI == ABI_V4)
19661 rtx toload = gen_rtx_CONST (VOIDmode,
19662 gen_rtx_PLUS (Pmode,
19666 emit_insn (gen_elf_high (tmp_reg, toload));
19667 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19668 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19672 warning (0, "stack limit expression is not supported");
19676 emit_move_insn (copy_reg, stack_reg);
19680 /* Need a note here so that try_split doesn't get confused. */
19681 if (get_last_insn () == NULL_RTX)
19682 emit_note (NOTE_INSN_DELETED);
19683 insn = emit_move_insn (tmp_reg, todec);
19684 try_split (PATTERN (insn), insn, 0);
19688 insn = emit_insn (TARGET_32BIT
19689 ? gen_movsi_update_stack (stack_reg, stack_reg,
19691 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19692 todec, stack_reg));
19693 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19694 it now and set the alias set/attributes. The above gen_*_update
19695 calls will generate a PARALLEL with the MEM set being the first
19697 par = PATTERN (insn);
19698 gcc_assert (GET_CODE (par) == PARALLEL);
19699 set = XVECEXP (par, 0, 0);
19700 gcc_assert (GET_CODE (set) == SET);
19701 mem = SET_DEST (set);
19702 gcc_assert (MEM_P (mem));
19703 MEM_NOTRAP_P (mem) = 1;
19704 set_mem_alias_set (mem, get_frame_alias_set ());
19706 RTX_FRAME_RELATED_P (insn) = 1;
19707 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19708 gen_rtx_SET (VOIDmode, stack_reg,
19709 gen_rtx_PLUS (Pmode, stack_reg,
19710 GEN_INT (-size))));
19713 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19715 #if PROBE_INTERVAL > 32768
19716 #error Cannot use indexed addressing mode for stack probing
19719 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19720 inclusive. These are offsets from the current stack pointer. */
19723 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19725 /* See if we have a constant small number of probes to generate. If so,
19726 that's the easy case. */
19727 if (first + size <= 32768)
19731 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19732 it exceeds SIZE. If only one probe is needed, this will not
19733 generate any code. Then probe at FIRST + SIZE. */
19734 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19735 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19737 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19740 /* Otherwise, do the same as above, but in a loop. Note that we must be
19741 extra careful with variables wrapping around because we might be at
19742 the very top (or the very bottom) of the address space and we have
19743 to be able to handle this case properly; in particular, we use an
19744 equality test for the loop condition. */
19747 HOST_WIDE_INT rounded_size;
19748 rtx r12 = gen_rtx_REG (Pmode, 12);
19749 rtx r0 = gen_rtx_REG (Pmode, 0);
19751 /* Sanity check for the addressing mode we're going to use. */
19752 gcc_assert (first <= 32768);
19754 /* Step 1: round SIZE to the previous multiple of the interval. */
19756 rounded_size = size & -PROBE_INTERVAL;
19759 /* Step 2: compute initial and final value of the loop counter. */
19761 /* TEST_ADDR = SP + FIRST. */
19762 emit_insn (gen_rtx_SET (VOIDmode, r12,
19763 plus_constant (stack_pointer_rtx, -first)));
19765 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19766 if (rounded_size > 32768)
19768 emit_move_insn (r0, GEN_INT (-rounded_size));
19769 emit_insn (gen_rtx_SET (VOIDmode, r0,
19770 gen_rtx_PLUS (Pmode, r12, r0)));
19773 emit_insn (gen_rtx_SET (VOIDmode, r0,
19774 plus_constant (r12, -rounded_size)));
19777 /* Step 3: the loop
19779 while (TEST_ADDR != LAST_ADDR)
19781 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19785 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19786 until it is equal to ROUNDED_SIZE. */
19789 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19791 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19794 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19795 that SIZE is equal to ROUNDED_SIZE. */
19797 if (size != rounded_size)
19798 emit_stack_probe (plus_constant (r12, rounded_size - size));
19802 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19803 absolute addresses. */
19806 output_probe_stack_range (rtx reg1, rtx reg2)
19808 static int labelno = 0;
19809 char loop_lab[32], end_lab[32];
19812 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19813 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19815 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19817 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19821 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19823 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19825 fputs ("\tbeq 0,", asm_out_file);
19826 assemble_name_raw (asm_out_file, end_lab);
19827 fputc ('\n', asm_out_file);
19829 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19830 xops[1] = GEN_INT (-PROBE_INTERVAL);
19831 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19833 /* Probe at TEST_ADDR and branch. */
19834 xops[1] = gen_rtx_REG (Pmode, 0);
19835 output_asm_insn ("{st|stw} %1,0(%0)", xops);
19836 fprintf (asm_out_file, "\tb ");
19837 assemble_name_raw (asm_out_file, loop_lab);
19838 fputc ('\n', asm_out_file);
19840 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19845 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19846 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19847 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19848 deduce these equivalences by itself so it wasn't necessary to hold
19849 its hand so much. */
19852 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19853 rtx reg2, rtx rreg)
19857 /* copy_rtx will not make unique copies of registers, so we need to
19858 ensure we don't have unwanted sharing here. */
19860 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19863 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19865 real = copy_rtx (PATTERN (insn));
19867 if (reg2 != NULL_RTX)
19868 real = replace_rtx (real, reg2, rreg);
19870 real = replace_rtx (real, reg,
19871 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19872 STACK_POINTER_REGNUM),
19875 /* We expect that 'real' is either a SET or a PARALLEL containing
19876 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19877 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19879 if (GET_CODE (real) == SET)
19883 temp = simplify_rtx (SET_SRC (set));
19885 SET_SRC (set) = temp;
19886 temp = simplify_rtx (SET_DEST (set));
19888 SET_DEST (set) = temp;
19889 if (GET_CODE (SET_DEST (set)) == MEM)
19891 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19893 XEXP (SET_DEST (set), 0) = temp;
19900 gcc_assert (GET_CODE (real) == PARALLEL);
19901 for (i = 0; i < XVECLEN (real, 0); i++)
19902 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19904 rtx set = XVECEXP (real, 0, i);
19906 temp = simplify_rtx (SET_SRC (set));
19908 SET_SRC (set) = temp;
19909 temp = simplify_rtx (SET_DEST (set));
19911 SET_DEST (set) = temp;
19912 if (GET_CODE (SET_DEST (set)) == MEM)
19914 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19916 XEXP (SET_DEST (set), 0) = temp;
19918 RTX_FRAME_RELATED_P (set) = 1;
19922 RTX_FRAME_RELATED_P (insn) = 1;
19923 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19926 /* Returns an insn that has a vrsave set operation with the
19927 appropriate CLOBBERs. */
19930 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19933 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19934 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19937 = gen_rtx_SET (VOIDmode,
19939 gen_rtx_UNSPEC_VOLATILE (SImode,
19940 gen_rtvec (2, reg, vrsave),
19941 UNSPECV_SET_VRSAVE));
19945 /* We need to clobber the registers in the mask so the scheduler
19946 does not move sets to VRSAVE before sets of AltiVec registers.
19948 However, if the function receives nonlocal gotos, reload will set
19949 all call saved registers live. We will end up with:
19951 (set (reg 999) (mem))
19952 (parallel [ (set (reg vrsave) (unspec blah))
19953 (clobber (reg 999))])
19955 The clobber will cause the store into reg 999 to be dead, and
19956 flow will attempt to delete an epilogue insn. In this case, we
19957 need an unspec use/set of the register. */
19959 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19960 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19962 if (!epiloguep || call_used_regs [i])
19963 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19964 gen_rtx_REG (V4SImode, i));
19967 rtx reg = gen_rtx_REG (V4SImode, i);
19970 = gen_rtx_SET (VOIDmode,
19972 gen_rtx_UNSPEC (V4SImode,
19973 gen_rtvec (1, reg), 27));
19977 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19979 for (i = 0; i < nclobs; ++i)
19980 XVECEXP (insn, 0, i) = clobs[i];
19985 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19986 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19989 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19990 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19992 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19993 rtx replacea, replaceb;
19995 int_rtx = GEN_INT (offset);
19997 /* Some cases that need register indexed addressing. */
19998 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19999 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
20000 || (TARGET_E500_DOUBLE && mode == DFmode)
20002 && SPE_VECTOR_MODE (mode)
20003 && !SPE_CONST_OFFSET_OK (offset)))
20005 /* Whomever calls us must make sure r11 is available in the
20006 flow path of instructions in the prologue. */
20007 offset_rtx = gen_rtx_REG (Pmode, 11);
20008 emit_move_insn (offset_rtx, int_rtx);
20010 replacea = offset_rtx;
20011 replaceb = int_rtx;
20015 offset_rtx = int_rtx;
20016 replacea = NULL_RTX;
20017 replaceb = NULL_RTX;
20020 reg = gen_rtx_REG (mode, regno);
20021 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
20022 mem = gen_frame_mem (mode, addr);
20024 insn = emit_move_insn (mem, reg);
20026 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
20029 /* Emit an offset memory reference suitable for a frame store, while
20030 converting to a valid addressing mode. */
20033 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
20035 rtx int_rtx, offset_rtx;
20037 int_rtx = GEN_INT (offset);
20039 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
20040 || (TARGET_E500_DOUBLE && mode == DFmode))
20042 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
20043 emit_move_insn (offset_rtx, int_rtx);
20046 offset_rtx = int_rtx;
20048 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
20051 /* Look for user-defined global regs. We should not save and restore these,
20052 and cannot use stmw/lmw if there are any in its range. */
20055 no_global_regs_above (int first, bool gpr)
20058 int last = gpr ? 32 : 64;
20059 for (i = first; i < last; i++)
20060 if (global_regs[i])
20065 #ifndef TARGET_FIX_AND_CONTINUE
20066 #define TARGET_FIX_AND_CONTINUE 0
20069 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20070 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20071 #define LAST_SAVRES_REGISTER 31
20072 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20074 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
20076 /* Temporary holding space for an out-of-line register save/restore
20078 static char savres_routine_name[30];
20080 /* Return the name for an out-of-line register save/restore routine.
20081 We are saving/restoring GPRs if GPR is true. */
20084 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20085 bool savep, bool gpr, bool lr)
20087 const char *prefix = "";
20088 const char *suffix = "";
20090 /* Different targets are supposed to define
20091 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20092 routine name could be defined with:
20094 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20096 This is a nice idea in practice, but in reality, things are
20097 complicated in several ways:
20099 - ELF targets have save/restore routines for GPRs.
20101 - SPE targets use different prefixes for 32/64-bit registers, and
20102 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20104 - PPC64 ELF targets have routines for save/restore of GPRs that
20105 differ in what they do with the link register, so having a set
20106 prefix doesn't work. (We only use one of the save routines at
20107 the moment, though.)
20109 - PPC32 elf targets have "exit" versions of the restore routines
20110 that restore the link register and can save some extra space.
20111 These require an extra suffix. (There are also "tail" versions
20112 of the restore routines and "GOT" versions of the save routines,
20113 but we don't generate those at present. Same problems apply,
20116 We deal with all this by synthesizing our own prefix/suffix and
20117 using that for the simple sprintf call shown above. */
20120 /* No floating point saves on the SPE. */
20124 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20126 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20131 else if (DEFAULT_ABI == ABI_V4)
20137 prefix = savep ? "_savegpr_" : "_restgpr_";
20139 prefix = savep ? "_savefpr_" : "_restfpr_";
20144 else if (DEFAULT_ABI == ABI_AIX)
20146 #ifndef POWERPC_LINUX
20147 /* No out-of-line save/restore routines for GPRs on AIX. */
20148 gcc_assert (!TARGET_AIX || !gpr);
20154 ? (lr ? "_savegpr0_" : "_savegpr1_")
20155 : (lr ? "_restgpr0_" : "_restgpr1_"));
20156 #ifdef POWERPC_LINUX
20158 prefix = (savep ? "_savefpr_" : "_restfpr_");
20162 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20163 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20166 else if (DEFAULT_ABI == ABI_DARWIN)
20167 sorry ("out-of-line save/restore routines not supported on Darwin");
20169 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20171 return savres_routine_name;
20174 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20175 We are saving/restoring GPRs if GPR is true. */
20178 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20181 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20183 int select = ((savep ? 1 : 0) << 2
20185 /* On the SPE, we never have any FPRs, but we do have
20186 32/64-bit versions of the routines. */
20187 ? (info->spe_64bit_regs_used ? 1 : 0)
20188 : (gpr ? 1 : 0)) << 1)
20191 /* Don't generate bogus routine names. */
20192 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20193 && regno <= LAST_SAVRES_REGISTER);
20195 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20201 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20203 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20204 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20205 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20211 /* Emit a sequence of insns, including a stack tie if needed, for
20212 resetting the stack pointer. If SAVRES is true, then don't reset the
20213 stack pointer, but move the base of the frame into r11 for use by
20214 out-of-line register restore routines. */
20217 rs6000_emit_stack_reset (rs6000_stack_t *info,
20218 rtx sp_reg_rtx, rtx frame_reg_rtx,
20219 int sp_offset, bool savres)
20221 /* This blockage is needed so that sched doesn't decide to move
20222 the sp change before the register restores. */
20223 if (DEFAULT_ABI == ABI_V4
20225 && info->spe_64bit_regs_used != 0
20226 && info->first_gp_reg_save != 32))
20227 rs6000_emit_stack_tie ();
20229 if (frame_reg_rtx != sp_reg_rtx)
20231 if (sp_offset != 0)
20233 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20234 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20235 GEN_INT (sp_offset)));
20238 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20240 else if (sp_offset != 0)
20242 /* If we are restoring registers out-of-line, we will be using the
20243 "exit" variants of the restore routines, which will reset the
20244 stack for us. But we do need to point r11 into the right place
20245 for those routines. */
20246 rtx dest_reg = (savres
20247 ? gen_rtx_REG (Pmode, 11)
20250 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20251 GEN_INT (sp_offset)));
20258 /* Construct a parallel rtx describing the effect of a call to an
20259 out-of-line register save/restore routine. */
20262 rs6000_make_savres_rtx (rs6000_stack_t *info,
20263 rtx frame_reg_rtx, int save_area_offset,
20264 enum machine_mode reg_mode,
20265 bool savep, bool gpr, bool lr)
20268 int offset, start_reg, end_reg, n_regs;
20269 int reg_size = GET_MODE_SIZE (reg_mode);
20275 ? info->first_gp_reg_save
20276 : info->first_fp_reg_save);
20277 end_reg = gpr ? 32 : 64;
20278 n_regs = end_reg - start_reg;
20279 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20282 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20284 RTVEC_ELT (p, offset++)
20285 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20287 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20288 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20289 RTVEC_ELT (p, offset++)
20290 = gen_rtx_USE (VOIDmode,
20291 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20295 for (i = 0; i < end_reg - start_reg; i++)
20297 rtx addr, reg, mem;
20298 reg = gen_rtx_REG (reg_mode, start_reg + i);
20299 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20300 GEN_INT (save_area_offset + reg_size*i));
20301 mem = gen_frame_mem (reg_mode, addr);
20303 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20305 savep ? reg : mem);
20310 rtx addr, reg, mem;
20311 reg = gen_rtx_REG (Pmode, 0);
20312 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20313 GEN_INT (info->lr_save_offset));
20314 mem = gen_frame_mem (Pmode, addr);
20315 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20318 return gen_rtx_PARALLEL (VOIDmode, p);
20321 /* Determine whether the gp REG is really used. */
20324 rs6000_reg_live_or_pic_offset_p (int reg)
20326 /* If the function calls eh_return, claim used all the registers that would
20327 be checked for liveness otherwise. This is required for the PIC offset
20328 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20329 register allocation purposes in this case. */
20331 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20332 && (!call_used_regs[reg]
20333 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20334 && !TARGET_SINGLE_PIC_BASE
20335 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20336 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20337 && !TARGET_SINGLE_PIC_BASE
20338 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20339 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20342 /* Emit function prologue as insns. */
20345 rs6000_emit_prologue (void)
20347 rs6000_stack_t *info = rs6000_stack_info ();
20348 enum machine_mode reg_mode = Pmode;
20349 int reg_size = TARGET_32BIT ? 4 : 8;
20350 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20351 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20352 rtx frame_reg_rtx = sp_reg_rtx;
20353 rtx cr_save_rtx = NULL_RTX;
20356 int saving_FPRs_inline;
20357 int saving_GPRs_inline;
20358 int using_store_multiple;
20359 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20360 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20361 && call_used_regs[STATIC_CHAIN_REGNUM]);
20362 HOST_WIDE_INT sp_offset = 0;
20364 if (flag_stack_usage)
20365 current_function_static_stack_size = info->total_size;
20367 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20368 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20370 if (TARGET_FIX_AND_CONTINUE)
20372 /* gdb on darwin arranges to forward a function from the old
20373 address by modifying the first 5 instructions of the function
20374 to branch to the overriding function. This is necessary to
20375 permit function pointers that point to the old function to
20376 actually forward to the new function. */
20377 emit_insn (gen_nop ());
20378 emit_insn (gen_nop ());
20379 emit_insn (gen_nop ());
20380 emit_insn (gen_nop ());
20381 emit_insn (gen_nop ());
20384 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20386 reg_mode = V2SImode;
20390 strategy = info->savres_strategy;
20391 using_store_multiple = strategy & SAVRES_MULTIPLE;
20392 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20393 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20395 /* For V.4, update stack before we do any saving and set back pointer. */
20396 if (! WORLD_SAVE_P (info)
20398 && (DEFAULT_ABI == ABI_V4
20399 || crtl->calls_eh_return))
20401 bool need_r11 = (TARGET_SPE
20402 ? (!saving_GPRs_inline
20403 && info->spe_64bit_regs_used == 0)
20404 : (!saving_FPRs_inline || !saving_GPRs_inline));
20405 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20407 if (info->total_size < 32767)
20408 sp_offset = info->total_size;
20410 frame_reg_rtx = copy_reg;
20411 else if (info->cr_save_p
20413 || info->first_fp_reg_save < 64
20414 || info->first_gp_reg_save < 32
20415 || info->altivec_size != 0
20416 || info->vrsave_mask != 0
20417 || crtl->calls_eh_return)
20419 copy_reg = frame_ptr_rtx;
20420 frame_reg_rtx = copy_reg;
20424 /* The prologue won't be saving any regs so there is no need
20425 to set up a frame register to access any frame save area.
20426 We also won't be using sp_offset anywhere below, but set
20427 the correct value anyway to protect against future
20428 changes to this function. */
20429 sp_offset = info->total_size;
20431 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20432 if (frame_reg_rtx != sp_reg_rtx)
20433 rs6000_emit_stack_tie ();
20436 /* Handle world saves specially here. */
20437 if (WORLD_SAVE_P (info))
20444 /* save_world expects lr in r0. */
20445 reg0 = gen_rtx_REG (Pmode, 0);
20446 if (info->lr_save_p)
20448 insn = emit_move_insn (reg0,
20449 gen_rtx_REG (Pmode, LR_REGNO));
20450 RTX_FRAME_RELATED_P (insn) = 1;
20453 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20454 assumptions about the offsets of various bits of the stack
20456 gcc_assert (info->gp_save_offset == -220
20457 && info->fp_save_offset == -144
20458 && info->lr_save_offset == 8
20459 && info->cr_save_offset == 4
20462 && (!crtl->calls_eh_return
20463 || info->ehrd_offset == -432)
20464 && info->vrsave_save_offset == -224
20465 && info->altivec_save_offset == -416);
20467 treg = gen_rtx_REG (SImode, 11);
20468 emit_move_insn (treg, GEN_INT (-info->total_size));
20470 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20471 in R11. It also clobbers R12, so beware! */
20473 /* Preserve CR2 for save_world prologues */
20475 sz += 32 - info->first_gp_reg_save;
20476 sz += 64 - info->first_fp_reg_save;
20477 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20478 p = rtvec_alloc (sz);
20480 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20481 gen_rtx_REG (SImode,
20483 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20484 gen_rtx_SYMBOL_REF (Pmode,
20486 /* We do floats first so that the instruction pattern matches
20488 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20490 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20491 ? DFmode : SFmode),
20492 info->first_fp_reg_save + i);
20493 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20494 GEN_INT (info->fp_save_offset
20495 + sp_offset + 8 * i));
20496 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20497 ? DFmode : SFmode), addr);
20499 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20501 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20503 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20504 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20505 GEN_INT (info->altivec_save_offset
20506 + sp_offset + 16 * i));
20507 rtx mem = gen_frame_mem (V4SImode, addr);
20509 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20511 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20513 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20514 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20515 GEN_INT (info->gp_save_offset
20516 + sp_offset + reg_size * i));
20517 rtx mem = gen_frame_mem (reg_mode, addr);
20519 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20523 /* CR register traditionally saved as CR2. */
20524 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20525 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20526 GEN_INT (info->cr_save_offset
20528 rtx mem = gen_frame_mem (reg_mode, addr);
20530 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20532 /* Explain about use of R0. */
20533 if (info->lr_save_p)
20535 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20536 GEN_INT (info->lr_save_offset
20538 rtx mem = gen_frame_mem (reg_mode, addr);
20540 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20542 /* Explain what happens to the stack pointer. */
20544 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20545 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20548 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20549 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20550 treg, GEN_INT (-info->total_size));
20551 sp_offset = info->total_size;
20554 /* If we use the link register, get it into r0. */
20555 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20557 rtx addr, reg, mem;
20559 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20560 gen_rtx_REG (Pmode, LR_REGNO));
20561 RTX_FRAME_RELATED_P (insn) = 1;
20563 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20564 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20566 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20567 GEN_INT (info->lr_save_offset + sp_offset));
20568 reg = gen_rtx_REG (Pmode, 0);
20569 mem = gen_rtx_MEM (Pmode, addr);
20570 /* This should not be of rs6000_sr_alias_set, because of
20571 __builtin_return_address. */
20573 insn = emit_move_insn (mem, reg);
20574 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20575 NULL_RTX, NULL_RTX);
20579 /* If we need to save CR, put it into r12 or r11. */
20580 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20585 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20587 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20588 RTX_FRAME_RELATED_P (insn) = 1;
20589 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20590 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20591 But that's OK. All we have to do is specify that _one_ condition
20592 code register is saved in this stack slot. The thrower's epilogue
20593 will then restore all the call-saved registers.
20594 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20595 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20596 gen_rtx_REG (SImode, CR2_REGNO));
20597 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20600 /* Do any required saving of fpr's. If only one or two to save, do
20601 it ourselves. Otherwise, call function. */
20602 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20605 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20606 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20607 && ! call_used_regs[info->first_fp_reg_save+i]))
20608 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20609 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20611 info->first_fp_reg_save + i,
20612 info->fp_save_offset + sp_offset + 8 * i,
20615 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20619 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20620 info->fp_save_offset + sp_offset,
20622 /*savep=*/true, /*gpr=*/false,
20624 & SAVE_NOINLINE_FPRS_SAVES_LR)
20626 insn = emit_insn (par);
20627 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20628 NULL_RTX, NULL_RTX);
20631 /* Save GPRs. This is done as a PARALLEL if we are using
20632 the store-multiple instructions. */
20633 if (!WORLD_SAVE_P (info)
20635 && info->spe_64bit_regs_used != 0
20636 && info->first_gp_reg_save != 32)
20639 rtx spe_save_area_ptr;
20640 int save_ptr_to_sp;
20641 int ool_adjust = 0;
20643 /* Determine whether we can address all of the registers that need
20644 to be saved with an offset from frame_reg_rtx that fits in
20645 the small const field for SPE memory instructions. */
20646 int spe_regs_addressable
20647 = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset
20648 + reg_size * (32 - info->first_gp_reg_save - 1))
20649 && saving_GPRs_inline);
20652 if (spe_regs_addressable)
20654 spe_save_area_ptr = frame_reg_rtx;
20655 save_ptr_to_sp = info->total_size - sp_offset;
20656 spe_offset = info->spe_gp_save_offset + sp_offset;
20660 /* Make r11 point to the start of the SPE save area. We need
20661 to be careful here if r11 is holding the static chain. If
20662 it is, then temporarily save it in r0. */
20665 if (!saving_GPRs_inline)
20666 ool_adjust = 8 * (info->first_gp_reg_save
20667 - (FIRST_SAVRES_REGISTER + 1));
20668 offset = info->spe_gp_save_offset + sp_offset - ool_adjust;
20669 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20670 save_ptr_to_sp = info->total_size - sp_offset + offset;
20673 if (using_static_chain_p)
20675 rtx r0 = gen_rtx_REG (Pmode, 0);
20676 gcc_assert (info->first_gp_reg_save > 11);
20678 emit_move_insn (r0, spe_save_area_ptr);
20680 emit_insn (gen_addsi3 (spe_save_area_ptr,
20681 frame_reg_rtx, GEN_INT (offset)));
20682 if (REGNO (frame_reg_rtx) == 11)
20683 sp_offset = -info->spe_gp_save_offset + ool_adjust;
20686 if (saving_GPRs_inline)
20688 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20689 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20691 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20692 rtx offset, addr, mem;
20694 /* We're doing all this to ensure that the offset fits into
20695 the immediate offset of 'evstdd'. */
20696 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20698 offset = GEN_INT (reg_size * i + spe_offset);
20699 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20700 mem = gen_rtx_MEM (V2SImode, addr);
20702 insn = emit_move_insn (mem, reg);
20704 rs6000_frame_related (insn,
20705 spe_save_area_ptr, save_ptr_to_sp,
20706 NULL_RTX, NULL_RTX);
20713 par = rs6000_make_savres_rtx (info, spe_save_area_ptr,
20714 ool_adjust, reg_mode,
20715 /*savep=*/true, /*gpr=*/true,
20717 insn = emit_insn (par);
20718 rs6000_frame_related (insn, spe_save_area_ptr, save_ptr_to_sp,
20719 NULL_RTX, NULL_RTX);
20722 /* Move the static chain pointer back. */
20723 if (using_static_chain_p && !spe_regs_addressable)
20724 emit_move_insn (spe_save_area_ptr, gen_rtx_REG (Pmode, 0));
20726 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20730 /* Need to adjust r11 (r12) if we saved any FPRs. */
20731 if (info->first_fp_reg_save != 64)
20733 rtx dest_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11);
20734 int save_off = 8 * (64 - info->first_fp_reg_save);
20735 rtx offset = GEN_INT (sp_offset - save_off);
20737 if (REGNO (dest_reg) == REGNO (frame_reg_rtx))
20738 sp_offset = save_off;
20739 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20742 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20743 info->gp_save_offset + sp_offset,
20745 /*savep=*/true, /*gpr=*/true,
20747 & SAVE_NOINLINE_GPRS_SAVES_LR)
20749 insn = emit_insn (par);
20750 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20751 NULL_RTX, NULL_RTX);
20753 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20757 p = rtvec_alloc (32 - info->first_gp_reg_save);
20758 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20760 rtx addr, reg, mem;
20761 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20762 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20763 GEN_INT (info->gp_save_offset
20766 mem = gen_frame_mem (reg_mode, addr);
20768 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20770 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20771 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20772 NULL_RTX, NULL_RTX);
20774 else if (!WORLD_SAVE_P (info))
20777 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20778 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20780 rtx addr, reg, mem;
20781 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20783 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20784 GEN_INT (info->gp_save_offset
20787 mem = gen_frame_mem (reg_mode, addr);
20789 insn = emit_move_insn (mem, reg);
20790 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20791 NULL_RTX, NULL_RTX);
20795 /* ??? There's no need to emit actual instructions here, but it's the
20796 easiest way to get the frame unwind information emitted. */
20797 if (crtl->calls_eh_return)
20799 unsigned int i, regno;
20803 regno = EH_RETURN_DATA_REGNO (i);
20804 if (regno == INVALID_REGNUM)
20807 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20808 info->ehrd_offset + sp_offset
20809 + reg_size * (int) i,
20814 /* In AIX ABI we need to make sure r2 is really saved. */
20815 if (TARGET_AIX && crtl->calls_eh_return)
20817 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20818 long toc_restore_insn;
20820 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20821 || frame_reg_rtx == sp_reg_rtx);
20822 tmp_reg = gen_rtx_REG (Pmode, 11);
20823 tmp_reg_si = gen_rtx_REG (SImode, 11);
20824 if (using_static_chain_p)
20825 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20826 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20827 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20828 /* Peek at instruction to which this function returns. If it's
20829 restoring r2, then we know we've already saved r2. We can't
20830 unconditionally save r2 because the value we have will already
20831 be updated if we arrived at this function via a plt call or
20832 toc adjusting stub. */
20833 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20834 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20835 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20836 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20837 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20838 validate_condition_mode (EQ, CCUNSmode);
20839 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20840 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20841 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20842 toc_save_done = gen_label_rtx ();
20843 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20844 gen_rtx_EQ (VOIDmode, compare_result,
20846 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20848 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20849 JUMP_LABEL (jump) = toc_save_done;
20850 LABEL_NUSES (toc_save_done) += 1;
20852 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20853 sp_offset + 5 * reg_size, info->total_size);
20854 emit_label (toc_save_done);
20855 if (using_static_chain_p)
20856 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20859 /* Save CR if we use any that must be preserved. */
20860 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20862 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20863 GEN_INT (info->cr_save_offset + sp_offset));
20864 rtx mem = gen_frame_mem (SImode, addr);
20865 /* See the large comment above about why CR2_REGNO is used. */
20866 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20868 /* If r12 was used to hold the original sp, copy cr into r0 now
20870 if (REGNO (frame_reg_rtx) == 12)
20874 cr_save_rtx = gen_rtx_REG (SImode, 0);
20875 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20876 RTX_FRAME_RELATED_P (insn) = 1;
20877 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20878 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20880 insn = emit_move_insn (mem, cr_save_rtx);
20882 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20883 NULL_RTX, NULL_RTX);
20886 /* Update stack and set back pointer unless this is V.4,
20887 for which it was done previously. */
20888 if (!WORLD_SAVE_P (info) && info->push_p
20889 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20891 rtx copy_reg = NULL;
20893 if (info->total_size < 32767)
20894 sp_offset = info->total_size;
20895 else if (info->altivec_size != 0
20896 || info->vrsave_mask != 0)
20898 copy_reg = frame_ptr_rtx;
20899 frame_reg_rtx = copy_reg;
20902 sp_offset = info->total_size;
20903 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20904 if (frame_reg_rtx != sp_reg_rtx)
20905 rs6000_emit_stack_tie ();
20908 /* Set frame pointer, if needed. */
20909 if (frame_pointer_needed)
20911 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20913 RTX_FRAME_RELATED_P (insn) = 1;
20916 /* Save AltiVec registers if needed. Save here because the red zone does
20917 not include AltiVec registers. */
20918 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20922 /* There should be a non inline version of this, for when we
20923 are saving lots of vector registers. */
20924 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20925 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20927 rtx areg, savereg, mem;
20930 offset = info->altivec_save_offset + sp_offset
20931 + 16 * (i - info->first_altivec_reg_save);
20933 savereg = gen_rtx_REG (V4SImode, i);
20935 areg = gen_rtx_REG (Pmode, 0);
20936 emit_move_insn (areg, GEN_INT (offset));
20938 /* AltiVec addressing mode is [reg+reg]. */
20939 mem = gen_frame_mem (V4SImode,
20940 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20942 insn = emit_move_insn (mem, savereg);
20944 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20945 areg, GEN_INT (offset));
20949 /* VRSAVE is a bit vector representing which AltiVec registers
20950 are used. The OS uses this to determine which vector
20951 registers to save on a context switch. We need to save
20952 VRSAVE on the stack frame, add whatever AltiVec registers we
20953 used in this function, and do the corresponding magic in the
20956 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20957 && info->vrsave_mask != 0)
20959 rtx reg, mem, vrsave;
20962 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20963 as frame_reg_rtx and r11 as the static chain pointer for
20964 nested functions. */
20965 reg = gen_rtx_REG (SImode, 0);
20966 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20968 emit_insn (gen_get_vrsave_internal (reg));
20970 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20972 if (!WORLD_SAVE_P (info))
20975 offset = info->vrsave_save_offset + sp_offset;
20976 mem = gen_frame_mem (SImode,
20977 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20978 GEN_INT (offset)));
20979 insn = emit_move_insn (mem, reg);
20982 /* Include the registers in the mask. */
20983 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20985 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20988 if (TARGET_SINGLE_PIC_BASE)
20989 return; /* Do not set PIC register */
20991 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20992 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20993 || (DEFAULT_ABI == ABI_V4
20994 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20995 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20997 /* If emit_load_toc_table will use the link register, we need to save
20998 it. We use R12 for this purpose because emit_load_toc_table
20999 can use register 0. This allows us to use a plain 'blr' to return
21000 from the procedure more often. */
21001 int save_LR_around_toc_setup = (TARGET_ELF
21002 && DEFAULT_ABI != ABI_AIX
21004 && ! info->lr_save_p
21005 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
21006 if (save_LR_around_toc_setup)
21008 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21010 insn = emit_move_insn (frame_ptr_rtx, lr);
21011 RTX_FRAME_RELATED_P (insn) = 1;
21013 rs6000_emit_load_toc_table (TRUE);
21015 insn = emit_move_insn (lr, frame_ptr_rtx);
21016 RTX_FRAME_RELATED_P (insn) = 1;
21019 rs6000_emit_load_toc_table (TRUE);
21023 if (DEFAULT_ABI == ABI_DARWIN
21024 && flag_pic && crtl->uses_pic_offset_table)
21026 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21027 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
21029 /* Save and restore LR locally around this call (in R0). */
21030 if (!info->lr_save_p)
21031 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
21033 emit_insn (gen_load_macho_picbase (src));
21035 emit_move_insn (gen_rtx_REG (Pmode,
21036 RS6000_PIC_OFFSET_TABLE_REGNUM),
21039 if (!info->lr_save_p)
21040 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
21045 /* Write function prologue. */
21048 rs6000_output_function_prologue (FILE *file,
21049 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21051 rs6000_stack_t *info = rs6000_stack_info ();
21053 if (TARGET_DEBUG_STACK)
21054 debug_stack_info (info);
21056 /* Write .extern for any function we will call to save and restore
21058 if (info->first_fp_reg_save < 64)
21061 int regno = info->first_fp_reg_save - 32;
21063 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
21065 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
21066 /*gpr=*/false, /*lr=*/false);
21067 fprintf (file, "\t.extern %s\n", name);
21069 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
21071 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
21072 /*gpr=*/false, /*lr=*/true);
21073 fprintf (file, "\t.extern %s\n", name);
21077 /* Write .extern for AIX common mode routines, if needed. */
21078 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21080 fputs ("\t.extern __mulh\n", file);
21081 fputs ("\t.extern __mull\n", file);
21082 fputs ("\t.extern __divss\n", file);
21083 fputs ("\t.extern __divus\n", file);
21084 fputs ("\t.extern __quoss\n", file);
21085 fputs ("\t.extern __quous\n", file);
21086 common_mode_defined = 1;
21089 if (! HAVE_prologue)
21095 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21096 the "toplevel" insn chain. */
21097 emit_note (NOTE_INSN_DELETED);
21098 rs6000_emit_prologue ();
21099 emit_note (NOTE_INSN_DELETED);
21101 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21105 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21107 INSN_ADDRESSES_NEW (insn, addr);
21112 prologue = get_insns ();
21115 if (TARGET_DEBUG_STACK)
21116 debug_rtx_list (prologue, 100);
21118 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21122 rs6000_pic_labelno++;
21125 /* Non-zero if vmx regs are restored before the frame pop, zero if
21126 we restore after the pop when possible. */
21127 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21129 /* Reload CR from REG. */
21132 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21137 if (using_mfcr_multiple)
21139 for (i = 0; i < 8; i++)
21140 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21142 gcc_assert (count);
21145 if (using_mfcr_multiple && count > 1)
21150 p = rtvec_alloc (count);
21153 for (i = 0; i < 8; i++)
21154 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21156 rtvec r = rtvec_alloc (2);
21157 RTVEC_ELT (r, 0) = reg;
21158 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21159 RTVEC_ELT (p, ndx) =
21160 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21161 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21164 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21165 gcc_assert (ndx == count);
21168 for (i = 0; i < 8; i++)
21169 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21171 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21177 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21178 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21179 below stack pointer not cloberred by signals. */
21182 offset_below_red_zone_p (HOST_WIDE_INT offset)
21184 return offset < (DEFAULT_ABI == ABI_V4
21186 : TARGET_32BIT ? -220 : -288);
21189 /* Emit function epilogue as insns. */
21192 rs6000_emit_epilogue (int sibcall)
21194 rs6000_stack_t *info;
21195 int restoring_GPRs_inline;
21196 int restoring_FPRs_inline;
21197 int using_load_multiple;
21198 int using_mtcr_multiple;
21199 int use_backchain_to_restore_sp;
21203 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21204 rtx frame_reg_rtx = sp_reg_rtx;
21205 rtx cfa_restores = NULL_RTX;
21207 rtx cr_save_reg = NULL_RTX;
21208 enum machine_mode reg_mode = Pmode;
21209 int reg_size = TARGET_32BIT ? 4 : 8;
21212 info = rs6000_stack_info ();
21214 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21216 reg_mode = V2SImode;
21220 strategy = info->savres_strategy;
21221 using_load_multiple = strategy & SAVRES_MULTIPLE;
21222 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21223 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21224 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21225 || rs6000_cpu == PROCESSOR_PPC603
21226 || rs6000_cpu == PROCESSOR_PPC750
21228 /* Restore via the backchain when we have a large frame, since this
21229 is more efficient than an addis, addi pair. The second condition
21230 here will not trigger at the moment; We don't actually need a
21231 frame pointer for alloca, but the generic parts of the compiler
21232 give us one anyway. */
21233 use_backchain_to_restore_sp = (info->total_size > 32767
21234 || info->total_size
21235 + (info->lr_save_p ? info->lr_save_offset : 0)
21237 || (cfun->calls_alloca
21238 && !frame_pointer_needed));
21239 restore_lr = (info->lr_save_p
21240 && (restoring_FPRs_inline
21241 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21242 && (restoring_GPRs_inline
21243 || info->first_fp_reg_save < 64));
21245 if (WORLD_SAVE_P (info))
21249 const char *alloc_rname;
21252 /* eh_rest_world_r10 will return to the location saved in the LR
21253 stack slot (which is not likely to be our caller.)
21254 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21255 rest_world is similar, except any R10 parameter is ignored.
21256 The exception-handling stuff that was here in 2.95 is no
21257 longer necessary. */
21261 + 32 - info->first_gp_reg_save
21262 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21263 + 63 + 1 - info->first_fp_reg_save);
21265 strcpy (rname, ((crtl->calls_eh_return) ?
21266 "*eh_rest_world_r10" : "*rest_world"));
21267 alloc_rname = ggc_strdup (rname);
21270 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21271 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21272 gen_rtx_REG (Pmode,
21275 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21276 /* The instruction pattern requires a clobber here;
21277 it is shared with the restVEC helper. */
21279 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21282 /* CR register traditionally saved as CR2. */
21283 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21284 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21285 GEN_INT (info->cr_save_offset));
21286 rtx mem = gen_frame_mem (reg_mode, addr);
21288 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21291 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21293 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21294 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21295 GEN_INT (info->gp_save_offset
21297 rtx mem = gen_frame_mem (reg_mode, addr);
21299 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21301 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21303 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21304 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21305 GEN_INT (info->altivec_save_offset
21307 rtx mem = gen_frame_mem (V4SImode, addr);
21309 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21311 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21313 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21314 ? DFmode : SFmode),
21315 info->first_fp_reg_save + i);
21316 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21317 GEN_INT (info->fp_save_offset
21319 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21320 ? DFmode : SFmode), addr);
21322 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21325 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21327 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21329 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21331 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21333 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21334 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21339 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21341 sp_offset = info->total_size;
21343 /* Restore AltiVec registers if we must do so before adjusting the
21345 if (TARGET_ALTIVEC_ABI
21346 && info->altivec_size != 0
21347 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21348 || (DEFAULT_ABI != ABI_V4
21349 && offset_below_red_zone_p (info->altivec_save_offset))))
21353 if (use_backchain_to_restore_sp)
21355 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21356 emit_move_insn (frame_reg_rtx,
21357 gen_rtx_MEM (Pmode, sp_reg_rtx));
21360 else if (frame_pointer_needed)
21361 frame_reg_rtx = hard_frame_pointer_rtx;
21363 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21364 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21366 rtx addr, areg, mem, reg;
21368 areg = gen_rtx_REG (Pmode, 0);
21370 (areg, GEN_INT (info->altivec_save_offset
21372 + 16 * (i - info->first_altivec_reg_save)));
21374 /* AltiVec addressing mode is [reg+reg]. */
21375 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21376 mem = gen_frame_mem (V4SImode, addr);
21378 reg = gen_rtx_REG (V4SImode, i);
21379 emit_move_insn (reg, mem);
21380 if (offset_below_red_zone_p (info->altivec_save_offset
21381 + (i - info->first_altivec_reg_save)
21383 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21388 /* Restore VRSAVE if we must do so before adjusting the stack. */
21390 && TARGET_ALTIVEC_VRSAVE
21391 && info->vrsave_mask != 0
21392 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21393 || (DEFAULT_ABI != ABI_V4
21394 && offset_below_red_zone_p (info->vrsave_save_offset))))
21396 rtx addr, mem, reg;
21398 if (frame_reg_rtx == sp_reg_rtx)
21400 if (use_backchain_to_restore_sp)
21402 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21403 emit_move_insn (frame_reg_rtx,
21404 gen_rtx_MEM (Pmode, sp_reg_rtx));
21407 else if (frame_pointer_needed)
21408 frame_reg_rtx = hard_frame_pointer_rtx;
21411 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21412 GEN_INT (info->vrsave_save_offset + sp_offset));
21413 mem = gen_frame_mem (SImode, addr);
21414 reg = gen_rtx_REG (SImode, 12);
21415 emit_move_insn (reg, mem);
21417 emit_insn (generate_set_vrsave (reg, info, 1));
21421 /* If we have a large stack frame, restore the old stack pointer
21422 using the backchain. */
21423 if (use_backchain_to_restore_sp)
21425 if (frame_reg_rtx == sp_reg_rtx)
21427 /* Under V.4, don't reset the stack pointer until after we're done
21428 loading the saved registers. */
21429 if (DEFAULT_ABI == ABI_V4)
21430 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21432 insn = emit_move_insn (frame_reg_rtx,
21433 gen_rtx_MEM (Pmode, sp_reg_rtx));
21436 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21437 && DEFAULT_ABI == ABI_V4)
21438 /* frame_reg_rtx has been set up by the altivec restore. */
21442 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21443 frame_reg_rtx = sp_reg_rtx;
21446 /* If we have a frame pointer, we can restore the old stack pointer
21448 else if (frame_pointer_needed)
21450 frame_reg_rtx = sp_reg_rtx;
21451 if (DEFAULT_ABI == ABI_V4)
21452 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21453 /* Prevent reordering memory accesses against stack pointer restore. */
21454 else if (cfun->calls_alloca
21455 || offset_below_red_zone_p (-info->total_size))
21457 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21458 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21459 MEM_NOTRAP_P (mem1) = 1;
21460 MEM_NOTRAP_P (mem2) = 1;
21461 emit_insn (gen_frame_tie (mem1, mem2));
21464 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21465 GEN_INT (info->total_size)));
21468 else if (info->push_p
21469 && DEFAULT_ABI != ABI_V4
21470 && !crtl->calls_eh_return)
21472 /* Prevent reordering memory accesses against stack pointer restore. */
21473 if (cfun->calls_alloca
21474 || offset_below_red_zone_p (-info->total_size))
21476 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21477 MEM_NOTRAP_P (mem) = 1;
21478 emit_insn (gen_stack_tie (mem));
21480 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21481 GEN_INT (info->total_size)));
21484 if (insn && frame_reg_rtx == sp_reg_rtx)
21488 REG_NOTES (insn) = cfa_restores;
21489 cfa_restores = NULL_RTX;
21491 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21492 RTX_FRAME_RELATED_P (insn) = 1;
21495 /* Restore AltiVec registers if we have not done so already. */
21496 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21497 && TARGET_ALTIVEC_ABI
21498 && info->altivec_size != 0
21499 && (DEFAULT_ABI == ABI_V4
21500 || !offset_below_red_zone_p (info->altivec_save_offset)))
21504 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21505 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21507 rtx addr, areg, mem, reg;
21509 areg = gen_rtx_REG (Pmode, 0);
21511 (areg, GEN_INT (info->altivec_save_offset
21513 + 16 * (i - info->first_altivec_reg_save)));
21515 /* AltiVec addressing mode is [reg+reg]. */
21516 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21517 mem = gen_frame_mem (V4SImode, addr);
21519 reg = gen_rtx_REG (V4SImode, i);
21520 emit_move_insn (reg, mem);
21521 if (DEFAULT_ABI == ABI_V4)
21522 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21527 /* Restore VRSAVE if we have not done so already. */
21528 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21530 && TARGET_ALTIVEC_VRSAVE
21531 && info->vrsave_mask != 0
21532 && (DEFAULT_ABI == ABI_V4
21533 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21535 rtx addr, mem, reg;
21537 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21538 GEN_INT (info->vrsave_save_offset + sp_offset));
21539 mem = gen_frame_mem (SImode, addr);
21540 reg = gen_rtx_REG (SImode, 12);
21541 emit_move_insn (reg, mem);
21543 emit_insn (generate_set_vrsave (reg, info, 1));
21546 /* Get the old lr if we saved it. If we are restoring registers
21547 out-of-line, then the out-of-line routines can do this for us. */
21548 if (restore_lr && restoring_GPRs_inline)
21550 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21551 info->lr_save_offset + sp_offset);
21553 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21556 /* Get the old cr if we saved it. */
21557 if (info->cr_save_p)
21559 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21560 GEN_INT (info->cr_save_offset + sp_offset));
21561 rtx mem = gen_frame_mem (SImode, addr);
21563 cr_save_reg = gen_rtx_REG (SImode,
21564 DEFAULT_ABI == ABI_AIX
21565 && !restoring_GPRs_inline
21566 && info->first_fp_reg_save < 64
21568 emit_move_insn (cr_save_reg, mem);
21571 /* Set LR here to try to overlap restores below. LR is always saved
21572 above incoming stack, so it never needs REG_CFA_RESTORE. */
21573 if (restore_lr && restoring_GPRs_inline)
21574 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21575 gen_rtx_REG (Pmode, 0));
21577 /* Load exception handler data registers, if needed. */
21578 if (crtl->calls_eh_return)
21580 unsigned int i, regno;
21584 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21585 GEN_INT (sp_offset + 5 * reg_size));
21586 rtx mem = gen_frame_mem (reg_mode, addr);
21588 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21595 regno = EH_RETURN_DATA_REGNO (i);
21596 if (regno == INVALID_REGNUM)
21599 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21600 info->ehrd_offset + sp_offset
21601 + reg_size * (int) i);
21603 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21607 /* Restore GPRs. This is done as a PARALLEL if we are using
21608 the load-multiple instructions. */
21610 && info->spe_64bit_regs_used != 0
21611 && info->first_gp_reg_save != 32)
21613 /* Determine whether we can address all of the registers that need
21614 to be saved with an offset from frame_reg_rtx that fits in
21615 the small const field for SPE memory instructions. */
21616 int spe_regs_addressable
21617 = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset
21618 + reg_size * (32 - info->first_gp_reg_save - 1))
21619 && restoring_GPRs_inline);
21621 int ool_adjust = 0;
21623 if (spe_regs_addressable)
21624 spe_offset = info->spe_gp_save_offset + sp_offset;
21627 rtx old_frame_reg_rtx = frame_reg_rtx;
21628 /* Make r11 point to the start of the SPE save area. We worried about
21629 not clobbering it when we were saving registers in the prologue.
21630 There's no need to worry here because the static chain is passed
21631 anew to every function. */
21633 if (!restoring_GPRs_inline)
21634 ool_adjust = 8 * (info->first_gp_reg_save
21635 - (FIRST_SAVRES_REGISTER + 1));
21636 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21637 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21638 GEN_INT (info->spe_gp_save_offset
21641 /* Keep the invariant that frame_reg_rtx + sp_offset points
21642 at the top of the stack frame. */
21643 sp_offset = -info->spe_gp_save_offset + ool_adjust;
21648 if (restoring_GPRs_inline)
21650 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21651 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21653 rtx offset, addr, mem, reg;
21655 /* We're doing all this to ensure that the immediate offset
21656 fits into the immediate field of 'evldd'. */
21657 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21659 offset = GEN_INT (spe_offset + reg_size * i);
21660 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21661 mem = gen_rtx_MEM (V2SImode, addr);
21662 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21664 insn = emit_move_insn (reg, mem);
21665 if (DEFAULT_ABI == ABI_V4)
21667 if (frame_pointer_needed
21668 && info->first_gp_reg_save + i
21669 == HARD_FRAME_POINTER_REGNUM)
21671 add_reg_note (insn, REG_CFA_DEF_CFA,
21672 plus_constant (frame_reg_rtx,
21674 RTX_FRAME_RELATED_P (insn) = 1;
21677 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21686 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21687 ool_adjust, reg_mode,
21688 /*savep=*/false, /*gpr=*/true,
21690 emit_jump_insn (par);
21691 /* We don't want anybody else emitting things after we jumped
21696 else if (!restoring_GPRs_inline)
21698 /* We are jumping to an out-of-line function. */
21699 bool can_use_exit = info->first_fp_reg_save == 64;
21702 /* Emit stack reset code if we need it. */
21704 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21705 sp_offset, can_use_exit);
21708 rtx src_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11);
21710 emit_insn (gen_add3_insn (src_reg, frame_reg_rtx,
21711 GEN_INT (sp_offset - info->fp_size)));
21712 if (REGNO (frame_reg_rtx) == REGNO (src_reg))
21713 sp_offset = info->fp_size;
21716 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21717 info->gp_save_offset, reg_mode,
21718 /*savep=*/false, /*gpr=*/true,
21719 /*lr=*/can_use_exit);
21723 if (info->cr_save_p)
21725 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21726 if (DEFAULT_ABI == ABI_V4)
21728 = alloc_reg_note (REG_CFA_RESTORE,
21729 gen_rtx_REG (SImode, CR2_REGNO),
21733 emit_jump_insn (par);
21735 /* We don't want anybody else emitting things after we jumped
21740 insn = emit_insn (par);
21741 if (DEFAULT_ABI == ABI_V4)
21743 if (frame_pointer_needed)
21745 add_reg_note (insn, REG_CFA_DEF_CFA,
21746 plus_constant (frame_reg_rtx, sp_offset));
21747 RTX_FRAME_RELATED_P (insn) = 1;
21750 for (i = info->first_gp_reg_save; i < 32; i++)
21752 = alloc_reg_note (REG_CFA_RESTORE,
21753 gen_rtx_REG (reg_mode, i), cfa_restores);
21756 else if (using_load_multiple)
21759 p = rtvec_alloc (32 - info->first_gp_reg_save);
21760 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21762 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21763 GEN_INT (info->gp_save_offset
21766 rtx mem = gen_frame_mem (reg_mode, addr);
21767 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21769 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21770 if (DEFAULT_ABI == ABI_V4)
21771 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21774 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21775 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21777 add_reg_note (insn, REG_CFA_DEF_CFA,
21778 plus_constant (frame_reg_rtx, sp_offset));
21779 RTX_FRAME_RELATED_P (insn) = 1;
21784 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21785 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21787 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21788 GEN_INT (info->gp_save_offset
21791 rtx mem = gen_frame_mem (reg_mode, addr);
21792 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21794 insn = emit_move_insn (reg, mem);
21795 if (DEFAULT_ABI == ABI_V4)
21797 if (frame_pointer_needed
21798 && info->first_gp_reg_save + i
21799 == HARD_FRAME_POINTER_REGNUM)
21801 add_reg_note (insn, REG_CFA_DEF_CFA,
21802 plus_constant (frame_reg_rtx, sp_offset));
21803 RTX_FRAME_RELATED_P (insn) = 1;
21806 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21812 if (restore_lr && !restoring_GPRs_inline)
21814 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21815 info->lr_save_offset + sp_offset);
21817 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21818 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21819 gen_rtx_REG (Pmode, 0));
21822 /* Restore fpr's if we need to do it without calling a function. */
21823 if (restoring_FPRs_inline)
21824 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21825 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21826 && ! call_used_regs[info->first_fp_reg_save+i]))
21828 rtx addr, mem, reg;
21829 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21830 GEN_INT (info->fp_save_offset
21833 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21834 ? DFmode : SFmode), addr);
21835 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21836 ? DFmode : SFmode),
21837 info->first_fp_reg_save + i);
21839 emit_move_insn (reg, mem);
21840 if (DEFAULT_ABI == ABI_V4)
21841 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21845 /* If we saved cr, restore it here. Just those that were used. */
21846 if (info->cr_save_p)
21848 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21849 if (DEFAULT_ABI == ABI_V4)
21851 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21855 /* If this is V.4, unwind the stack pointer after all of the loads
21857 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21858 sp_offset, !restoring_FPRs_inline);
21863 REG_NOTES (insn) = cfa_restores;
21864 cfa_restores = NULL_RTX;
21866 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21867 RTX_FRAME_RELATED_P (insn) = 1;
21870 if (crtl->calls_eh_return)
21872 rtx sa = EH_RETURN_STACKADJ_RTX;
21873 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21879 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21880 if (! restoring_FPRs_inline)
21881 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21883 p = rtvec_alloc (2);
21885 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21886 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21887 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21888 : gen_rtx_CLOBBER (VOIDmode,
21889 gen_rtx_REG (Pmode, 65)));
21891 /* If we have to restore more than two FP registers, branch to the
21892 restore function. It will return to our caller. */
21893 if (! restoring_FPRs_inline)
21898 sym = rs6000_savres_routine_sym (info,
21902 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21903 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21904 gen_rtx_REG (Pmode,
21905 DEFAULT_ABI == ABI_AIX
21907 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21910 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21911 GEN_INT (info->fp_save_offset + 8*i));
21912 mem = gen_frame_mem (DFmode, addr);
21914 RTVEC_ELT (p, i+4) =
21915 gen_rtx_SET (VOIDmode,
21916 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21921 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21925 /* Write function epilogue. */
21928 rs6000_output_function_epilogue (FILE *file,
21929 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21931 if (! HAVE_epilogue)
21933 rtx insn = get_last_insn ();
21934 /* If the last insn was a BARRIER, we don't have to write anything except
21935 the trace table. */
21936 if (GET_CODE (insn) == NOTE)
21937 insn = prev_nonnote_insn (insn);
21938 if (insn == 0 || GET_CODE (insn) != BARRIER)
21940 /* This is slightly ugly, but at least we don't have two
21941 copies of the epilogue-emitting code. */
21944 /* A NOTE_INSN_DELETED is supposed to be at the start
21945 and end of the "toplevel" insn chain. */
21946 emit_note (NOTE_INSN_DELETED);
21947 rs6000_emit_epilogue (FALSE);
21948 emit_note (NOTE_INSN_DELETED);
21950 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21954 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21956 INSN_ADDRESSES_NEW (insn, addr);
21961 if (TARGET_DEBUG_STACK)
21962 debug_rtx_list (get_insns (), 100);
21963 final (get_insns (), file, FALSE);
21969 macho_branch_islands ();
21970 /* Mach-O doesn't support labels at the end of objects, so if
21971 it looks like we might want one, insert a NOP. */
21973 rtx insn = get_last_insn ();
21976 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21977 insn = PREV_INSN (insn);
21981 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21982 fputs ("\tnop\n", file);
21986 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21989 We don't output a traceback table if -finhibit-size-directive was
21990 used. The documentation for -finhibit-size-directive reads
21991 ``don't output a @code{.size} assembler directive, or anything
21992 else that would cause trouble if the function is split in the
21993 middle, and the two halves are placed at locations far apart in
21994 memory.'' The traceback table has this property, since it
21995 includes the offset from the start of the function to the
21996 traceback table itself.
21998 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21999 different traceback table. */
22000 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
22001 && rs6000_traceback != traceback_none && !cfun->is_thunk)
22003 const char *fname = NULL;
22004 const char *language_string = lang_hooks.name;
22005 int fixed_parms = 0, float_parms = 0, parm_info = 0;
22007 int optional_tbtab;
22008 rs6000_stack_t *info = rs6000_stack_info ();
22010 if (rs6000_traceback == traceback_full)
22011 optional_tbtab = 1;
22012 else if (rs6000_traceback == traceback_part)
22013 optional_tbtab = 0;
22015 optional_tbtab = !optimize_size && !TARGET_ELF;
22017 if (optional_tbtab)
22019 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
22020 while (*fname == '.') /* V.4 encodes . in the name */
22023 /* Need label immediately before tbtab, so we can compute
22024 its offset from the function start. */
22025 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22026 ASM_OUTPUT_LABEL (file, fname);
22029 /* The .tbtab pseudo-op can only be used for the first eight
22030 expressions, since it can't handle the possibly variable
22031 length fields that follow. However, if you omit the optional
22032 fields, the assembler outputs zeros for all optional fields
22033 anyways, giving each variable length field is minimum length
22034 (as defined in sys/debug.h). Thus we can not use the .tbtab
22035 pseudo-op at all. */
22037 /* An all-zero word flags the start of the tbtab, for debuggers
22038 that have to find it by searching forward from the entry
22039 point or from the current pc. */
22040 fputs ("\t.long 0\n", file);
22042 /* Tbtab format type. Use format type 0. */
22043 fputs ("\t.byte 0,", file);
22045 /* Language type. Unfortunately, there does not seem to be any
22046 official way to discover the language being compiled, so we
22047 use language_string.
22048 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22049 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22050 a number, so for now use 9. LTO isn't assigned a number either,
22051 so for now use 0. */
22052 if (! strcmp (language_string, "GNU C")
22053 || ! strcmp (language_string, "GNU GIMPLE"))
22055 else if (! strcmp (language_string, "GNU F77")
22056 || ! strcmp (language_string, "GNU Fortran"))
22058 else if (! strcmp (language_string, "GNU Pascal"))
22060 else if (! strcmp (language_string, "GNU Ada"))
22062 else if (! strcmp (language_string, "GNU C++")
22063 || ! strcmp (language_string, "GNU Objective-C++"))
22065 else if (! strcmp (language_string, "GNU Java"))
22067 else if (! strcmp (language_string, "GNU Objective-C"))
22070 gcc_unreachable ();
22071 fprintf (file, "%d,", i);
22073 /* 8 single bit fields: global linkage (not set for C extern linkage,
22074 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22075 from start of procedure stored in tbtab, internal function, function
22076 has controlled storage, function has no toc, function uses fp,
22077 function logs/aborts fp operations. */
22078 /* Assume that fp operations are used if any fp reg must be saved. */
22079 fprintf (file, "%d,",
22080 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22082 /* 6 bitfields: function is interrupt handler, name present in
22083 proc table, function calls alloca, on condition directives
22084 (controls stack walks, 3 bits), saves condition reg, saves
22086 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22087 set up as a frame pointer, even when there is no alloca call. */
22088 fprintf (file, "%d,",
22089 ((optional_tbtab << 6)
22090 | ((optional_tbtab & frame_pointer_needed) << 5)
22091 | (info->cr_save_p << 1)
22092 | (info->lr_save_p)));
22094 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22096 fprintf (file, "%d,",
22097 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22099 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22100 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22102 if (optional_tbtab)
22104 /* Compute the parameter info from the function decl argument
22107 int next_parm_info_bit = 31;
22109 for (decl = DECL_ARGUMENTS (current_function_decl);
22110 decl; decl = DECL_CHAIN (decl))
22112 rtx parameter = DECL_INCOMING_RTL (decl);
22113 enum machine_mode mode = GET_MODE (parameter);
22115 if (GET_CODE (parameter) == REG)
22117 if (SCALAR_FLOAT_MODE_P (mode))
22138 gcc_unreachable ();
22141 /* If only one bit will fit, don't or in this entry. */
22142 if (next_parm_info_bit > 0)
22143 parm_info |= (bits << (next_parm_info_bit - 1));
22144 next_parm_info_bit -= 2;
22148 fixed_parms += ((GET_MODE_SIZE (mode)
22149 + (UNITS_PER_WORD - 1))
22151 next_parm_info_bit -= 1;
22157 /* Number of fixed point parameters. */
22158 /* This is actually the number of words of fixed point parameters; thus
22159 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22160 fprintf (file, "%d,", fixed_parms);
22162 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22164 /* This is actually the number of fp registers that hold parameters;
22165 and thus the maximum value is 13. */
22166 /* Set parameters on stack bit if parameters are not in their original
22167 registers, regardless of whether they are on the stack? Xlc
22168 seems to set the bit when not optimizing. */
22169 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22171 if (! optional_tbtab)
22174 /* Optional fields follow. Some are variable length. */
22176 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22177 11 double float. */
22178 /* There is an entry for each parameter in a register, in the order that
22179 they occur in the parameter list. Any intervening arguments on the
22180 stack are ignored. If the list overflows a long (max possible length
22181 34 bits) then completely leave off all elements that don't fit. */
22182 /* Only emit this long if there was at least one parameter. */
22183 if (fixed_parms || float_parms)
22184 fprintf (file, "\t.long %d\n", parm_info);
22186 /* Offset from start of code to tb table. */
22187 fputs ("\t.long ", file);
22188 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22189 RS6000_OUTPUT_BASENAME (file, fname);
22191 rs6000_output_function_entry (file, fname);
22194 /* Interrupt handler mask. */
22195 /* Omit this long, since we never set the interrupt handler bit
22198 /* Number of CTL (controlled storage) anchors. */
22199 /* Omit this long, since the has_ctl bit is never set above. */
22201 /* Displacement into stack of each CTL anchor. */
22202 /* Omit this list of longs, because there are no CTL anchors. */
22204 /* Length of function name. */
22207 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22209 /* Function name. */
22210 assemble_string (fname, strlen (fname));
22212 /* Register for alloca automatic storage; this is always reg 31.
22213 Only emit this if the alloca bit was set above. */
22214 if (frame_pointer_needed)
22215 fputs ("\t.byte 31\n", file);
22217 fputs ("\t.align 2\n", file);
22221 /* A C compound statement that outputs the assembler code for a thunk
22222 function, used to implement C++ virtual function calls with
22223 multiple inheritance. The thunk acts as a wrapper around a virtual
22224 function, adjusting the implicit object parameter before handing
22225 control off to the real function.
22227 First, emit code to add the integer DELTA to the location that
22228 contains the incoming first argument. Assume that this argument
22229 contains a pointer, and is the one used to pass the `this' pointer
22230 in C++. This is the incoming argument *before* the function
22231 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22232 values of all other incoming arguments.
22234 After the addition, emit code to jump to FUNCTION, which is a
22235 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22236 not touch the return address. Hence returning from FUNCTION will
22237 return to whoever called the current `thunk'.
22239 The effect must be as if FUNCTION had been called directly with the
22240 adjusted first argument. This macro is responsible for emitting
22241 all of the code for a thunk function; output_function_prologue()
22242 and output_function_epilogue() are not invoked.
22244 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22245 been extracted from it.) It might possibly be useful on some
22246 targets, but probably not.
22248 If you do not define this macro, the target-independent code in the
22249 C++ frontend will generate a less efficient heavyweight thunk that
22250 calls FUNCTION instead of jumping to it. The generic approach does
22251 not support varargs. */
22254 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22255 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22258 rtx this_rtx, insn, funexp;
22260 reload_completed = 1;
22261 epilogue_completed = 1;
22263 /* Mark the end of the (empty) prologue. */
22264 emit_note (NOTE_INSN_PROLOGUE_END);
22266 /* Find the "this" pointer. If the function returns a structure,
22267 the structure return pointer is in r3. */
22268 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22269 this_rtx = gen_rtx_REG (Pmode, 4);
22271 this_rtx = gen_rtx_REG (Pmode, 3);
22273 /* Apply the constant offset, if required. */
22275 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22277 /* Apply the offset from the vtable, if required. */
22280 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22281 rtx tmp = gen_rtx_REG (Pmode, 12);
22283 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22284 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22286 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22287 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22291 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22293 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22295 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22298 /* Generate a tail call to the target function. */
22299 if (!TREE_USED (function))
22301 assemble_external (function);
22302 TREE_USED (function) = 1;
22304 funexp = XEXP (DECL_RTL (function), 0);
22305 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22308 if (MACHOPIC_INDIRECT)
22309 funexp = machopic_indirect_call_target (funexp);
22312 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22313 generate sibcall RTL explicitly. */
22314 insn = emit_call_insn (
22315 gen_rtx_PARALLEL (VOIDmode,
22317 gen_rtx_CALL (VOIDmode,
22318 funexp, const0_rtx),
22319 gen_rtx_USE (VOIDmode, const0_rtx),
22320 gen_rtx_USE (VOIDmode,
22321 gen_rtx_REG (SImode,
22323 gen_rtx_RETURN (VOIDmode))));
22324 SIBLING_CALL_P (insn) = 1;
22327 /* Run just enough of rest_of_compilation to get the insns emitted.
22328 There's not really enough bulk here to make other passes such as
22329 instruction scheduling worth while. Note that use_thunk calls
22330 assemble_start_function and assemble_end_function. */
22331 insn = get_insns ();
22332 insn_locators_alloc ();
22333 shorten_branches (insn);
22334 final_start_function (insn, file, 1);
22335 final (insn, file, 1);
22336 final_end_function ();
22338 reload_completed = 0;
22339 epilogue_completed = 0;
22342 /* A quick summary of the various types of 'constant-pool tables'
22345 Target Flags Name One table per
22346 AIX (none) AIX TOC object file
22347 AIX -mfull-toc AIX TOC object file
22348 AIX -mminimal-toc AIX minimal TOC translation unit
22349 SVR4/EABI (none) SVR4 SDATA object file
22350 SVR4/EABI -fpic SVR4 pic object file
22351 SVR4/EABI -fPIC SVR4 PIC translation unit
22352 SVR4/EABI -mrelocatable EABI TOC function
22353 SVR4/EABI -maix AIX TOC object file
22354 SVR4/EABI -maix -mminimal-toc
22355 AIX minimal TOC translation unit
22357 Name Reg. Set by entries contains:
22358 made by addrs? fp? sum?
22360 AIX TOC 2 crt0 as Y option option
22361 AIX minimal TOC 30 prolog gcc Y Y option
22362 SVR4 SDATA 13 crt0 gcc N Y N
22363 SVR4 pic 30 prolog ld Y not yet N
22364 SVR4 PIC 30 prolog gcc Y option option
22365 EABI TOC 30 prolog gcc Y option option
22369 /* Hash functions for the hash table. */
22372 rs6000_hash_constant (rtx k)
22374 enum rtx_code code = GET_CODE (k);
22375 enum machine_mode mode = GET_MODE (k);
22376 unsigned result = (code << 3) ^ mode;
22377 const char *format;
22380 format = GET_RTX_FORMAT (code);
22381 flen = strlen (format);
22387 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22390 if (mode != VOIDmode)
22391 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22403 for (; fidx < flen; fidx++)
22404 switch (format[fidx])
22409 const char *str = XSTR (k, fidx);
22410 len = strlen (str);
22411 result = result * 613 + len;
22412 for (i = 0; i < len; i++)
22413 result = result * 613 + (unsigned) str[i];
22418 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22422 result = result * 613 + (unsigned) XINT (k, fidx);
22425 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22426 result = result * 613 + (unsigned) XWINT (k, fidx);
22430 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22431 result = result * 613 + (unsigned) (XWINT (k, fidx)
22438 gcc_unreachable ();
22445 toc_hash_function (const void *hash_entry)
22447 const struct toc_hash_struct *thc =
22448 (const struct toc_hash_struct *) hash_entry;
22449 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22452 /* Compare H1 and H2 for equivalence. */
22455 toc_hash_eq (const void *h1, const void *h2)
22457 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22458 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22460 if (((const struct toc_hash_struct *) h1)->key_mode
22461 != ((const struct toc_hash_struct *) h2)->key_mode)
22464 return rtx_equal_p (r1, r2);
22467 /* These are the names given by the C++ front-end to vtables, and
22468 vtable-like objects. Ideally, this logic should not be here;
22469 instead, there should be some programmatic way of inquiring as
22470 to whether or not an object is a vtable. */
22472 #define VTABLE_NAME_P(NAME) \
22473 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22474 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22475 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22476 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22477 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22479 #ifdef NO_DOLLAR_IN_LABEL
22480 /* Return a GGC-allocated character string translating dollar signs in
22481 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22484 rs6000_xcoff_strip_dollar (const char *name)
22489 p = strchr (name, '$');
22491 if (p == 0 || p == name)
22494 len = strlen (name);
22495 strip = (char *) alloca (len + 1);
22496 strcpy (strip, name);
22497 p = strchr (strip, '$');
22501 p = strchr (p + 1, '$');
22504 return ggc_alloc_string (strip, len);
22509 rs6000_output_symbol_ref (FILE *file, rtx x)
22511 /* Currently C++ toc references to vtables can be emitted before it
22512 is decided whether the vtable is public or private. If this is
22513 the case, then the linker will eventually complain that there is
22514 a reference to an unknown section. Thus, for vtables only,
22515 we emit the TOC reference to reference the symbol and not the
22517 const char *name = XSTR (x, 0);
22519 if (VTABLE_NAME_P (name))
22521 RS6000_OUTPUT_BASENAME (file, name);
22524 assemble_name (file, name);
22527 /* Output a TOC entry. We derive the entry name from what is being
22531 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22534 const char *name = buf;
22536 HOST_WIDE_INT offset = 0;
22538 gcc_assert (!TARGET_NO_TOC);
22540 /* When the linker won't eliminate them, don't output duplicate
22541 TOC entries (this happens on AIX if there is any kind of TOC,
22542 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22544 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22546 struct toc_hash_struct *h;
22549 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22550 time because GGC is not initialized at that point. */
22551 if (toc_hash_table == NULL)
22552 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22553 toc_hash_eq, NULL);
22555 h = ggc_alloc_toc_hash_struct ();
22557 h->key_mode = mode;
22558 h->labelno = labelno;
22560 found = htab_find_slot (toc_hash_table, h, INSERT);
22561 if (*found == NULL)
22563 else /* This is indeed a duplicate.
22564 Set this label equal to that label. */
22566 fputs ("\t.set ", file);
22567 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22568 fprintf (file, "%d,", labelno);
22569 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22570 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22576 /* If we're going to put a double constant in the TOC, make sure it's
22577 aligned properly when strict alignment is on. */
22578 if (GET_CODE (x) == CONST_DOUBLE
22579 && STRICT_ALIGNMENT
22580 && GET_MODE_BITSIZE (mode) >= 64
22581 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22582 ASM_OUTPUT_ALIGN (file, 3);
22585 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22587 /* Handle FP constants specially. Note that if we have a minimal
22588 TOC, things we put here aren't actually in the TOC, so we can allow
22590 if (GET_CODE (x) == CONST_DOUBLE &&
22591 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22593 REAL_VALUE_TYPE rv;
22596 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22597 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22598 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22600 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22604 if (TARGET_MINIMAL_TOC)
22605 fputs (DOUBLE_INT_ASM_OP, file);
22607 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22608 k[0] & 0xffffffff, k[1] & 0xffffffff,
22609 k[2] & 0xffffffff, k[3] & 0xffffffff);
22610 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22611 k[0] & 0xffffffff, k[1] & 0xffffffff,
22612 k[2] & 0xffffffff, k[3] & 0xffffffff);
22617 if (TARGET_MINIMAL_TOC)
22618 fputs ("\t.long ", file);
22620 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22621 k[0] & 0xffffffff, k[1] & 0xffffffff,
22622 k[2] & 0xffffffff, k[3] & 0xffffffff);
22623 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22624 k[0] & 0xffffffff, k[1] & 0xffffffff,
22625 k[2] & 0xffffffff, k[3] & 0xffffffff);
22629 else if (GET_CODE (x) == CONST_DOUBLE &&
22630 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22632 REAL_VALUE_TYPE rv;
22635 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22637 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22638 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22640 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22644 if (TARGET_MINIMAL_TOC)
22645 fputs (DOUBLE_INT_ASM_OP, file);
22647 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22648 k[0] & 0xffffffff, k[1] & 0xffffffff);
22649 fprintf (file, "0x%lx%08lx\n",
22650 k[0] & 0xffffffff, k[1] & 0xffffffff);
22655 if (TARGET_MINIMAL_TOC)
22656 fputs ("\t.long ", file);
22658 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22659 k[0] & 0xffffffff, k[1] & 0xffffffff);
22660 fprintf (file, "0x%lx,0x%lx\n",
22661 k[0] & 0xffffffff, k[1] & 0xffffffff);
22665 else if (GET_CODE (x) == CONST_DOUBLE &&
22666 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22668 REAL_VALUE_TYPE rv;
22671 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22672 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22673 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22675 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22679 if (TARGET_MINIMAL_TOC)
22680 fputs (DOUBLE_INT_ASM_OP, file);
22682 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22683 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22688 if (TARGET_MINIMAL_TOC)
22689 fputs ("\t.long ", file);
22691 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22692 fprintf (file, "0x%lx\n", l & 0xffffffff);
22696 else if (GET_MODE (x) == VOIDmode
22697 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22699 unsigned HOST_WIDE_INT low;
22700 HOST_WIDE_INT high;
22702 if (GET_CODE (x) == CONST_DOUBLE)
22704 low = CONST_DOUBLE_LOW (x);
22705 high = CONST_DOUBLE_HIGH (x);
22708 #if HOST_BITS_PER_WIDE_INT == 32
22711 high = (low & 0x80000000) ? ~0 : 0;
22715 low = INTVAL (x) & 0xffffffff;
22716 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22720 /* TOC entries are always Pmode-sized, but since this
22721 is a bigendian machine then if we're putting smaller
22722 integer constants in the TOC we have to pad them.
22723 (This is still a win over putting the constants in
22724 a separate constant pool, because then we'd have
22725 to have both a TOC entry _and_ the actual constant.)
22727 For a 32-bit target, CONST_INT values are loaded and shifted
22728 entirely within `low' and can be stored in one TOC entry. */
22730 /* It would be easy to make this work, but it doesn't now. */
22731 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22733 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22735 #if HOST_BITS_PER_WIDE_INT == 32
22736 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22737 POINTER_SIZE, &low, &high, 0);
22740 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22741 high = (HOST_WIDE_INT) low >> 32;
22748 if (TARGET_MINIMAL_TOC)
22749 fputs (DOUBLE_INT_ASM_OP, file);
22751 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22752 (long) high & 0xffffffff, (long) low & 0xffffffff);
22753 fprintf (file, "0x%lx%08lx\n",
22754 (long) high & 0xffffffff, (long) low & 0xffffffff);
22759 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22761 if (TARGET_MINIMAL_TOC)
22762 fputs ("\t.long ", file);
22764 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22765 (long) high & 0xffffffff, (long) low & 0xffffffff);
22766 fprintf (file, "0x%lx,0x%lx\n",
22767 (long) high & 0xffffffff, (long) low & 0xffffffff);
22771 if (TARGET_MINIMAL_TOC)
22772 fputs ("\t.long ", file);
22774 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22775 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22781 if (GET_CODE (x) == CONST)
22783 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22784 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22786 base = XEXP (XEXP (x, 0), 0);
22787 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22790 switch (GET_CODE (base))
22793 name = XSTR (base, 0);
22797 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22798 CODE_LABEL_NUMBER (XEXP (base, 0)));
22802 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22806 gcc_unreachable ();
22809 if (TARGET_MINIMAL_TOC)
22810 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22813 fputs ("\t.tc ", file);
22814 RS6000_OUTPUT_BASENAME (file, name);
22817 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22819 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22821 fputs ("[TC],", file);
22824 /* Currently C++ toc references to vtables can be emitted before it
22825 is decided whether the vtable is public or private. If this is
22826 the case, then the linker will eventually complain that there is
22827 a TOC reference to an unknown section. Thus, for vtables only,
22828 we emit the TOC reference to reference the symbol and not the
22830 if (VTABLE_NAME_P (name))
22832 RS6000_OUTPUT_BASENAME (file, name);
22834 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22835 else if (offset > 0)
22836 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22839 output_addr_const (file, x);
22843 /* Output an assembler pseudo-op to write an ASCII string of N characters
22844 starting at P to FILE.
22846 On the RS/6000, we have to do this using the .byte operation and
22847 write out special characters outside the quoted string.
22848 Also, the assembler is broken; very long strings are truncated,
22849 so we must artificially break them up early. */
22852 output_ascii (FILE *file, const char *p, int n)
22855 int i, count_string;
22856 const char *for_string = "\t.byte \"";
22857 const char *for_decimal = "\t.byte ";
22858 const char *to_close = NULL;
22861 for (i = 0; i < n; i++)
22864 if (c >= ' ' && c < 0177)
22867 fputs (for_string, file);
22870 /* Write two quotes to get one. */
22878 for_decimal = "\"\n\t.byte ";
22882 if (count_string >= 512)
22884 fputs (to_close, file);
22886 for_string = "\t.byte \"";
22887 for_decimal = "\t.byte ";
22895 fputs (for_decimal, file);
22896 fprintf (file, "%d", c);
22898 for_string = "\n\t.byte \"";
22899 for_decimal = ", ";
22905 /* Now close the string if we have written one. Then end the line. */
22907 fputs (to_close, file);
22910 /* Generate a unique section name for FILENAME for a section type
22911 represented by SECTION_DESC. Output goes into BUF.
22913 SECTION_DESC can be any string, as long as it is different for each
22914 possible section type.
22916 We name the section in the same manner as xlc. The name begins with an
22917 underscore followed by the filename (after stripping any leading directory
22918 names) with the last period replaced by the string SECTION_DESC. If
22919 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22923 rs6000_gen_section_name (char **buf, const char *filename,
22924 const char *section_desc)
22926 const char *q, *after_last_slash, *last_period = 0;
22930 after_last_slash = filename;
22931 for (q = filename; *q; q++)
22934 after_last_slash = q + 1;
22935 else if (*q == '.')
22939 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22940 *buf = (char *) xmalloc (len);
22945 for (q = after_last_slash; *q; q++)
22947 if (q == last_period)
22949 strcpy (p, section_desc);
22950 p += strlen (section_desc);
22954 else if (ISALNUM (*q))
22958 if (last_period == 0)
22959 strcpy (p, section_desc);
22964 /* Emit profile function. */
22967 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22969 /* Non-standard profiling for kernels, which just saves LR then calls
22970 _mcount without worrying about arg saves. The idea is to change
22971 the function prologue as little as possible as it isn't easy to
22972 account for arg save/restore code added just for _mcount. */
22973 if (TARGET_PROFILE_KERNEL)
22976 if (DEFAULT_ABI == ABI_AIX)
22978 #ifndef NO_PROFILE_COUNTERS
22979 # define NO_PROFILE_COUNTERS 0
22981 if (NO_PROFILE_COUNTERS)
22982 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22983 LCT_NORMAL, VOIDmode, 0);
22987 const char *label_name;
22990 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22991 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22992 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22994 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22995 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22998 else if (DEFAULT_ABI == ABI_DARWIN)
23000 const char *mcount_name = RS6000_MCOUNT;
23001 int caller_addr_regno = LR_REGNO;
23003 /* Be conservative and always set this, at least for now. */
23004 crtl->uses_pic_offset_table = 1;
23007 /* For PIC code, set up a stub and collect the caller's address
23008 from r0, which is where the prologue puts it. */
23009 if (MACHOPIC_INDIRECT
23010 && crtl->uses_pic_offset_table)
23011 caller_addr_regno = 0;
23013 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
23014 LCT_NORMAL, VOIDmode, 1,
23015 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
23019 /* Write function profiler code. */
23022 output_function_profiler (FILE *file, int labelno)
23026 switch (DEFAULT_ABI)
23029 gcc_unreachable ();
23034 warning (0, "no profiling of 64-bit code for this ABI");
23037 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23038 fprintf (file, "\tmflr %s\n", reg_names[0]);
23039 if (NO_PROFILE_COUNTERS)
23041 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23042 reg_names[0], reg_names[1]);
23044 else if (TARGET_SECURE_PLT && flag_pic)
23046 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23047 reg_names[0], reg_names[1]);
23048 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23049 asm_fprintf (file, "\t{cau|addis} %s,%s,",
23050 reg_names[12], reg_names[12]);
23051 assemble_name (file, buf);
23052 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
23053 assemble_name (file, buf);
23054 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
23056 else if (flag_pic == 1)
23058 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
23059 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23060 reg_names[0], reg_names[1]);
23061 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23062 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
23063 assemble_name (file, buf);
23064 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
23066 else if (flag_pic > 1)
23068 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23069 reg_names[0], reg_names[1]);
23070 /* Now, we need to get the address of the label. */
23071 fputs ("\tbcl 20,31,1f\n\t.long ", file);
23072 assemble_name (file, buf);
23073 fputs ("-.\n1:", file);
23074 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
23075 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
23076 reg_names[0], reg_names[11]);
23077 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23078 reg_names[0], reg_names[0], reg_names[11]);
23082 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23083 assemble_name (file, buf);
23084 fputs ("@ha\n", file);
23085 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23086 reg_names[0], reg_names[1]);
23087 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23088 assemble_name (file, buf);
23089 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23092 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23093 fprintf (file, "\tbl %s%s\n",
23094 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23099 if (!TARGET_PROFILE_KERNEL)
23101 /* Don't do anything, done in output_profile_hook (). */
23105 gcc_assert (!TARGET_32BIT);
23107 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23108 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23110 if (cfun->static_chain_decl != NULL)
23112 asm_fprintf (file, "\tstd %s,24(%s)\n",
23113 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23114 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23115 asm_fprintf (file, "\tld %s,24(%s)\n",
23116 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23119 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23127 /* The following variable value is the last issued insn. */
23129 static rtx last_scheduled_insn;
23131 /* The following variable helps to balance issuing of load and
23132 store instructions */
23134 static int load_store_pendulum;
23136 /* Power4 load update and store update instructions are cracked into a
23137 load or store and an integer insn which are executed in the same cycle.
23138 Branches have their own dispatch slot which does not count against the
23139 GCC issue rate, but it changes the program flow so there are no other
23140 instructions to issue in this cycle. */
23143 rs6000_variable_issue_1 (rtx insn, int more)
23145 last_scheduled_insn = insn;
23146 if (GET_CODE (PATTERN (insn)) == USE
23147 || GET_CODE (PATTERN (insn)) == CLOBBER)
23149 cached_can_issue_more = more;
23150 return cached_can_issue_more;
23153 if (insn_terminates_group_p (insn, current_group))
23155 cached_can_issue_more = 0;
23156 return cached_can_issue_more;
23159 /* If no reservation, but reach here */
23160 if (recog_memoized (insn) < 0)
23163 if (rs6000_sched_groups)
23165 if (is_microcoded_insn (insn))
23166 cached_can_issue_more = 0;
23167 else if (is_cracked_insn (insn))
23168 cached_can_issue_more = more > 2 ? more - 2 : 0;
23170 cached_can_issue_more = more - 1;
23172 return cached_can_issue_more;
23175 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23178 cached_can_issue_more = more - 1;
23179 return cached_can_issue_more;
23183 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23185 int r = rs6000_variable_issue_1 (insn, more);
23187 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23191 /* Adjust the cost of a scheduling dependency. Return the new cost of
23192 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23195 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23197 enum attr_type attr_type;
23199 if (! recog_memoized (insn))
23202 switch (REG_NOTE_KIND (link))
23206 /* Data dependency; DEP_INSN writes a register that INSN reads
23207 some cycles later. */
23209 /* Separate a load from a narrower, dependent store. */
23210 if (rs6000_sched_groups
23211 && GET_CODE (PATTERN (insn)) == SET
23212 && GET_CODE (PATTERN (dep_insn)) == SET
23213 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23214 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23215 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23216 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23219 attr_type = get_attr_type (insn);
23224 /* Tell the first scheduling pass about the latency between
23225 a mtctr and bctr (and mtlr and br/blr). The first
23226 scheduling pass will not know about this latency since
23227 the mtctr instruction, which has the latency associated
23228 to it, will be generated by reload. */
23229 return TARGET_POWER ? 5 : 4;
23231 /* Leave some extra cycles between a compare and its
23232 dependent branch, to inhibit expensive mispredicts. */
23233 if ((rs6000_cpu_attr == CPU_PPC603
23234 || rs6000_cpu_attr == CPU_PPC604
23235 || rs6000_cpu_attr == CPU_PPC604E
23236 || rs6000_cpu_attr == CPU_PPC620
23237 || rs6000_cpu_attr == CPU_PPC630
23238 || rs6000_cpu_attr == CPU_PPC750
23239 || rs6000_cpu_attr == CPU_PPC7400
23240 || rs6000_cpu_attr == CPU_PPC7450
23241 || rs6000_cpu_attr == CPU_POWER4
23242 || rs6000_cpu_attr == CPU_POWER5
23243 || rs6000_cpu_attr == CPU_POWER7
23244 || rs6000_cpu_attr == CPU_CELL)
23245 && recog_memoized (dep_insn)
23246 && (INSN_CODE (dep_insn) >= 0))
23248 switch (get_attr_type (dep_insn))
23252 case TYPE_DELAYED_COMPARE:
23253 case TYPE_IMUL_COMPARE:
23254 case TYPE_LMUL_COMPARE:
23255 case TYPE_FPCOMPARE:
23256 case TYPE_CR_LOGICAL:
23257 case TYPE_DELAYED_CR:
23266 case TYPE_STORE_UX:
23268 case TYPE_FPSTORE_U:
23269 case TYPE_FPSTORE_UX:
23270 if ((rs6000_cpu == PROCESSOR_POWER6)
23271 && recog_memoized (dep_insn)
23272 && (INSN_CODE (dep_insn) >= 0))
23275 if (GET_CODE (PATTERN (insn)) != SET)
23276 /* If this happens, we have to extend this to schedule
23277 optimally. Return default for now. */
23280 /* Adjust the cost for the case where the value written
23281 by a fixed point operation is used as the address
23282 gen value on a store. */
23283 switch (get_attr_type (dep_insn))
23290 if (! store_data_bypass_p (dep_insn, insn))
23294 case TYPE_LOAD_EXT:
23295 case TYPE_LOAD_EXT_U:
23296 case TYPE_LOAD_EXT_UX:
23297 case TYPE_VAR_SHIFT_ROTATE:
23298 case TYPE_VAR_DELAYED_COMPARE:
23300 if (! store_data_bypass_p (dep_insn, insn))
23306 case TYPE_FAST_COMPARE:
23309 case TYPE_INSERT_WORD:
23310 case TYPE_INSERT_DWORD:
23311 case TYPE_FPLOAD_U:
23312 case TYPE_FPLOAD_UX:
23314 case TYPE_STORE_UX:
23315 case TYPE_FPSTORE_U:
23316 case TYPE_FPSTORE_UX:
23318 if (! store_data_bypass_p (dep_insn, insn))
23326 case TYPE_IMUL_COMPARE:
23327 case TYPE_LMUL_COMPARE:
23329 if (! store_data_bypass_p (dep_insn, insn))
23335 if (! store_data_bypass_p (dep_insn, insn))
23341 if (! store_data_bypass_p (dep_insn, insn))
23354 case TYPE_LOAD_EXT:
23355 case TYPE_LOAD_EXT_U:
23356 case TYPE_LOAD_EXT_UX:
23357 if ((rs6000_cpu == PROCESSOR_POWER6)
23358 && recog_memoized (dep_insn)
23359 && (INSN_CODE (dep_insn) >= 0))
23362 /* Adjust the cost for the case where the value written
23363 by a fixed point instruction is used within the address
23364 gen portion of a subsequent load(u)(x) */
23365 switch (get_attr_type (dep_insn))
23372 if (set_to_load_agen (dep_insn, insn))
23376 case TYPE_LOAD_EXT:
23377 case TYPE_LOAD_EXT_U:
23378 case TYPE_LOAD_EXT_UX:
23379 case TYPE_VAR_SHIFT_ROTATE:
23380 case TYPE_VAR_DELAYED_COMPARE:
23382 if (set_to_load_agen (dep_insn, insn))
23388 case TYPE_FAST_COMPARE:
23391 case TYPE_INSERT_WORD:
23392 case TYPE_INSERT_DWORD:
23393 case TYPE_FPLOAD_U:
23394 case TYPE_FPLOAD_UX:
23396 case TYPE_STORE_UX:
23397 case TYPE_FPSTORE_U:
23398 case TYPE_FPSTORE_UX:
23400 if (set_to_load_agen (dep_insn, insn))
23408 case TYPE_IMUL_COMPARE:
23409 case TYPE_LMUL_COMPARE:
23411 if (set_to_load_agen (dep_insn, insn))
23417 if (set_to_load_agen (dep_insn, insn))
23423 if (set_to_load_agen (dep_insn, insn))
23434 if ((rs6000_cpu == PROCESSOR_POWER6)
23435 && recog_memoized (dep_insn)
23436 && (INSN_CODE (dep_insn) >= 0)
23437 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23444 /* Fall out to return default cost. */
23448 case REG_DEP_OUTPUT:
23449 /* Output dependency; DEP_INSN writes a register that INSN writes some
23451 if ((rs6000_cpu == PROCESSOR_POWER6)
23452 && recog_memoized (dep_insn)
23453 && (INSN_CODE (dep_insn) >= 0))
23455 attr_type = get_attr_type (insn);
23460 if (get_attr_type (dep_insn) == TYPE_FP)
23464 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23472 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23477 gcc_unreachable ();
23483 /* Debug version of rs6000_adjust_cost. */
23486 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23488 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23494 switch (REG_NOTE_KIND (link))
23496 default: dep = "unknown depencency"; break;
23497 case REG_DEP_TRUE: dep = "data dependency"; break;
23498 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23499 case REG_DEP_ANTI: dep = "anti depencency"; break;
23503 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23504 "%s, insn:\n", ret, cost, dep);
23512 /* The function returns a true if INSN is microcoded.
23513 Return false otherwise. */
23516 is_microcoded_insn (rtx insn)
23518 if (!insn || !NONDEBUG_INSN_P (insn)
23519 || GET_CODE (PATTERN (insn)) == USE
23520 || GET_CODE (PATTERN (insn)) == CLOBBER)
23523 if (rs6000_cpu_attr == CPU_CELL)
23524 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23526 if (rs6000_sched_groups)
23528 enum attr_type type = get_attr_type (insn);
23529 if (type == TYPE_LOAD_EXT_U
23530 || type == TYPE_LOAD_EXT_UX
23531 || type == TYPE_LOAD_UX
23532 || type == TYPE_STORE_UX
23533 || type == TYPE_MFCR)
23540 /* The function returns true if INSN is cracked into 2 instructions
23541 by the processor (and therefore occupies 2 issue slots). */
23544 is_cracked_insn (rtx insn)
23546 if (!insn || !NONDEBUG_INSN_P (insn)
23547 || GET_CODE (PATTERN (insn)) == USE
23548 || GET_CODE (PATTERN (insn)) == CLOBBER)
23551 if (rs6000_sched_groups)
23553 enum attr_type type = get_attr_type (insn);
23554 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23555 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23556 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23557 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23558 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23559 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23560 || type == TYPE_IDIV || type == TYPE_LDIV
23561 || type == TYPE_INSERT_WORD)
23568 /* The function returns true if INSN can be issued only from
23569 the branch slot. */
23572 is_branch_slot_insn (rtx insn)
23574 if (!insn || !NONDEBUG_INSN_P (insn)
23575 || GET_CODE (PATTERN (insn)) == USE
23576 || GET_CODE (PATTERN (insn)) == CLOBBER)
23579 if (rs6000_sched_groups)
23581 enum attr_type type = get_attr_type (insn);
23582 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23590 /* The function returns true if out_inst sets a value that is
23591 used in the address generation computation of in_insn */
23593 set_to_load_agen (rtx out_insn, rtx in_insn)
23595 rtx out_set, in_set;
23597 /* For performance reasons, only handle the simple case where
23598 both loads are a single_set. */
23599 out_set = single_set (out_insn);
23602 in_set = single_set (in_insn);
23604 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23610 /* The function returns true if the target storage location of
23611 out_insn is adjacent to the target storage location of in_insn */
23612 /* Return 1 if memory locations are adjacent. */
23615 adjacent_mem_locations (rtx insn1, rtx insn2)
23618 rtx a = get_store_dest (PATTERN (insn1));
23619 rtx b = get_store_dest (PATTERN (insn2));
23621 if ((GET_CODE (XEXP (a, 0)) == REG
23622 || (GET_CODE (XEXP (a, 0)) == PLUS
23623 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23624 && (GET_CODE (XEXP (b, 0)) == REG
23625 || (GET_CODE (XEXP (b, 0)) == PLUS
23626 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23628 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23631 if (GET_CODE (XEXP (a, 0)) == PLUS)
23633 reg0 = XEXP (XEXP (a, 0), 0);
23634 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23637 reg0 = XEXP (a, 0);
23639 if (GET_CODE (XEXP (b, 0)) == PLUS)
23641 reg1 = XEXP (XEXP (b, 0), 0);
23642 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23645 reg1 = XEXP (b, 0);
23647 val_diff = val1 - val0;
23649 return ((REGNO (reg0) == REGNO (reg1))
23650 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23651 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23657 /* A C statement (sans semicolon) to update the integer scheduling
23658 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23659 INSN earlier, reduce the priority to execute INSN later. Do not
23660 define this macro if you do not need to adjust the scheduling
23661 priorities of insns. */
23664 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23666 /* On machines (like the 750) which have asymmetric integer units,
23667 where one integer unit can do multiply and divides and the other
23668 can't, reduce the priority of multiply/divide so it is scheduled
23669 before other integer operations. */
23672 if (! INSN_P (insn))
23675 if (GET_CODE (PATTERN (insn)) == USE)
23678 switch (rs6000_cpu_attr) {
23680 switch (get_attr_type (insn))
23687 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23688 priority, priority);
23689 if (priority >= 0 && priority < 0x01000000)
23696 if (insn_must_be_first_in_group (insn)
23697 && reload_completed
23698 && current_sched_info->sched_max_insns_priority
23699 && rs6000_sched_restricted_insns_priority)
23702 /* Prioritize insns that can be dispatched only in the first
23704 if (rs6000_sched_restricted_insns_priority == 1)
23705 /* Attach highest priority to insn. This means that in
23706 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23707 precede 'priority' (critical path) considerations. */
23708 return current_sched_info->sched_max_insns_priority;
23709 else if (rs6000_sched_restricted_insns_priority == 2)
23710 /* Increase priority of insn by a minimal amount. This means that in
23711 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23712 considerations precede dispatch-slot restriction considerations. */
23713 return (priority + 1);
23716 if (rs6000_cpu == PROCESSOR_POWER6
23717 && ((load_store_pendulum == -2 && is_load_insn (insn))
23718 || (load_store_pendulum == 2 && is_store_insn (insn))))
23719 /* Attach highest priority to insn if the scheduler has just issued two
23720 stores and this instruction is a load, or two loads and this instruction
23721 is a store. Power6 wants loads and stores scheduled alternately
23723 return current_sched_info->sched_max_insns_priority;
23728 /* Return true if the instruction is nonpipelined on the Cell. */
23730 is_nonpipeline_insn (rtx insn)
23732 enum attr_type type;
23733 if (!insn || !NONDEBUG_INSN_P (insn)
23734 || GET_CODE (PATTERN (insn)) == USE
23735 || GET_CODE (PATTERN (insn)) == CLOBBER)
23738 type = get_attr_type (insn);
23739 if (type == TYPE_IMUL
23740 || type == TYPE_IMUL2
23741 || type == TYPE_IMUL3
23742 || type == TYPE_LMUL
23743 || type == TYPE_IDIV
23744 || type == TYPE_LDIV
23745 || type == TYPE_SDIV
23746 || type == TYPE_DDIV
23747 || type == TYPE_SSQRT
23748 || type == TYPE_DSQRT
23749 || type == TYPE_MFCR
23750 || type == TYPE_MFCRF
23751 || type == TYPE_MFJMPR)
23759 /* Return how many instructions the machine can issue per cycle. */
23762 rs6000_issue_rate (void)
23764 /* Unless scheduling for register pressure, use issue rate of 1 for
23765 first scheduling pass to decrease degradation. */
23766 if (!reload_completed && !flag_sched_pressure)
23769 switch (rs6000_cpu_attr) {
23770 case CPU_RIOS1: /* ? */
23772 case CPU_PPC601: /* ? */
23781 case CPU_PPCE300C2:
23782 case CPU_PPCE300C3:
23783 case CPU_PPCE500MC:
23784 case CPU_PPCE500MC64:
23804 /* Return how many instructions to look ahead for better insn
23808 rs6000_use_sched_lookahead (void)
23810 if (rs6000_cpu_attr == CPU_PPC8540)
23812 if (rs6000_cpu_attr == CPU_CELL)
23813 return (reload_completed ? 8 : 0);
23817 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23819 rs6000_use_sched_lookahead_guard (rtx insn)
23821 if (rs6000_cpu_attr != CPU_CELL)
23824 if (insn == NULL_RTX || !INSN_P (insn))
23827 if (!reload_completed
23828 || is_nonpipeline_insn (insn)
23829 || is_microcoded_insn (insn))
23835 /* Determine is PAT refers to memory. */
23838 is_mem_ref (rtx pat)
23844 /* stack_tie does not produce any real memory traffic. */
23845 if (GET_CODE (pat) == UNSPEC
23846 && XINT (pat, 1) == UNSPEC_TIE)
23849 if (GET_CODE (pat) == MEM)
23852 /* Recursively process the pattern. */
23853 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23855 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23858 ret |= is_mem_ref (XEXP (pat, i));
23859 else if (fmt[i] == 'E')
23860 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23861 ret |= is_mem_ref (XVECEXP (pat, i, j));
23867 /* Determine if PAT is a PATTERN of a load insn. */
23870 is_load_insn1 (rtx pat)
23872 if (!pat || pat == NULL_RTX)
23875 if (GET_CODE (pat) == SET)
23876 return is_mem_ref (SET_SRC (pat));
23878 if (GET_CODE (pat) == PARALLEL)
23882 for (i = 0; i < XVECLEN (pat, 0); i++)
23883 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23890 /* Determine if INSN loads from memory. */
23893 is_load_insn (rtx insn)
23895 if (!insn || !INSN_P (insn))
23898 if (GET_CODE (insn) == CALL_INSN)
23901 return is_load_insn1 (PATTERN (insn));
23904 /* Determine if PAT is a PATTERN of a store insn. */
23907 is_store_insn1 (rtx pat)
23909 if (!pat || pat == NULL_RTX)
23912 if (GET_CODE (pat) == SET)
23913 return is_mem_ref (SET_DEST (pat));
23915 if (GET_CODE (pat) == PARALLEL)
23919 for (i = 0; i < XVECLEN (pat, 0); i++)
23920 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23927 /* Determine if INSN stores to memory. */
23930 is_store_insn (rtx insn)
23932 if (!insn || !INSN_P (insn))
23935 return is_store_insn1 (PATTERN (insn));
23938 /* Return the dest of a store insn. */
23941 get_store_dest (rtx pat)
23943 gcc_assert (is_store_insn1 (pat));
23945 if (GET_CODE (pat) == SET)
23946 return SET_DEST (pat);
23947 else if (GET_CODE (pat) == PARALLEL)
23951 for (i = 0; i < XVECLEN (pat, 0); i++)
23953 rtx inner_pat = XVECEXP (pat, 0, i);
23954 if (GET_CODE (inner_pat) == SET
23955 && is_mem_ref (SET_DEST (inner_pat)))
23959 /* We shouldn't get here, because we should have either a simple
23960 store insn or a store with update which are covered above. */
23964 /* Returns whether the dependence between INSN and NEXT is considered
23965 costly by the given target. */
23968 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23973 /* If the flag is not enabled - no dependence is considered costly;
23974 allow all dependent insns in the same group.
23975 This is the most aggressive option. */
23976 if (rs6000_sched_costly_dep == no_dep_costly)
23979 /* If the flag is set to 1 - a dependence is always considered costly;
23980 do not allow dependent instructions in the same group.
23981 This is the most conservative option. */
23982 if (rs6000_sched_costly_dep == all_deps_costly)
23985 insn = DEP_PRO (dep);
23986 next = DEP_CON (dep);
23988 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23989 && is_load_insn (next)
23990 && is_store_insn (insn))
23991 /* Prevent load after store in the same group. */
23994 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23995 && is_load_insn (next)
23996 && is_store_insn (insn)
23997 && DEP_TYPE (dep) == REG_DEP_TRUE)
23998 /* Prevent load after store in the same group if it is a true
24002 /* The flag is set to X; dependences with latency >= X are considered costly,
24003 and will not be scheduled in the same group. */
24004 if (rs6000_sched_costly_dep <= max_dep_latency
24005 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
24011 /* Return the next insn after INSN that is found before TAIL is reached,
24012 skipping any "non-active" insns - insns that will not actually occupy
24013 an issue slot. Return NULL_RTX if such an insn is not found. */
24016 get_next_active_insn (rtx insn, rtx tail)
24018 if (insn == NULL_RTX || insn == tail)
24023 insn = NEXT_INSN (insn);
24024 if (insn == NULL_RTX || insn == tail)
24029 || (NONJUMP_INSN_P (insn)
24030 && GET_CODE (PATTERN (insn)) != USE
24031 && GET_CODE (PATTERN (insn)) != CLOBBER
24032 && INSN_CODE (insn) != CODE_FOR_stack_tie))
24038 /* We are about to begin issuing insns for this clock cycle. */
24041 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
24042 rtx *ready ATTRIBUTE_UNUSED,
24043 int *pn_ready ATTRIBUTE_UNUSED,
24044 int clock_var ATTRIBUTE_UNUSED)
24046 int n_ready = *pn_ready;
24049 fprintf (dump, "// rs6000_sched_reorder :\n");
24051 /* Reorder the ready list, if the second to last ready insn
24052 is a nonepipeline insn. */
24053 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
24055 if (is_nonpipeline_insn (ready[n_ready - 1])
24056 && (recog_memoized (ready[n_ready - 2]) > 0))
24057 /* Simply swap first two insns. */
24059 rtx tmp = ready[n_ready - 1];
24060 ready[n_ready - 1] = ready[n_ready - 2];
24061 ready[n_ready - 2] = tmp;
24065 if (rs6000_cpu == PROCESSOR_POWER6)
24066 load_store_pendulum = 0;
24068 return rs6000_issue_rate ();
24071 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24074 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
24075 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24078 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24080 /* For Power6, we need to handle some special cases to try and keep the
24081 store queue from overflowing and triggering expensive flushes.
24083 This code monitors how load and store instructions are being issued
24084 and skews the ready list one way or the other to increase the likelihood
24085 that a desired instruction is issued at the proper time.
24087 A couple of things are done. First, we maintain a "load_store_pendulum"
24088 to track the current state of load/store issue.
24090 - If the pendulum is at zero, then no loads or stores have been
24091 issued in the current cycle so we do nothing.
24093 - If the pendulum is 1, then a single load has been issued in this
24094 cycle and we attempt to locate another load in the ready list to
24097 - If the pendulum is -2, then two stores have already been
24098 issued in this cycle, so we increase the priority of the first load
24099 in the ready list to increase it's likelihood of being chosen first
24102 - If the pendulum is -1, then a single store has been issued in this
24103 cycle and we attempt to locate another store in the ready list to
24104 issue with it, preferring a store to an adjacent memory location to
24105 facilitate store pairing in the store queue.
24107 - If the pendulum is 2, then two loads have already been
24108 issued in this cycle, so we increase the priority of the first store
24109 in the ready list to increase it's likelihood of being chosen first
24112 - If the pendulum < -2 or > 2, then do nothing.
24114 Note: This code covers the most common scenarios. There exist non
24115 load/store instructions which make use of the LSU and which
24116 would need to be accounted for to strictly model the behavior
24117 of the machine. Those instructions are currently unaccounted
24118 for to help minimize compile time overhead of this code.
24120 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24126 if (is_store_insn (last_scheduled_insn))
24127 /* Issuing a store, swing the load_store_pendulum to the left */
24128 load_store_pendulum--;
24129 else if (is_load_insn (last_scheduled_insn))
24130 /* Issuing a load, swing the load_store_pendulum to the right */
24131 load_store_pendulum++;
24133 return cached_can_issue_more;
24135 /* If the pendulum is balanced, or there is only one instruction on
24136 the ready list, then all is well, so return. */
24137 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24138 return cached_can_issue_more;
24140 if (load_store_pendulum == 1)
24142 /* A load has been issued in this cycle. Scan the ready list
24143 for another load to issue with it */
24148 if (is_load_insn (ready[pos]))
24150 /* Found a load. Move it to the head of the ready list,
24151 and adjust it's priority so that it is more likely to
24154 for (i=pos; i<*pn_ready-1; i++)
24155 ready[i] = ready[i + 1];
24156 ready[*pn_ready-1] = tmp;
24158 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24159 INSN_PRIORITY (tmp)++;
24165 else if (load_store_pendulum == -2)
24167 /* Two stores have been issued in this cycle. Increase the
24168 priority of the first load in the ready list to favor it for
24169 issuing in the next cycle. */
24174 if (is_load_insn (ready[pos])
24176 && INSN_PRIORITY_KNOWN (ready[pos]))
24178 INSN_PRIORITY (ready[pos])++;
24180 /* Adjust the pendulum to account for the fact that a load
24181 was found and increased in priority. This is to prevent
24182 increasing the priority of multiple loads */
24183 load_store_pendulum--;
24190 else if (load_store_pendulum == -1)
24192 /* A store has been issued in this cycle. Scan the ready list for
24193 another store to issue with it, preferring a store to an adjacent
24195 int first_store_pos = -1;
24201 if (is_store_insn (ready[pos]))
24203 /* Maintain the index of the first store found on the
24205 if (first_store_pos == -1)
24206 first_store_pos = pos;
24208 if (is_store_insn (last_scheduled_insn)
24209 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24211 /* Found an adjacent store. Move it to the head of the
24212 ready list, and adjust it's priority so that it is
24213 more likely to stay there */
24215 for (i=pos; i<*pn_ready-1; i++)
24216 ready[i] = ready[i + 1];
24217 ready[*pn_ready-1] = tmp;
24219 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24220 INSN_PRIORITY (tmp)++;
24222 first_store_pos = -1;
24230 if (first_store_pos >= 0)
24232 /* An adjacent store wasn't found, but a non-adjacent store was,
24233 so move the non-adjacent store to the front of the ready
24234 list, and adjust its priority so that it is more likely to
24236 tmp = ready[first_store_pos];
24237 for (i=first_store_pos; i<*pn_ready-1; i++)
24238 ready[i] = ready[i + 1];
24239 ready[*pn_ready-1] = tmp;
24240 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24241 INSN_PRIORITY (tmp)++;
24244 else if (load_store_pendulum == 2)
24246 /* Two loads have been issued in this cycle. Increase the priority
24247 of the first store in the ready list to favor it for issuing in
24253 if (is_store_insn (ready[pos])
24255 && INSN_PRIORITY_KNOWN (ready[pos]))
24257 INSN_PRIORITY (ready[pos])++;
24259 /* Adjust the pendulum to account for the fact that a store
24260 was found and increased in priority. This is to prevent
24261 increasing the priority of multiple stores */
24262 load_store_pendulum++;
24271 return cached_can_issue_more;
24274 /* Return whether the presence of INSN causes a dispatch group termination
24275 of group WHICH_GROUP.
24277 If WHICH_GROUP == current_group, this function will return true if INSN
24278 causes the termination of the current group (i.e, the dispatch group to
24279 which INSN belongs). This means that INSN will be the last insn in the
24280 group it belongs to.
24282 If WHICH_GROUP == previous_group, this function will return true if INSN
24283 causes the termination of the previous group (i.e, the dispatch group that
24284 precedes the group to which INSN belongs). This means that INSN will be
24285 the first insn in the group it belongs to). */
24288 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24295 first = insn_must_be_first_in_group (insn);
24296 last = insn_must_be_last_in_group (insn);
24301 if (which_group == current_group)
24303 else if (which_group == previous_group)
24311 insn_must_be_first_in_group (rtx insn)
24313 enum attr_type type;
24316 || GET_CODE (insn) == NOTE
24317 || DEBUG_INSN_P (insn)
24318 || GET_CODE (PATTERN (insn)) == USE
24319 || GET_CODE (PATTERN (insn)) == CLOBBER)
24322 switch (rs6000_cpu)
24324 case PROCESSOR_POWER5:
24325 if (is_cracked_insn (insn))
24327 case PROCESSOR_POWER4:
24328 if (is_microcoded_insn (insn))
24331 if (!rs6000_sched_groups)
24334 type = get_attr_type (insn);
24341 case TYPE_DELAYED_CR:
24342 case TYPE_CR_LOGICAL:
24356 case PROCESSOR_POWER6:
24357 type = get_attr_type (insn);
24361 case TYPE_INSERT_DWORD:
24365 case TYPE_VAR_SHIFT_ROTATE:
24372 case TYPE_INSERT_WORD:
24373 case TYPE_DELAYED_COMPARE:
24374 case TYPE_IMUL_COMPARE:
24375 case TYPE_LMUL_COMPARE:
24376 case TYPE_FPCOMPARE:
24387 case TYPE_LOAD_EXT_UX:
24389 case TYPE_STORE_UX:
24390 case TYPE_FPLOAD_U:
24391 case TYPE_FPLOAD_UX:
24392 case TYPE_FPSTORE_U:
24393 case TYPE_FPSTORE_UX:
24399 case PROCESSOR_POWER7:
24400 type = get_attr_type (insn);
24404 case TYPE_CR_LOGICAL:
24411 case TYPE_DELAYED_COMPARE:
24412 case TYPE_VAR_DELAYED_COMPARE:
24418 case TYPE_LOAD_EXT:
24419 case TYPE_LOAD_EXT_U:
24420 case TYPE_LOAD_EXT_UX:
24422 case TYPE_STORE_UX:
24423 case TYPE_FPLOAD_U:
24424 case TYPE_FPLOAD_UX:
24425 case TYPE_FPSTORE_U:
24426 case TYPE_FPSTORE_UX:
24442 insn_must_be_last_in_group (rtx insn)
24444 enum attr_type type;
24447 || GET_CODE (insn) == NOTE
24448 || DEBUG_INSN_P (insn)
24449 || GET_CODE (PATTERN (insn)) == USE
24450 || GET_CODE (PATTERN (insn)) == CLOBBER)
24453 switch (rs6000_cpu) {
24454 case PROCESSOR_POWER4:
24455 case PROCESSOR_POWER5:
24456 if (is_microcoded_insn (insn))
24459 if (is_branch_slot_insn (insn))
24463 case PROCESSOR_POWER6:
24464 type = get_attr_type (insn);
24471 case TYPE_VAR_SHIFT_ROTATE:
24478 case TYPE_DELAYED_COMPARE:
24479 case TYPE_IMUL_COMPARE:
24480 case TYPE_LMUL_COMPARE:
24481 case TYPE_FPCOMPARE:
24495 case PROCESSOR_POWER7:
24496 type = get_attr_type (insn);
24504 case TYPE_LOAD_EXT_U:
24505 case TYPE_LOAD_EXT_UX:
24506 case TYPE_STORE_UX:
24519 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24520 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24523 is_costly_group (rtx *group_insns, rtx next_insn)
24526 int issue_rate = rs6000_issue_rate ();
24528 for (i = 0; i < issue_rate; i++)
24530 sd_iterator_def sd_it;
24532 rtx insn = group_insns[i];
24537 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24539 rtx next = DEP_CON (dep);
24541 if (next == next_insn
24542 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24550 /* Utility of the function redefine_groups.
24551 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24552 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24553 to keep it "far" (in a separate group) from GROUP_INSNS, following
24554 one of the following schemes, depending on the value of the flag
24555 -minsert_sched_nops = X:
24556 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24557 in order to force NEXT_INSN into a separate group.
24558 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24559 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24560 insertion (has a group just ended, how many vacant issue slots remain in the
24561 last group, and how many dispatch groups were encountered so far). */
24564 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24565 rtx next_insn, bool *group_end, int can_issue_more,
24570 int issue_rate = rs6000_issue_rate ();
24571 bool end = *group_end;
24574 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24575 return can_issue_more;
24577 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24578 return can_issue_more;
24580 force = is_costly_group (group_insns, next_insn);
24582 return can_issue_more;
24584 if (sched_verbose > 6)
24585 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24586 *group_count ,can_issue_more);
24588 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24591 can_issue_more = 0;
24593 /* Since only a branch can be issued in the last issue_slot, it is
24594 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24595 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24596 in this case the last nop will start a new group and the branch
24597 will be forced to the new group. */
24598 if (can_issue_more && !is_branch_slot_insn (next_insn))
24601 while (can_issue_more > 0)
24604 emit_insn_before (nop, next_insn);
24612 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24614 int n_nops = rs6000_sched_insert_nops;
24616 /* Nops can't be issued from the branch slot, so the effective
24617 issue_rate for nops is 'issue_rate - 1'. */
24618 if (can_issue_more == 0)
24619 can_issue_more = issue_rate;
24621 if (can_issue_more == 0)
24623 can_issue_more = issue_rate - 1;
24626 for (i = 0; i < issue_rate; i++)
24628 group_insns[i] = 0;
24635 emit_insn_before (nop, next_insn);
24636 if (can_issue_more == issue_rate - 1) /* new group begins */
24639 if (can_issue_more == 0)
24641 can_issue_more = issue_rate - 1;
24644 for (i = 0; i < issue_rate; i++)
24646 group_insns[i] = 0;
24652 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24655 /* Is next_insn going to start a new group? */
24658 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24659 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24660 || (can_issue_more < issue_rate &&
24661 insn_terminates_group_p (next_insn, previous_group)));
24662 if (*group_end && end)
24665 if (sched_verbose > 6)
24666 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24667 *group_count, can_issue_more);
24668 return can_issue_more;
24671 return can_issue_more;
24674 /* This function tries to synch the dispatch groups that the compiler "sees"
24675 with the dispatch groups that the processor dispatcher is expected to
24676 form in practice. It tries to achieve this synchronization by forcing the
24677 estimated processor grouping on the compiler (as opposed to the function
24678 'pad_goups' which tries to force the scheduler's grouping on the processor).
24680 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24681 examines the (estimated) dispatch groups that will be formed by the processor
24682 dispatcher. It marks these group boundaries to reflect the estimated
24683 processor grouping, overriding the grouping that the scheduler had marked.
24684 Depending on the value of the flag '-minsert-sched-nops' this function can
24685 force certain insns into separate groups or force a certain distance between
24686 them by inserting nops, for example, if there exists a "costly dependence"
24689 The function estimates the group boundaries that the processor will form as
24690 follows: It keeps track of how many vacant issue slots are available after
24691 each insn. A subsequent insn will start a new group if one of the following
24693 - no more vacant issue slots remain in the current dispatch group.
24694 - only the last issue slot, which is the branch slot, is vacant, but the next
24695 insn is not a branch.
24696 - only the last 2 or less issue slots, including the branch slot, are vacant,
24697 which means that a cracked insn (which occupies two issue slots) can't be
24698 issued in this group.
24699 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24700 start a new group. */
24703 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24705 rtx insn, next_insn;
24707 int can_issue_more;
24710 int group_count = 0;
24714 issue_rate = rs6000_issue_rate ();
24715 group_insns = XALLOCAVEC (rtx, issue_rate);
24716 for (i = 0; i < issue_rate; i++)
24718 group_insns[i] = 0;
24720 can_issue_more = issue_rate;
24722 insn = get_next_active_insn (prev_head_insn, tail);
24725 while (insn != NULL_RTX)
24727 slot = (issue_rate - can_issue_more);
24728 group_insns[slot] = insn;
24730 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24731 if (insn_terminates_group_p (insn, current_group))
24732 can_issue_more = 0;
24734 next_insn = get_next_active_insn (insn, tail);
24735 if (next_insn == NULL_RTX)
24736 return group_count + 1;
24738 /* Is next_insn going to start a new group? */
24740 = (can_issue_more == 0
24741 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24742 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24743 || (can_issue_more < issue_rate &&
24744 insn_terminates_group_p (next_insn, previous_group)));
24746 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24747 next_insn, &group_end, can_issue_more,
24753 can_issue_more = 0;
24754 for (i = 0; i < issue_rate; i++)
24756 group_insns[i] = 0;
24760 if (GET_MODE (next_insn) == TImode && can_issue_more)
24761 PUT_MODE (next_insn, VOIDmode);
24762 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24763 PUT_MODE (next_insn, TImode);
24766 if (can_issue_more == 0)
24767 can_issue_more = issue_rate;
24770 return group_count;
24773 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24774 dispatch group boundaries that the scheduler had marked. Pad with nops
24775 any dispatch groups which have vacant issue slots, in order to force the
24776 scheduler's grouping on the processor dispatcher. The function
24777 returns the number of dispatch groups found. */
24780 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24782 rtx insn, next_insn;
24785 int can_issue_more;
24787 int group_count = 0;
24789 /* Initialize issue_rate. */
24790 issue_rate = rs6000_issue_rate ();
24791 can_issue_more = issue_rate;
24793 insn = get_next_active_insn (prev_head_insn, tail);
24794 next_insn = get_next_active_insn (insn, tail);
24796 while (insn != NULL_RTX)
24799 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24801 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24803 if (next_insn == NULL_RTX)
24808 /* If the scheduler had marked group termination at this location
24809 (between insn and next_insn), and neither insn nor next_insn will
24810 force group termination, pad the group with nops to force group
24813 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24814 && !insn_terminates_group_p (insn, current_group)
24815 && !insn_terminates_group_p (next_insn, previous_group))
24817 if (!is_branch_slot_insn (next_insn))
24820 while (can_issue_more)
24823 emit_insn_before (nop, next_insn);
24828 can_issue_more = issue_rate;
24833 next_insn = get_next_active_insn (insn, tail);
24836 return group_count;
24839 /* We're beginning a new block. Initialize data structures as necessary. */
24842 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24843 int sched_verbose ATTRIBUTE_UNUSED,
24844 int max_ready ATTRIBUTE_UNUSED)
24846 last_scheduled_insn = NULL_RTX;
24847 load_store_pendulum = 0;
24850 /* The following function is called at the end of scheduling BB.
24851 After reload, it inserts nops at insn group bundling. */
24854 rs6000_sched_finish (FILE *dump, int sched_verbose)
24859 fprintf (dump, "=== Finishing schedule.\n");
24861 if (reload_completed && rs6000_sched_groups)
24863 /* Do not run sched_finish hook when selective scheduling enabled. */
24864 if (sel_sched_p ())
24867 if (rs6000_sched_insert_nops == sched_finish_none)
24870 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24871 n_groups = pad_groups (dump, sched_verbose,
24872 current_sched_info->prev_head,
24873 current_sched_info->next_tail);
24875 n_groups = redefine_groups (dump, sched_verbose,
24876 current_sched_info->prev_head,
24877 current_sched_info->next_tail);
24879 if (sched_verbose >= 6)
24881 fprintf (dump, "ngroups = %d\n", n_groups);
24882 print_rtl (dump, current_sched_info->prev_head);
24883 fprintf (dump, "Done finish_sched\n");
24888 struct _rs6000_sched_context
24890 short cached_can_issue_more;
24891 rtx last_scheduled_insn;
24892 int load_store_pendulum;
24895 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24896 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24898 /* Allocate store for new scheduling context. */
24900 rs6000_alloc_sched_context (void)
24902 return xmalloc (sizeof (rs6000_sched_context_def));
24905 /* If CLEAN_P is true then initializes _SC with clean data,
24906 and from the global context otherwise. */
24908 rs6000_init_sched_context (void *_sc, bool clean_p)
24910 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24914 sc->cached_can_issue_more = 0;
24915 sc->last_scheduled_insn = NULL_RTX;
24916 sc->load_store_pendulum = 0;
24920 sc->cached_can_issue_more = cached_can_issue_more;
24921 sc->last_scheduled_insn = last_scheduled_insn;
24922 sc->load_store_pendulum = load_store_pendulum;
24926 /* Sets the global scheduling context to the one pointed to by _SC. */
24928 rs6000_set_sched_context (void *_sc)
24930 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24932 gcc_assert (sc != NULL);
24934 cached_can_issue_more = sc->cached_can_issue_more;
24935 last_scheduled_insn = sc->last_scheduled_insn;
24936 load_store_pendulum = sc->load_store_pendulum;
24941 rs6000_free_sched_context (void *_sc)
24943 gcc_assert (_sc != NULL);
24949 /* Length in units of the trampoline for entering a nested function. */
24952 rs6000_trampoline_size (void)
24956 switch (DEFAULT_ABI)
24959 gcc_unreachable ();
24962 ret = (TARGET_32BIT) ? 12 : 24;
24967 ret = (TARGET_32BIT) ? 40 : 48;
24974 /* Emit RTL insns to initialize the variable parts of a trampoline.
24975 FNADDR is an RTX for the address of the function's pure code.
24976 CXT is an RTX for the static chain value for the function. */
24979 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24981 int regsize = (TARGET_32BIT) ? 4 : 8;
24982 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24983 rtx ctx_reg = force_reg (Pmode, cxt);
24984 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24986 switch (DEFAULT_ABI)
24989 gcc_unreachable ();
24991 /* Under AIX, just build the 3 word function descriptor */
24994 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24995 rtx fn_reg = gen_reg_rtx (Pmode);
24996 rtx toc_reg = gen_reg_rtx (Pmode);
24998 /* Macro to shorten the code expansions below. */
24999 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25001 m_tramp = replace_equiv_address (m_tramp, addr);
25003 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
25004 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
25005 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
25006 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
25007 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
25013 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25016 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
25017 LCT_NORMAL, VOIDmode, 4,
25019 GEN_INT (rs6000_trampoline_size ()), SImode,
25027 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25028 identifier as an argument, so the front end shouldn't look it up. */
25031 rs6000_attribute_takes_identifier_p (const_tree attr_id)
25033 return is_attribute_p ("altivec", attr_id);
25036 /* Handle the "altivec" attribute. The attribute may have
25037 arguments as follows:
25039 __attribute__((altivec(vector__)))
25040 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25041 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25043 and may appear more than once (e.g., 'vector bool char') in a
25044 given declaration. */
25047 rs6000_handle_altivec_attribute (tree *node,
25048 tree name ATTRIBUTE_UNUSED,
25050 int flags ATTRIBUTE_UNUSED,
25051 bool *no_add_attrs)
25053 tree type = *node, result = NULL_TREE;
25054 enum machine_mode mode;
25057 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
25058 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
25059 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
25062 while (POINTER_TYPE_P (type)
25063 || TREE_CODE (type) == FUNCTION_TYPE
25064 || TREE_CODE (type) == METHOD_TYPE
25065 || TREE_CODE (type) == ARRAY_TYPE)
25066 type = TREE_TYPE (type);
25068 mode = TYPE_MODE (type);
25070 /* Check for invalid AltiVec type qualifiers. */
25071 if (type == long_double_type_node)
25072 error ("use of %<long double%> in AltiVec types is invalid");
25073 else if (type == boolean_type_node)
25074 error ("use of boolean types in AltiVec types is invalid");
25075 else if (TREE_CODE (type) == COMPLEX_TYPE)
25076 error ("use of %<complex%> in AltiVec types is invalid");
25077 else if (DECIMAL_FLOAT_MODE_P (mode))
25078 error ("use of decimal floating point types in AltiVec types is invalid");
25079 else if (!TARGET_VSX)
25081 if (type == long_unsigned_type_node || type == long_integer_type_node)
25084 error ("use of %<long%> in AltiVec types is invalid for "
25085 "64-bit code without -mvsx");
25086 else if (rs6000_warn_altivec_long)
25087 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25090 else if (type == long_long_unsigned_type_node
25091 || type == long_long_integer_type_node)
25092 error ("use of %<long long%> in AltiVec types is invalid without "
25094 else if (type == double_type_node)
25095 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25098 switch (altivec_type)
25101 unsigned_p = TYPE_UNSIGNED (type);
25105 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25108 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25111 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25114 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25116 case SFmode: result = V4SF_type_node; break;
25117 case DFmode: result = V2DF_type_node; break;
25118 /* If the user says 'vector int bool', we may be handed the 'bool'
25119 attribute _before_ the 'vector' attribute, and so select the
25120 proper type in the 'b' case below. */
25121 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25122 case V2DImode: case V2DFmode:
25130 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25131 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25132 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25133 case QImode: case V16QImode: result = bool_V16QI_type_node;
25140 case V8HImode: result = pixel_V8HI_type_node;
25146 /* Propagate qualifiers attached to the element type
25147 onto the vector type. */
25148 if (result && result != type && TYPE_QUALS (type))
25149 result = build_qualified_type (result, TYPE_QUALS (type));
25151 *no_add_attrs = true; /* No need to hang on to the attribute. */
25154 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25159 /* AltiVec defines four built-in scalar types that serve as vector
25160 elements; we must teach the compiler how to mangle them. */
25162 static const char *
25163 rs6000_mangle_type (const_tree type)
25165 type = TYPE_MAIN_VARIANT (type);
25167 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25168 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25171 if (type == bool_char_type_node) return "U6__boolc";
25172 if (type == bool_short_type_node) return "U6__bools";
25173 if (type == pixel_type_node) return "u7__pixel";
25174 if (type == bool_int_type_node) return "U6__booli";
25175 if (type == bool_long_type_node) return "U6__booll";
25177 /* Mangle IBM extended float long double as `g' (__float128) on
25178 powerpc*-linux where long-double-64 previously was the default. */
25179 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25181 && TARGET_LONG_DOUBLE_128
25182 && !TARGET_IEEEQUAD)
25185 /* For all other types, use normal C++ mangling. */
25189 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25190 struct attribute_spec.handler. */
25193 rs6000_handle_longcall_attribute (tree *node, tree name,
25194 tree args ATTRIBUTE_UNUSED,
25195 int flags ATTRIBUTE_UNUSED,
25196 bool *no_add_attrs)
25198 if (TREE_CODE (*node) != FUNCTION_TYPE
25199 && TREE_CODE (*node) != FIELD_DECL
25200 && TREE_CODE (*node) != TYPE_DECL)
25202 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25204 *no_add_attrs = true;
25210 /* Set longcall attributes on all functions declared when
25211 rs6000_default_long_calls is true. */
25213 rs6000_set_default_type_attributes (tree type)
25215 if (rs6000_default_long_calls
25216 && (TREE_CODE (type) == FUNCTION_TYPE
25217 || TREE_CODE (type) == METHOD_TYPE))
25218 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25220 TYPE_ATTRIBUTES (type));
25223 darwin_set_default_type_attributes (type);
25227 /* Return a reference suitable for calling a function with the
25228 longcall attribute. */
25231 rs6000_longcall_ref (rtx call_ref)
25233 const char *call_name;
25236 if (GET_CODE (call_ref) != SYMBOL_REF)
25239 /* System V adds '.' to the internal name, so skip them. */
25240 call_name = XSTR (call_ref, 0);
25241 if (*call_name == '.')
25243 while (*call_name == '.')
25246 node = get_identifier (call_name);
25247 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25250 return force_reg (Pmode, call_ref);
25253 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25254 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25257 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25258 struct attribute_spec.handler. */
25260 rs6000_handle_struct_attribute (tree *node, tree name,
25261 tree args ATTRIBUTE_UNUSED,
25262 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25265 if (DECL_P (*node))
25267 if (TREE_CODE (*node) == TYPE_DECL)
25268 type = &TREE_TYPE (*node);
25273 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25274 || TREE_CODE (*type) == UNION_TYPE)))
25276 warning (OPT_Wattributes, "%qE attribute ignored", name);
25277 *no_add_attrs = true;
25280 else if ((is_attribute_p ("ms_struct", name)
25281 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25282 || ((is_attribute_p ("gcc_struct", name)
25283 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25285 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25287 *no_add_attrs = true;
25294 rs6000_ms_bitfield_layout_p (const_tree record_type)
25296 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25297 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25298 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25301 #ifdef USING_ELFOS_H
25303 /* A get_unnamed_section callback, used for switching to toc_section. */
25306 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25308 if (DEFAULT_ABI == ABI_AIX
25309 && TARGET_MINIMAL_TOC
25310 && !TARGET_RELOCATABLE)
25312 if (!toc_initialized)
25314 toc_initialized = 1;
25315 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25316 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25317 fprintf (asm_out_file, "\t.tc ");
25318 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25319 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25320 fprintf (asm_out_file, "\n");
25322 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25323 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25324 fprintf (asm_out_file, " = .+32768\n");
25327 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25329 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25330 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25333 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25334 if (!toc_initialized)
25336 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25337 fprintf (asm_out_file, " = .+32768\n");
25338 toc_initialized = 1;
25343 /* Implement TARGET_ASM_INIT_SECTIONS. */
25346 rs6000_elf_asm_init_sections (void)
25349 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25352 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25353 SDATA2_SECTION_ASM_OP);
25356 /* Implement TARGET_SELECT_RTX_SECTION. */
25359 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25360 unsigned HOST_WIDE_INT align)
25362 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25363 return toc_section;
25365 return default_elf_select_rtx_section (mode, x, align);
25368 /* For a SYMBOL_REF, set generic flags and then perform some
25369 target-specific processing.
25371 When the AIX ABI is requested on a non-AIX system, replace the
25372 function name with the real name (with a leading .) rather than the
25373 function descriptor name. This saves a lot of overriding code to
25374 read the prefixes. */
25377 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25379 default_encode_section_info (decl, rtl, first);
25382 && TREE_CODE (decl) == FUNCTION_DECL
25384 && DEFAULT_ABI == ABI_AIX)
25386 rtx sym_ref = XEXP (rtl, 0);
25387 size_t len = strlen (XSTR (sym_ref, 0));
25388 char *str = XALLOCAVEC (char, len + 2);
25390 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25391 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25396 compare_section_name (const char *section, const char *templ)
25400 len = strlen (templ);
25401 return (strncmp (section, templ, len) == 0
25402 && (section[len] == 0 || section[len] == '.'));
25406 rs6000_elf_in_small_data_p (const_tree decl)
25408 if (rs6000_sdata == SDATA_NONE)
25411 /* We want to merge strings, so we never consider them small data. */
25412 if (TREE_CODE (decl) == STRING_CST)
25415 /* Functions are never in the small data area. */
25416 if (TREE_CODE (decl) == FUNCTION_DECL)
25419 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25421 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25422 if (compare_section_name (section, ".sdata")
25423 || compare_section_name (section, ".sdata2")
25424 || compare_section_name (section, ".gnu.linkonce.s")
25425 || compare_section_name (section, ".sbss")
25426 || compare_section_name (section, ".sbss2")
25427 || compare_section_name (section, ".gnu.linkonce.sb")
25428 || strcmp (section, ".PPC.EMB.sdata0") == 0
25429 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25434 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25437 && size <= g_switch_value
25438 /* If it's not public, and we're not going to reference it there,
25439 there's no need to put it in the small data section. */
25440 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25447 #endif /* USING_ELFOS_H */
25449 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25452 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25454 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25457 /* Return a REG that occurs in ADDR with coefficient 1.
25458 ADDR can be effectively incremented by incrementing REG.
25460 r0 is special and we must not select it as an address
25461 register by this routine since our caller will try to
25462 increment the returned register via an "la" instruction. */
25465 find_addr_reg (rtx addr)
25467 while (GET_CODE (addr) == PLUS)
25469 if (GET_CODE (XEXP (addr, 0)) == REG
25470 && REGNO (XEXP (addr, 0)) != 0)
25471 addr = XEXP (addr, 0);
25472 else if (GET_CODE (XEXP (addr, 1)) == REG
25473 && REGNO (XEXP (addr, 1)) != 0)
25474 addr = XEXP (addr, 1);
25475 else if (CONSTANT_P (XEXP (addr, 0)))
25476 addr = XEXP (addr, 1);
25477 else if (CONSTANT_P (XEXP (addr, 1)))
25478 addr = XEXP (addr, 0);
25480 gcc_unreachable ();
25482 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25487 rs6000_fatal_bad_address (rtx op)
25489 fatal_insn ("bad address", op);
25494 typedef struct branch_island_d {
25495 tree function_name;
25500 DEF_VEC_O(branch_island);
25501 DEF_VEC_ALLOC_O(branch_island,gc);
25503 static VEC(branch_island,gc) *branch_islands;
25505 /* Remember to generate a branch island for far calls to the given
25509 add_compiler_branch_island (tree label_name, tree function_name,
25512 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25514 bi->function_name = function_name;
25515 bi->label_name = label_name;
25516 bi->line_number = line_number;
25519 /* Generate far-jump branch islands for everything recorded in
25520 branch_islands. Invoked immediately after the last instruction of
25521 the epilogue has been emitted; the branch islands must be appended
25522 to, and contiguous with, the function body. Mach-O stubs are
25523 generated in machopic_output_stub(). */
25526 macho_branch_islands (void)
25530 while (!VEC_empty (branch_island, branch_islands))
25532 branch_island *bi = VEC_last (branch_island, branch_islands);
25533 const char *label = IDENTIFIER_POINTER (bi->label_name);
25534 const char *name = IDENTIFIER_POINTER (bi->function_name);
25535 char name_buf[512];
25536 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25537 if (name[0] == '*' || name[0] == '&')
25538 strcpy (name_buf, name+1);
25542 strcpy (name_buf+1, name);
25544 strcpy (tmp_buf, "\n");
25545 strcat (tmp_buf, label);
25546 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25547 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25548 dbxout_stabd (N_SLINE, bi->line_number);
25549 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25552 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25553 strcat (tmp_buf, label);
25554 strcat (tmp_buf, "_pic\n");
25555 strcat (tmp_buf, label);
25556 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25558 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25559 strcat (tmp_buf, name_buf);
25560 strcat (tmp_buf, " - ");
25561 strcat (tmp_buf, label);
25562 strcat (tmp_buf, "_pic)\n");
25564 strcat (tmp_buf, "\tmtlr r0\n");
25566 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25567 strcat (tmp_buf, name_buf);
25568 strcat (tmp_buf, " - ");
25569 strcat (tmp_buf, label);
25570 strcat (tmp_buf, "_pic)\n");
25572 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25576 strcat (tmp_buf, ":\nlis r12,hi16(");
25577 strcat (tmp_buf, name_buf);
25578 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25579 strcat (tmp_buf, name_buf);
25580 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25582 output_asm_insn (tmp_buf, 0);
25583 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25584 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25585 dbxout_stabd (N_SLINE, bi->line_number);
25586 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25587 VEC_pop (branch_island, branch_islands);
25591 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25592 already there or not. */
25595 no_previous_def (tree function_name)
25600 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25601 if (function_name == bi->function_name)
25606 /* GET_PREV_LABEL gets the label name from the previous definition of
25610 get_prev_label (tree function_name)
25615 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25616 if (function_name == bi->function_name)
25617 return bi->label_name;
25621 /* INSN is either a function call or a millicode call. It may have an
25622 unconditional jump in its delay slot.
25624 CALL_DEST is the routine we are calling. */
25627 output_call (rtx insn, rtx *operands, int dest_operand_number,
25628 int cookie_operand_number)
25630 static char buf[256];
25631 if (darwin_emit_branch_islands
25632 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25633 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25636 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25638 if (no_previous_def (funname))
25640 rtx label_rtx = gen_label_rtx ();
25641 char *label_buf, temp_buf[256];
25642 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25643 CODE_LABEL_NUMBER (label_rtx));
25644 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25645 labelname = get_identifier (label_buf);
25646 add_compiler_branch_island (labelname, funname, insn_line (insn));
25649 labelname = get_prev_label (funname);
25651 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25652 instruction will reach 'foo', otherwise link as 'bl L42'".
25653 "L42" should be a 'branch island', that will do a far jump to
25654 'foo'. Branch islands are generated in
25655 macho_branch_islands(). */
25656 sprintf (buf, "jbsr %%z%d,%.246s",
25657 dest_operand_number, IDENTIFIER_POINTER (labelname));
25660 sprintf (buf, "bl %%z%d", dest_operand_number);
25664 /* Generate PIC and indirect symbol stubs. */
25667 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25669 unsigned int length;
25670 char *symbol_name, *lazy_ptr_name;
25671 char *local_label_0;
25672 static int label = 0;
25674 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25675 symb = (*targetm.strip_name_encoding) (symb);
25678 length = strlen (symb);
25679 symbol_name = XALLOCAVEC (char, length + 32);
25680 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25682 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25683 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25686 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25688 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25692 fprintf (file, "\t.align 5\n");
25694 fprintf (file, "%s:\n", stub);
25695 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25698 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25699 sprintf (local_label_0, "\"L%011d$spb\"", label);
25701 fprintf (file, "\tmflr r0\n");
25702 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25703 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25704 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25705 lazy_ptr_name, local_label_0);
25706 fprintf (file, "\tmtlr r0\n");
25707 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25708 (TARGET_64BIT ? "ldu" : "lwzu"),
25709 lazy_ptr_name, local_label_0);
25710 fprintf (file, "\tmtctr r12\n");
25711 fprintf (file, "\tbctr\n");
25715 fprintf (file, "\t.align 4\n");
25717 fprintf (file, "%s:\n", stub);
25718 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25720 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25721 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25722 (TARGET_64BIT ? "ldu" : "lwzu"),
25724 fprintf (file, "\tmtctr r12\n");
25725 fprintf (file, "\tbctr\n");
25728 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25729 fprintf (file, "%s:\n", lazy_ptr_name);
25730 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25731 fprintf (file, "%sdyld_stub_binding_helper\n",
25732 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25735 /* Legitimize PIC addresses. If the address is already
25736 position-independent, we return ORIG. Newly generated
25737 position-independent addresses go into a reg. This is REG if non
25738 zero, otherwise we allocate register(s) as necessary. */
25740 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25743 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25748 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25749 reg = gen_reg_rtx (Pmode);
25751 if (GET_CODE (orig) == CONST)
25755 if (GET_CODE (XEXP (orig, 0)) == PLUS
25756 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25759 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25761 /* Use a different reg for the intermediate value, as
25762 it will be marked UNCHANGING. */
25763 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25764 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25767 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25770 if (GET_CODE (offset) == CONST_INT)
25772 if (SMALL_INT (offset))
25773 return plus_constant (base, INTVAL (offset));
25774 else if (! reload_in_progress && ! reload_completed)
25775 offset = force_reg (Pmode, offset);
25778 rtx mem = force_const_mem (Pmode, orig);
25779 return machopic_legitimize_pic_address (mem, Pmode, reg);
25782 return gen_rtx_PLUS (Pmode, base, offset);
25785 /* Fall back on generic machopic code. */
25786 return machopic_legitimize_pic_address (orig, mode, reg);
25789 /* Output a .machine directive for the Darwin assembler, and call
25790 the generic start_file routine. */
25793 rs6000_darwin_file_start (void)
25795 static const struct
25801 { "ppc64", "ppc64", MASK_64BIT },
25802 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25803 { "power4", "ppc970", 0 },
25804 { "G5", "ppc970", 0 },
25805 { "7450", "ppc7450", 0 },
25806 { "7400", "ppc7400", MASK_ALTIVEC },
25807 { "G4", "ppc7400", 0 },
25808 { "750", "ppc750", 0 },
25809 { "740", "ppc750", 0 },
25810 { "G3", "ppc750", 0 },
25811 { "604e", "ppc604e", 0 },
25812 { "604", "ppc604", 0 },
25813 { "603e", "ppc603", 0 },
25814 { "603", "ppc603", 0 },
25815 { "601", "ppc601", 0 },
25816 { NULL, "ppc", 0 } };
25817 const char *cpu_id = "";
25820 rs6000_file_start ();
25821 darwin_file_start ();
25823 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25824 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25825 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25826 && rs6000_select[i].string[0] != '\0')
25827 cpu_id = rs6000_select[i].string;
25829 /* Look through the mapping array. Pick the first name that either
25830 matches the argument, has a bit set in IF_SET that is also set
25831 in the target flags, or has a NULL name. */
25834 while (mapping[i].arg != NULL
25835 && strcmp (mapping[i].arg, cpu_id) != 0
25836 && (mapping[i].if_set & target_flags) == 0)
25839 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25842 #endif /* TARGET_MACHO */
25846 rs6000_elf_reloc_rw_mask (void)
25850 else if (DEFAULT_ABI == ABI_AIX)
25856 /* Record an element in the table of global constructors. SYMBOL is
25857 a SYMBOL_REF of the function to be called; PRIORITY is a number
25858 between 0 and MAX_INIT_PRIORITY.
25860 This differs from default_named_section_asm_out_constructor in
25861 that we have special handling for -mrelocatable. */
25864 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25866 const char *section = ".ctors";
25869 if (priority != DEFAULT_INIT_PRIORITY)
25871 sprintf (buf, ".ctors.%.5u",
25872 /* Invert the numbering so the linker puts us in the proper
25873 order; constructors are run from right to left, and the
25874 linker sorts in increasing order. */
25875 MAX_INIT_PRIORITY - priority);
25879 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25880 assemble_align (POINTER_SIZE);
25882 if (TARGET_RELOCATABLE)
25884 fputs ("\t.long (", asm_out_file);
25885 output_addr_const (asm_out_file, symbol);
25886 fputs (")@fixup\n", asm_out_file);
25889 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25893 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25895 const char *section = ".dtors";
25898 if (priority != DEFAULT_INIT_PRIORITY)
25900 sprintf (buf, ".dtors.%.5u",
25901 /* Invert the numbering so the linker puts us in the proper
25902 order; constructors are run from right to left, and the
25903 linker sorts in increasing order. */
25904 MAX_INIT_PRIORITY - priority);
25908 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25909 assemble_align (POINTER_SIZE);
25911 if (TARGET_RELOCATABLE)
25913 fputs ("\t.long (", asm_out_file);
25914 output_addr_const (asm_out_file, symbol);
25915 fputs (")@fixup\n", asm_out_file);
25918 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25922 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25926 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25927 ASM_OUTPUT_LABEL (file, name);
25928 fputs (DOUBLE_INT_ASM_OP, file);
25929 rs6000_output_function_entry (file, name);
25930 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25933 fputs ("\t.size\t", file);
25934 assemble_name (file, name);
25935 fputs (",24\n\t.type\t.", file);
25936 assemble_name (file, name);
25937 fputs (",@function\n", file);
25938 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25940 fputs ("\t.globl\t.", file);
25941 assemble_name (file, name);
25946 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25947 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25948 rs6000_output_function_entry (file, name);
25949 fputs (":\n", file);
25953 if (TARGET_RELOCATABLE
25954 && !TARGET_SECURE_PLT
25955 && (get_pool_size () != 0 || crtl->profile)
25960 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25962 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25963 fprintf (file, "\t.long ");
25964 assemble_name (file, buf);
25966 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25967 assemble_name (file, buf);
25971 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25972 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25974 if (DEFAULT_ABI == ABI_AIX)
25976 const char *desc_name, *orig_name;
25978 orig_name = (*targetm.strip_name_encoding) (name);
25979 desc_name = orig_name;
25980 while (*desc_name == '.')
25983 if (TREE_PUBLIC (decl))
25984 fprintf (file, "\t.globl %s\n", desc_name);
25986 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25987 fprintf (file, "%s:\n", desc_name);
25988 fprintf (file, "\t.long %s\n", orig_name);
25989 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25990 if (DEFAULT_ABI == ABI_AIX)
25991 fputs ("\t.long 0\n", file);
25992 fprintf (file, "\t.previous\n");
25994 ASM_OUTPUT_LABEL (file, name);
25998 rs6000_elf_file_end (void)
26000 #ifdef HAVE_AS_GNU_ATTRIBUTE
26001 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
26003 if (rs6000_passes_float)
26004 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
26005 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
26006 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
26008 if (rs6000_passes_vector)
26009 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
26010 (TARGET_ALTIVEC_ABI ? 2
26011 : TARGET_SPE_ABI ? 3
26013 if (rs6000_returns_struct)
26014 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
26015 aix_struct_return ? 2 : 1);
26018 #ifdef POWERPC_LINUX
26020 file_end_indicate_exec_stack ();
26027 rs6000_xcoff_asm_output_anchor (rtx symbol)
26031 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
26032 SYMBOL_REF_BLOCK_OFFSET (symbol));
26033 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
26037 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
26039 fputs (GLOBAL_ASM_OP, stream);
26040 RS6000_OUTPUT_BASENAME (stream, name);
26041 putc ('\n', stream);
26044 /* A get_unnamed_decl callback, used for read-only sections. PTR
26045 points to the section string variable. */
26048 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
26050 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
26051 *(const char *const *) directive,
26052 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26055 /* Likewise for read-write sections. */
26058 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
26060 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
26061 *(const char *const *) directive,
26062 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26065 /* A get_unnamed_section callback, used for switching to toc_section. */
26068 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
26070 if (TARGET_MINIMAL_TOC)
26072 /* toc_section is always selected at least once from
26073 rs6000_xcoff_file_start, so this is guaranteed to
26074 always be defined once and only once in each file. */
26075 if (!toc_initialized)
26077 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26078 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26079 toc_initialized = 1;
26081 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26082 (TARGET_32BIT ? "" : ",3"));
26085 fputs ("\t.toc\n", asm_out_file);
26088 /* Implement TARGET_ASM_INIT_SECTIONS. */
26091 rs6000_xcoff_asm_init_sections (void)
26093 read_only_data_section
26094 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26095 &xcoff_read_only_section_name);
26097 private_data_section
26098 = get_unnamed_section (SECTION_WRITE,
26099 rs6000_xcoff_output_readwrite_section_asm_op,
26100 &xcoff_private_data_section_name);
26102 read_only_private_data_section
26103 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26104 &xcoff_private_data_section_name);
26107 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26109 readonly_data_section = read_only_data_section;
26110 exception_section = data_section;
26114 rs6000_xcoff_reloc_rw_mask (void)
26120 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26121 tree decl ATTRIBUTE_UNUSED)
26124 static const char * const suffix[3] = { "PR", "RO", "RW" };
26126 if (flags & SECTION_CODE)
26128 else if (flags & SECTION_WRITE)
26133 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26134 (flags & SECTION_CODE) ? "." : "",
26135 name, suffix[smclass], flags & SECTION_ENTSIZE);
26139 rs6000_xcoff_select_section (tree decl, int reloc,
26140 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26142 if (decl_readonly_section (decl, reloc))
26144 if (TREE_PUBLIC (decl))
26145 return read_only_data_section;
26147 return read_only_private_data_section;
26151 if (TREE_PUBLIC (decl))
26152 return data_section;
26154 return private_data_section;
26159 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26163 /* Use select_section for private and uninitialized data. */
26164 if (!TREE_PUBLIC (decl)
26165 || DECL_COMMON (decl)
26166 || DECL_INITIAL (decl) == NULL_TREE
26167 || DECL_INITIAL (decl) == error_mark_node
26168 || (flag_zero_initialized_in_bss
26169 && initializer_zerop (DECL_INITIAL (decl))))
26172 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26173 name = (*targetm.strip_name_encoding) (name);
26174 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26177 /* Select section for constant in constant pool.
26179 On RS/6000, all constants are in the private read-only data area.
26180 However, if this is being placed in the TOC it must be output as a
26184 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26185 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26187 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26188 return toc_section;
26190 return read_only_private_data_section;
26193 /* Remove any trailing [DS] or the like from the symbol name. */
26195 static const char *
26196 rs6000_xcoff_strip_name_encoding (const char *name)
26201 len = strlen (name);
26202 if (name[len - 1] == ']')
26203 return ggc_alloc_string (name, len - 4);
26208 /* Section attributes. AIX is always PIC. */
26210 static unsigned int
26211 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26213 unsigned int align;
26214 unsigned int flags = default_section_type_flags (decl, name, reloc);
26216 /* Align to at least UNIT size. */
26217 if (flags & SECTION_CODE)
26218 align = MIN_UNITS_PER_WORD;
26220 /* Increase alignment of large objects if not already stricter. */
26221 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26222 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26223 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26225 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26228 /* Output at beginning of assembler file.
26230 Initialize the section names for the RS/6000 at this point.
26232 Specify filename, including full path, to assembler.
26234 We want to go into the TOC section so at least one .toc will be emitted.
26235 Also, in order to output proper .bs/.es pairs, we need at least one static
26236 [RW] section emitted.
26238 Finally, declare mcount when profiling to make the assembler happy. */
26241 rs6000_xcoff_file_start (void)
26243 rs6000_gen_section_name (&xcoff_bss_section_name,
26244 main_input_filename, ".bss_");
26245 rs6000_gen_section_name (&xcoff_private_data_section_name,
26246 main_input_filename, ".rw_");
26247 rs6000_gen_section_name (&xcoff_read_only_section_name,
26248 main_input_filename, ".ro_");
26250 fputs ("\t.file\t", asm_out_file);
26251 output_quoted_string (asm_out_file, main_input_filename);
26252 fputc ('\n', asm_out_file);
26253 if (write_symbols != NO_DEBUG)
26254 switch_to_section (private_data_section);
26255 switch_to_section (text_section);
26257 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26258 rs6000_file_start ();
26261 /* Output at end of assembler file.
26262 On the RS/6000, referencing data should automatically pull in text. */
26265 rs6000_xcoff_file_end (void)
26267 switch_to_section (text_section);
26268 fputs ("_section_.text:\n", asm_out_file);
26269 switch_to_section (data_section);
26270 fputs (TARGET_32BIT
26271 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26274 #endif /* TARGET_XCOFF */
26276 /* Compute a (partial) cost for rtx X. Return true if the complete
26277 cost has been computed, and false if subexpressions should be
26278 scanned. In either case, *TOTAL contains the cost result. */
26281 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26284 enum machine_mode mode = GET_MODE (x);
26288 /* On the RS/6000, if it is valid in the insn, it is free. */
26290 if (((outer_code == SET
26291 || outer_code == PLUS
26292 || outer_code == MINUS)
26293 && (satisfies_constraint_I (x)
26294 || satisfies_constraint_L (x)))
26295 || (outer_code == AND
26296 && (satisfies_constraint_K (x)
26298 ? satisfies_constraint_L (x)
26299 : satisfies_constraint_J (x))
26300 || mask_operand (x, mode)
26302 && mask64_operand (x, DImode))))
26303 || ((outer_code == IOR || outer_code == XOR)
26304 && (satisfies_constraint_K (x)
26306 ? satisfies_constraint_L (x)
26307 : satisfies_constraint_J (x))))
26308 || outer_code == ASHIFT
26309 || outer_code == ASHIFTRT
26310 || outer_code == LSHIFTRT
26311 || outer_code == ROTATE
26312 || outer_code == ROTATERT
26313 || outer_code == ZERO_EXTRACT
26314 || (outer_code == MULT
26315 && satisfies_constraint_I (x))
26316 || ((outer_code == DIV || outer_code == UDIV
26317 || outer_code == MOD || outer_code == UMOD)
26318 && exact_log2 (INTVAL (x)) >= 0)
26319 || (outer_code == COMPARE
26320 && (satisfies_constraint_I (x)
26321 || satisfies_constraint_K (x)))
26322 || ((outer_code == EQ || outer_code == NE)
26323 && (satisfies_constraint_I (x)
26324 || satisfies_constraint_K (x)
26326 ? satisfies_constraint_L (x)
26327 : satisfies_constraint_J (x))))
26328 || (outer_code == GTU
26329 && satisfies_constraint_I (x))
26330 || (outer_code == LTU
26331 && satisfies_constraint_P (x)))
26336 else if ((outer_code == PLUS
26337 && reg_or_add_cint_operand (x, VOIDmode))
26338 || (outer_code == MINUS
26339 && reg_or_sub_cint_operand (x, VOIDmode))
26340 || ((outer_code == SET
26341 || outer_code == IOR
26342 || outer_code == XOR)
26344 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26346 *total = COSTS_N_INSNS (1);
26352 if (mode == DImode && code == CONST_DOUBLE)
26354 if ((outer_code == IOR || outer_code == XOR)
26355 && CONST_DOUBLE_HIGH (x) == 0
26356 && (CONST_DOUBLE_LOW (x)
26357 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26362 else if ((outer_code == AND && and64_2_operand (x, DImode))
26363 || ((outer_code == SET
26364 || outer_code == IOR
26365 || outer_code == XOR)
26366 && CONST_DOUBLE_HIGH (x) == 0))
26368 *total = COSTS_N_INSNS (1);
26378 /* When optimizing for size, MEM should be slightly more expensive
26379 than generating address, e.g., (plus (reg) (const)).
26380 L1 cache latency is about two instructions. */
26381 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26390 if (FLOAT_MODE_P (mode))
26391 *total = rs6000_cost->fp;
26393 *total = COSTS_N_INSNS (1);
26397 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26398 && satisfies_constraint_I (XEXP (x, 1)))
26400 if (INTVAL (XEXP (x, 1)) >= -256
26401 && INTVAL (XEXP (x, 1)) <= 255)
26402 *total = rs6000_cost->mulsi_const9;
26404 *total = rs6000_cost->mulsi_const;
26406 else if (mode == SFmode)
26407 *total = rs6000_cost->fp;
26408 else if (FLOAT_MODE_P (mode))
26409 *total = rs6000_cost->dmul;
26410 else if (mode == DImode)
26411 *total = rs6000_cost->muldi;
26413 *total = rs6000_cost->mulsi;
26417 if (mode == SFmode)
26418 *total = rs6000_cost->fp;
26420 *total = rs6000_cost->dmul;
26425 if (FLOAT_MODE_P (mode))
26427 *total = mode == DFmode ? rs6000_cost->ddiv
26428 : rs6000_cost->sdiv;
26435 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26436 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26438 if (code == DIV || code == MOD)
26440 *total = COSTS_N_INSNS (2);
26443 *total = COSTS_N_INSNS (1);
26447 if (GET_MODE (XEXP (x, 1)) == DImode)
26448 *total = rs6000_cost->divdi;
26450 *total = rs6000_cost->divsi;
26452 /* Add in shift and subtract for MOD. */
26453 if (code == MOD || code == UMOD)
26454 *total += COSTS_N_INSNS (2);
26459 *total = COSTS_N_INSNS (4);
26463 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26467 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26471 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26483 *total = COSTS_N_INSNS (1);
26491 /* Handle mul_highpart. */
26492 if (outer_code == TRUNCATE
26493 && GET_CODE (XEXP (x, 0)) == MULT)
26495 if (mode == DImode)
26496 *total = rs6000_cost->muldi;
26498 *total = rs6000_cost->mulsi;
26501 else if (outer_code == AND)
26504 *total = COSTS_N_INSNS (1);
26509 if (GET_CODE (XEXP (x, 0)) == MEM)
26512 *total = COSTS_N_INSNS (1);
26518 if (!FLOAT_MODE_P (mode))
26520 *total = COSTS_N_INSNS (1);
26526 case UNSIGNED_FLOAT:
26529 case FLOAT_TRUNCATE:
26530 *total = rs6000_cost->fp;
26534 if (mode == DFmode)
26537 *total = rs6000_cost->fp;
26541 switch (XINT (x, 1))
26544 *total = rs6000_cost->fp;
26556 *total = COSTS_N_INSNS (1);
26559 else if (FLOAT_MODE_P (mode)
26560 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26562 *total = rs6000_cost->fp;
26570 /* Carry bit requires mode == Pmode.
26571 NEG or PLUS already counted so only add one. */
26573 && (outer_code == NEG || outer_code == PLUS))
26575 *total = COSTS_N_INSNS (1);
26578 if (outer_code == SET)
26580 if (XEXP (x, 1) == const0_rtx)
26582 if (TARGET_ISEL && !TARGET_MFCRF)
26583 *total = COSTS_N_INSNS (8);
26585 *total = COSTS_N_INSNS (2);
26588 else if (mode == Pmode)
26590 *total = COSTS_N_INSNS (3);
26599 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26601 if (TARGET_ISEL && !TARGET_MFCRF)
26602 *total = COSTS_N_INSNS (8);
26604 *total = COSTS_N_INSNS (2);
26608 if (outer_code == COMPARE)
26622 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26625 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26628 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26631 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26632 "total = %d, speed = %s, x:\n",
26633 ret ? "complete" : "scan inner",
26634 GET_RTX_NAME (code),
26635 GET_RTX_NAME (outer_code),
26637 speed ? "true" : "false");
26644 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26647 rs6000_debug_address_cost (rtx x, bool speed)
26649 int ret = TARGET_ADDRESS_COST (x, speed);
26651 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26652 ret, speed ? "true" : "false");
26659 /* A C expression returning the cost of moving data from a register of class
26660 CLASS1 to one of CLASS2. */
26663 rs6000_register_move_cost (enum machine_mode mode,
26664 reg_class_t from, reg_class_t to)
26668 /* Moves from/to GENERAL_REGS. */
26669 if (reg_classes_intersect_p (to, GENERAL_REGS)
26670 || reg_classes_intersect_p (from, GENERAL_REGS))
26672 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26675 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26676 ret = (rs6000_memory_move_cost (mode, from, false)
26677 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26679 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26681 else if (from == CR_REGS)
26684 /* For those processors that have slow LR/CTR moves, make them more
26685 expensive than memory in order to bias spills to memory .*/
26686 else if ((rs6000_cpu == PROCESSOR_POWER6
26687 || rs6000_cpu == PROCESSOR_POWER7)
26688 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26689 ret = 6 * hard_regno_nregs[0][mode];
26692 /* A move will cost one instruction per GPR moved. */
26693 ret = 2 * hard_regno_nregs[0][mode];
26696 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26697 else if (VECTOR_UNIT_VSX_P (mode)
26698 && reg_classes_intersect_p (to, VSX_REGS)
26699 && reg_classes_intersect_p (from, VSX_REGS))
26700 ret = 2 * hard_regno_nregs[32][mode];
26702 /* Moving between two similar registers is just one instruction. */
26703 else if (reg_classes_intersect_p (to, from))
26704 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26706 /* Everything else has to go through GENERAL_REGS. */
26708 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26709 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26711 if (TARGET_DEBUG_COST)
26713 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26714 ret, GET_MODE_NAME (mode), reg_class_names[from],
26715 reg_class_names[to]);
26720 /* A C expressions returning the cost of moving data of MODE from a register to
26724 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26725 bool in ATTRIBUTE_UNUSED)
26729 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26730 ret = 4 * hard_regno_nregs[0][mode];
26731 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26732 ret = 4 * hard_regno_nregs[32][mode];
26733 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26734 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26736 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26738 if (TARGET_DEBUG_COST)
26740 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26741 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26746 /* Returns a code for a target-specific builtin that implements
26747 reciprocal of the function, or NULL_TREE if not available. */
26750 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26751 bool sqrt ATTRIBUTE_UNUSED)
26753 if (optimize_insn_for_size_p ())
26759 case VSX_BUILTIN_XVSQRTDP:
26760 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26763 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26765 case VSX_BUILTIN_XVSQRTSP:
26766 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26769 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26778 case BUILT_IN_SQRT:
26779 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26782 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26784 case BUILT_IN_SQRTF:
26785 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26788 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26795 /* Load up a constant. If the mode is a vector mode, splat the value across
26796 all of the vector elements. */
26799 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26803 if (mode == SFmode || mode == DFmode)
26805 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26806 reg = force_reg (mode, d);
26808 else if (mode == V4SFmode)
26810 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26811 rtvec v = gen_rtvec (4, d, d, d, d);
26812 reg = gen_reg_rtx (mode);
26813 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26815 else if (mode == V2DFmode)
26817 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26818 rtvec v = gen_rtvec (2, d, d);
26819 reg = gen_reg_rtx (mode);
26820 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26823 gcc_unreachable ();
26828 /* Generate an FMA instruction. */
26831 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26833 enum machine_mode mode = GET_MODE (target);
26836 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26837 gcc_assert (dst != NULL);
26840 emit_move_insn (target, dst);
26843 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26846 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26848 enum machine_mode mode = GET_MODE (target);
26851 /* Altivec does not support fms directly;
26852 generate in terms of fma in that case. */
26853 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26854 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26857 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26858 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26860 gcc_assert (dst != NULL);
26863 emit_move_insn (target, dst);
26866 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26869 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26871 enum machine_mode mode = GET_MODE (dst);
26874 /* This is a tad more complicated, since the fnma_optab is for
26875 a different expression: fma(-m1, m2, a), which is the same
26876 thing except in the case of signed zeros.
26878 Fortunately we know that if FMA is supported that FNMSUB is
26879 also supported in the ISA. Just expand it directly. */
26881 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26883 r = gen_rtx_NEG (mode, a);
26884 r = gen_rtx_FMA (mode, m1, m2, r);
26885 r = gen_rtx_NEG (mode, r);
26886 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26889 /* Newton-Raphson approximation of floating point divide with just 2 passes
26890 (either single precision floating point, or newer machines with higher
26891 accuracy estimates). Support both scalar and vector divide. Assumes no
26892 trapping math and finite arguments. */
26895 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26897 enum machine_mode mode = GET_MODE (dst);
26898 rtx x0, e0, e1, y1, u0, v0;
26899 enum insn_code code = optab_handler (smul_optab, mode);
26900 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26901 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26903 gcc_assert (code != CODE_FOR_nothing);
26905 /* x0 = 1./d estimate */
26906 x0 = gen_reg_rtx (mode);
26907 emit_insn (gen_rtx_SET (VOIDmode, x0,
26908 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26911 e0 = gen_reg_rtx (mode);
26912 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26914 e1 = gen_reg_rtx (mode);
26915 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26917 y1 = gen_reg_rtx (mode);
26918 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26920 u0 = gen_reg_rtx (mode);
26921 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26923 v0 = gen_reg_rtx (mode);
26924 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26926 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26929 /* Newton-Raphson approximation of floating point divide that has a low
26930 precision estimate. Assumes no trapping math and finite arguments. */
26933 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26935 enum machine_mode mode = GET_MODE (dst);
26936 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26937 enum insn_code code = optab_handler (smul_optab, mode);
26938 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26940 gcc_assert (code != CODE_FOR_nothing);
26942 one = rs6000_load_constant_and_splat (mode, dconst1);
26944 /* x0 = 1./d estimate */
26945 x0 = gen_reg_rtx (mode);
26946 emit_insn (gen_rtx_SET (VOIDmode, x0,
26947 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26950 e0 = gen_reg_rtx (mode);
26951 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26953 y1 = gen_reg_rtx (mode);
26954 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26956 e1 = gen_reg_rtx (mode);
26957 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26959 y2 = gen_reg_rtx (mode);
26960 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26962 e2 = gen_reg_rtx (mode);
26963 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26965 y3 = gen_reg_rtx (mode);
26966 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26968 u0 = gen_reg_rtx (mode);
26969 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26971 v0 = gen_reg_rtx (mode);
26972 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26974 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26977 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26978 add a reg_note saying that this was a division. Support both scalar and
26979 vector divide. Assumes no trapping math and finite arguments. */
26982 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26984 enum machine_mode mode = GET_MODE (dst);
26986 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26987 rs6000_emit_swdiv_high_precision (dst, n, d);
26989 rs6000_emit_swdiv_low_precision (dst, n, d);
26992 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26995 /* Newton-Raphson approximation of single/double-precision floating point
26996 rsqrt. Assumes no trapping math and finite arguments. */
26999 rs6000_emit_swrsqrt (rtx dst, rtx src)
27001 enum machine_mode mode = GET_MODE (src);
27002 rtx x0 = gen_reg_rtx (mode);
27003 rtx y = gen_reg_rtx (mode);
27004 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
27005 REAL_VALUE_TYPE dconst3_2;
27008 enum insn_code code = optab_handler (smul_optab, mode);
27009 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27011 gcc_assert (code != CODE_FOR_nothing);
27013 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27014 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
27015 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
27017 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
27019 /* x0 = rsqrt estimate */
27020 emit_insn (gen_rtx_SET (VOIDmode, x0,
27021 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
27024 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27025 rs6000_emit_msub (y, src, halfthree, src);
27027 for (i = 0; i < passes; i++)
27029 rtx x1 = gen_reg_rtx (mode);
27030 rtx u = gen_reg_rtx (mode);
27031 rtx v = gen_reg_rtx (mode);
27033 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27034 emit_insn (gen_mul (u, x0, x0));
27035 rs6000_emit_nmsub (v, y, u, halfthree);
27036 emit_insn (gen_mul (x1, x0, v));
27040 emit_move_insn (dst, x0);
27044 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27045 (Power7) targets. DST is the target, and SRC is the argument operand. */
27048 rs6000_emit_popcount (rtx dst, rtx src)
27050 enum machine_mode mode = GET_MODE (dst);
27053 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27054 if (TARGET_POPCNTD)
27056 if (mode == SImode)
27057 emit_insn (gen_popcntdsi2 (dst, src));
27059 emit_insn (gen_popcntddi2 (dst, src));
27063 tmp1 = gen_reg_rtx (mode);
27065 if (mode == SImode)
27067 emit_insn (gen_popcntbsi2 (tmp1, src));
27068 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
27070 tmp2 = force_reg (SImode, tmp2);
27071 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
27075 emit_insn (gen_popcntbdi2 (tmp1, src));
27076 tmp2 = expand_mult (DImode, tmp1,
27077 GEN_INT ((HOST_WIDE_INT)
27078 0x01010101 << 32 | 0x01010101),
27080 tmp2 = force_reg (DImode, tmp2);
27081 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27086 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27087 target, and SRC is the argument operand. */
27090 rs6000_emit_parity (rtx dst, rtx src)
27092 enum machine_mode mode = GET_MODE (dst);
27095 tmp = gen_reg_rtx (mode);
27097 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27100 if (mode == SImode)
27102 emit_insn (gen_popcntbsi2 (tmp, src));
27103 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27107 emit_insn (gen_popcntbdi2 (tmp, src));
27108 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27113 if (mode == SImode)
27115 /* Is mult+shift >= shift+xor+shift+xor? */
27116 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27118 rtx tmp1, tmp2, tmp3, tmp4;
27120 tmp1 = gen_reg_rtx (SImode);
27121 emit_insn (gen_popcntbsi2 (tmp1, src));
27123 tmp2 = gen_reg_rtx (SImode);
27124 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27125 tmp3 = gen_reg_rtx (SImode);
27126 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27128 tmp4 = gen_reg_rtx (SImode);
27129 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27130 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27133 rs6000_emit_popcount (tmp, src);
27134 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27138 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27139 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27141 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27143 tmp1 = gen_reg_rtx (DImode);
27144 emit_insn (gen_popcntbdi2 (tmp1, src));
27146 tmp2 = gen_reg_rtx (DImode);
27147 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27148 tmp3 = gen_reg_rtx (DImode);
27149 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27151 tmp4 = gen_reg_rtx (DImode);
27152 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27153 tmp5 = gen_reg_rtx (DImode);
27154 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27156 tmp6 = gen_reg_rtx (DImode);
27157 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27158 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27161 rs6000_emit_popcount (tmp, src);
27162 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27166 /* Return an RTX representing where to find the function value of a
27167 function returning MODE. */
27169 rs6000_complex_function_value (enum machine_mode mode)
27171 unsigned int regno;
27173 enum machine_mode inner = GET_MODE_INNER (mode);
27174 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27176 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27177 regno = FP_ARG_RETURN;
27180 regno = GP_ARG_RETURN;
27182 /* 32-bit is OK since it'll go in r3/r4. */
27183 if (TARGET_32BIT && inner_bytes >= 4)
27184 return gen_rtx_REG (mode, regno);
27187 if (inner_bytes >= 8)
27188 return gen_rtx_REG (mode, regno);
27190 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27192 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27193 GEN_INT (inner_bytes));
27194 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27197 /* Target hook for TARGET_FUNCTION_VALUE.
27199 On the SPE, both FPs and vectors are returned in r3.
27201 On RS/6000 an integer value is in r3 and a floating-point value is in
27202 fp1, unless -msoft-float. */
27205 rs6000_function_value (const_tree valtype,
27206 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27207 bool outgoing ATTRIBUTE_UNUSED)
27209 enum machine_mode mode;
27210 unsigned int regno;
27212 /* Special handling for structs in darwin64. */
27214 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27216 CUMULATIVE_ARGS valcum;
27220 valcum.fregno = FP_ARG_MIN_REG;
27221 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27222 /* Do a trial code generation as if this were going to be passed as
27223 an argument; if any part goes in memory, we return NULL. */
27224 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27227 /* Otherwise fall through to standard ABI rules. */
27230 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27232 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27233 return gen_rtx_PARALLEL (DImode,
27235 gen_rtx_EXPR_LIST (VOIDmode,
27236 gen_rtx_REG (SImode, GP_ARG_RETURN),
27238 gen_rtx_EXPR_LIST (VOIDmode,
27239 gen_rtx_REG (SImode,
27240 GP_ARG_RETURN + 1),
27243 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27245 return gen_rtx_PARALLEL (DCmode,
27247 gen_rtx_EXPR_LIST (VOIDmode,
27248 gen_rtx_REG (SImode, GP_ARG_RETURN),
27250 gen_rtx_EXPR_LIST (VOIDmode,
27251 gen_rtx_REG (SImode,
27252 GP_ARG_RETURN + 1),
27254 gen_rtx_EXPR_LIST (VOIDmode,
27255 gen_rtx_REG (SImode,
27256 GP_ARG_RETURN + 2),
27258 gen_rtx_EXPR_LIST (VOIDmode,
27259 gen_rtx_REG (SImode,
27260 GP_ARG_RETURN + 3),
27264 mode = TYPE_MODE (valtype);
27265 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27266 || POINTER_TYPE_P (valtype))
27267 mode = TARGET_32BIT ? SImode : DImode;
27269 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27270 /* _Decimal128 must use an even/odd register pair. */
27271 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27272 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27273 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27274 regno = FP_ARG_RETURN;
27275 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27276 && targetm.calls.split_complex_arg)
27277 return rs6000_complex_function_value (mode);
27278 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
27279 return register is used in both cases, and we won't see V2DImode/V2DFmode
27280 for pure altivec, combine the two cases. */
27281 else if (TREE_CODE (valtype) == VECTOR_TYPE
27282 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27283 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
27284 regno = ALTIVEC_ARG_RETURN;
27285 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27286 && (mode == DFmode || mode == DCmode
27287 || mode == TFmode || mode == TCmode))
27288 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27290 regno = GP_ARG_RETURN;
27292 return gen_rtx_REG (mode, regno);
27295 /* Define how to find the value returned by a library function
27296 assuming the value has mode MODE. */
27298 rs6000_libcall_value (enum machine_mode mode)
27300 unsigned int regno;
27302 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27304 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27305 return gen_rtx_PARALLEL (DImode,
27307 gen_rtx_EXPR_LIST (VOIDmode,
27308 gen_rtx_REG (SImode, GP_ARG_RETURN),
27310 gen_rtx_EXPR_LIST (VOIDmode,
27311 gen_rtx_REG (SImode,
27312 GP_ARG_RETURN + 1),
27316 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27317 /* _Decimal128 must use an even/odd register pair. */
27318 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27319 else if (SCALAR_FLOAT_MODE_P (mode)
27320 && TARGET_HARD_FLOAT && TARGET_FPRS
27321 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27322 regno = FP_ARG_RETURN;
27323 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
27324 return register is used in both cases, and we won't see V2DImode/V2DFmode
27325 for pure altivec, combine the two cases. */
27326 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
27327 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27328 regno = ALTIVEC_ARG_RETURN;
27329 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27330 return rs6000_complex_function_value (mode);
27331 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27332 && (mode == DFmode || mode == DCmode
27333 || mode == TFmode || mode == TCmode))
27334 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27336 regno = GP_ARG_RETURN;
27338 return gen_rtx_REG (mode, regno);
27342 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27343 Frame pointer elimination is automatically handled.
27345 For the RS/6000, if frame pointer elimination is being done, we would like
27346 to convert ap into fp, not sp.
27348 We need r30 if -mminimal-toc was specified, and there are constant pool
27352 rs6000_can_eliminate (const int from, const int to)
27354 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27355 ? ! frame_pointer_needed
27356 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27357 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27361 /* Define the offset between two registers, FROM to be eliminated and its
27362 replacement TO, at the start of a routine. */
27364 rs6000_initial_elimination_offset (int from, int to)
27366 rs6000_stack_t *info = rs6000_stack_info ();
27367 HOST_WIDE_INT offset;
27369 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27370 offset = info->push_p ? 0 : -info->total_size;
27371 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27373 offset = info->push_p ? 0 : -info->total_size;
27374 if (FRAME_GROWS_DOWNWARD)
27375 offset += info->fixed_size + info->vars_size + info->parm_size;
27377 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27378 offset = FRAME_GROWS_DOWNWARD
27379 ? info->fixed_size + info->vars_size + info->parm_size
27381 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27382 offset = info->total_size;
27383 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27384 offset = info->push_p ? info->total_size : 0;
27385 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27388 gcc_unreachable ();
27394 rs6000_dwarf_register_span (rtx reg)
27398 unsigned regno = REGNO (reg);
27399 enum machine_mode mode = GET_MODE (reg);
27403 && (SPE_VECTOR_MODE (GET_MODE (reg))
27404 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27405 && mode != SFmode && mode != SDmode && mode != SCmode)))
27410 regno = REGNO (reg);
27412 /* The duality of the SPE register size wreaks all kinds of havoc.
27413 This is a way of distinguishing r0 in 32-bits from r0 in
27415 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27416 gcc_assert (words <= 4);
27417 for (i = 0; i < words; i++, regno++)
27419 if (BYTES_BIG_ENDIAN)
27421 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27422 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27426 parts[2 * i] = gen_rtx_REG (SImode, regno);
27427 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27431 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27434 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27437 rs6000_init_dwarf_reg_sizes_extra (tree address)
27442 enum machine_mode mode = TYPE_MODE (char_type_node);
27443 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27444 rtx mem = gen_rtx_MEM (BLKmode, addr);
27445 rtx value = gen_int_mode (4, mode);
27447 for (i = 1201; i < 1232; i++)
27449 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27450 HOST_WIDE_INT offset
27451 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27453 emit_move_insn (adjust_address (mem, mode, offset), value);
27458 /* Map internal gcc register numbers to DWARF2 register numbers. */
27461 rs6000_dbx_register_number (unsigned int regno)
27463 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27465 if (regno == MQ_REGNO)
27467 if (regno == LR_REGNO)
27469 if (regno == CTR_REGNO)
27471 if (CR_REGNO_P (regno))
27472 return regno - CR0_REGNO + 86;
27473 if (regno == CA_REGNO)
27474 return 101; /* XER */
27475 if (ALTIVEC_REGNO_P (regno))
27476 return regno - FIRST_ALTIVEC_REGNO + 1124;
27477 if (regno == VRSAVE_REGNO)
27479 if (regno == VSCR_REGNO)
27481 if (regno == SPE_ACC_REGNO)
27483 if (regno == SPEFSCR_REGNO)
27485 /* SPE high reg number. We get these values of regno from
27486 rs6000_dwarf_register_span. */
27487 gcc_assert (regno >= 1200 && regno < 1232);
27491 /* target hook eh_return_filter_mode */
27492 static enum machine_mode
27493 rs6000_eh_return_filter_mode (void)
27495 return TARGET_32BIT ? SImode : word_mode;
27498 /* Target hook for scalar_mode_supported_p. */
27500 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27502 if (DECIMAL_FLOAT_MODE_P (mode))
27503 return default_decimal_float_supported_p ();
27505 return default_scalar_mode_supported_p (mode);
27508 /* Target hook for vector_mode_supported_p. */
27510 rs6000_vector_mode_supported_p (enum machine_mode mode)
27513 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27516 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27519 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27526 /* Target hook for invalid_arg_for_unprototyped_fn. */
27527 static const char *
27528 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27530 return (!rs6000_darwin64_abi
27532 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27533 && (funcdecl == NULL_TREE
27534 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27535 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27536 ? N_("AltiVec argument passed to unprototyped function")
27540 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27541 setup by using __stack_chk_fail_local hidden function instead of
27542 calling __stack_chk_fail directly. Otherwise it is better to call
27543 __stack_chk_fail directly. */
27546 rs6000_stack_protect_fail (void)
27548 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27549 ? default_hidden_stack_protect_fail ()
27550 : default_external_stack_protect_fail ();
27554 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27555 int num_operands ATTRIBUTE_UNUSED)
27557 if (rs6000_warn_cell_microcode)
27560 int insn_code_number = recog_memoized (insn);
27561 location_t location = locator_location (INSN_LOCATOR (insn));
27563 /* Punt on insns we cannot recognize. */
27564 if (insn_code_number < 0)
27567 temp = get_insn_template (insn_code_number, insn);
27569 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27570 warning_at (location, OPT_mwarn_cell_microcode,
27571 "emitting microcode insn %s\t[%s] #%d",
27572 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27573 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27574 warning_at (location, OPT_mwarn_cell_microcode,
27575 "emitting conditional microcode insn %s\t[%s] #%d",
27576 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27581 /* Mask options that we want to support inside of attribute((target)) and
27582 #pragma GCC target operations. Note, we do not include things like
27583 64/32-bit, endianess, hard/soft floating point, etc. that would have
27584 different calling sequences. */
27586 struct rs6000_opt_mask {
27587 const char *name; /* option name */
27588 int mask; /* mask to set */
27589 bool invert; /* invert sense of mask */
27590 bool valid_target; /* option is a target option */
27593 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27595 { "altivec", MASK_ALTIVEC, false, true },
27596 { "cmpb", MASK_CMPB, false, true },
27597 { "dlmzb", MASK_DLMZB, false, true },
27598 { "fprnd", MASK_FPRND, false, true },
27599 { "hard-dfp", MASK_DFP, false, true },
27600 { "isel", MASK_ISEL, false, true },
27601 { "mfcrf", MASK_MFCRF, false, true },
27602 { "mfpgpr", MASK_MFPGPR, false, true },
27603 { "mulhw", MASK_MULHW, false, true },
27604 { "multiple", MASK_MULTIPLE, false, true },
27605 { "update", MASK_NO_UPDATE, true , true },
27606 { "popcntb", MASK_POPCNTB, false, true },
27607 { "popcntd", MASK_POPCNTD, false, true },
27608 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27609 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27610 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27611 { "string", MASK_STRING, false, true },
27612 { "vsx", MASK_VSX, false, true },
27615 { "aix64", MASK_64BIT, false, false },
27616 { "aix32", MASK_64BIT, true, false },
27618 { "64", MASK_64BIT, false, false },
27619 { "32", MASK_64BIT, true, false },
27623 { "eabi", MASK_EABI, false, false },
27625 #ifdef MASK_LITTLE_ENDIAN
27626 { "little", MASK_LITTLE_ENDIAN, false, false },
27627 { "big", MASK_LITTLE_ENDIAN, true, false },
27629 #ifdef MASK_RELOCATABLE
27630 { "relocatable", MASK_RELOCATABLE, false, false },
27632 #ifdef MASK_STRICT_ALIGN
27633 { "strict-align", MASK_STRICT_ALIGN, false, false },
27635 { "power", MASK_POWER, false, false },
27636 { "power2", MASK_POWER2, false, false },
27637 { "powerpc", MASK_POWERPC, false, false },
27638 { "soft-float", MASK_SOFT_FLOAT, false, false },
27639 { "string", MASK_STRING, false, false },
27642 /* Option variables that we want to support inside attribute((target)) and
27643 #pragma GCC target operations. */
27645 struct rs6000_opt_var {
27646 const char *name; /* option name */
27647 size_t global_offset; /* offset of the option in global_options. */
27648 size_t target_offset; /* offset of the option in target optiosn. */
27651 static struct rs6000_opt_var const rs6000_opt_vars[] =
27654 offsetof (struct gcc_options, x_TARGET_FRIZ),
27655 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27656 { "avoid-indexed-addresses",
27657 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27658 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27660 offsetof (struct gcc_options, x_rs6000_paired_float),
27661 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27663 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27664 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27667 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27668 parsing. Return true if there were no errors. */
27671 rs6000_inner_target_options (tree args, bool attr_p)
27675 if (args == NULL_TREE)
27678 else if (TREE_CODE (args) == STRING_CST)
27680 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27683 while ((q = strtok (p, ",")) != NULL)
27685 bool error_p = false;
27686 bool not_valid_p = false;
27687 const char *cpu_opt = NULL;
27690 if (strncmp (q, "cpu=", 4) == 0)
27692 int cpu_index = rs6000_cpu_name_lookup (q+4);
27693 if (cpu_index >= 0)
27694 rs6000_cpu_index = cpu_index;
27701 else if (strncmp (q, "tune=", 5) == 0)
27703 int tune_index = rs6000_cpu_name_lookup (q+5);
27704 if (tune_index >= 0)
27705 rs6000_tune_index = tune_index;
27715 bool invert = false;
27719 if (strncmp (r, "no-", 3) == 0)
27725 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27726 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27728 int mask = rs6000_opt_masks[i].mask;
27730 if (!rs6000_opt_masks[i].valid_target)
27731 not_valid_p = true;
27735 target_flags_explicit |= mask;
27737 if (rs6000_opt_masks[i].invert)
27741 target_flags &= ~mask;
27743 target_flags |= mask;
27748 if (error_p && !not_valid_p)
27750 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27751 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27753 size_t j = rs6000_opt_vars[i].global_offset;
27754 *((int *) ((char *)&global_options + j)) = !invert;
27763 const char *eprefix, *esuffix;
27768 eprefix = "__attribute__((__target__(";
27773 eprefix = "#pragma GCC target ";
27778 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27780 else if (not_valid_p)
27781 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27783 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27788 else if (TREE_CODE (args) == TREE_LIST)
27792 tree value = TREE_VALUE (args);
27795 bool ret2 = rs6000_inner_target_options (value, attr_p);
27799 args = TREE_CHAIN (args);
27801 while (args != NULL_TREE);
27805 gcc_unreachable ();
27810 /* Print out the target options as a list for -mdebug=target. */
27813 rs6000_debug_target_options (tree args, const char *prefix)
27815 if (args == NULL_TREE)
27816 fprintf (stderr, "%s<NULL>", prefix);
27818 else if (TREE_CODE (args) == STRING_CST)
27820 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27823 while ((q = strtok (p, ",")) != NULL)
27826 fprintf (stderr, "%s\"%s\"", prefix, q);
27831 else if (TREE_CODE (args) == TREE_LIST)
27835 tree value = TREE_VALUE (args);
27838 rs6000_debug_target_options (value, prefix);
27841 args = TREE_CHAIN (args);
27843 while (args != NULL_TREE);
27847 gcc_unreachable ();
27853 /* Hook to validate attribute((target("..."))). */
27856 rs6000_valid_attribute_p (tree fndecl,
27857 tree ARG_UNUSED (name),
27861 struct cl_target_option cur_target;
27863 tree old_optimize = build_optimization_node ();
27864 tree new_target, new_optimize;
27865 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27867 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27869 if (TARGET_DEBUG_TARGET)
27871 tree tname = DECL_NAME (fndecl);
27872 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27874 fprintf (stderr, "function: %.*s\n",
27875 (int) IDENTIFIER_LENGTH (tname),
27876 IDENTIFIER_POINTER (tname));
27878 fprintf (stderr, "function: unknown\n");
27880 fprintf (stderr, "args:");
27881 rs6000_debug_target_options (args, " ");
27882 fprintf (stderr, "\n");
27885 fprintf (stderr, "flags: 0x%x\n", flags);
27887 fprintf (stderr, "--------------------\n");
27890 old_optimize = build_optimization_node ();
27891 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27893 /* If the function changed the optimization levels as well as setting target
27894 options, start with the optimizations specified. */
27895 if (func_optimize && func_optimize != old_optimize)
27896 cl_optimization_restore (&global_options,
27897 TREE_OPTIMIZATION (func_optimize));
27899 /* The target attributes may also change some optimization flags, so update
27900 the optimization options if necessary. */
27901 cl_target_option_save (&cur_target, &global_options);
27902 rs6000_cpu_index = rs6000_tune_index = -1;
27903 ret = rs6000_inner_target_options (args, true);
27905 /* Set up any additional state. */
27908 ret = rs6000_option_override_internal (false);
27909 new_target = build_target_option_node ();
27914 new_optimize = build_optimization_node ();
27921 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27923 if (old_optimize != new_optimize)
27924 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27927 cl_target_option_restore (&global_options, &cur_target);
27929 if (old_optimize != new_optimize)
27930 cl_optimization_restore (&global_options,
27931 TREE_OPTIMIZATION (old_optimize));
27937 /* Hook to validate the current #pragma GCC target and set the state, and
27938 update the macros based on what was changed. If ARGS is NULL, then
27939 POP_TARGET is used to reset the options. */
27942 rs6000_pragma_target_parse (tree args, tree pop_target)
27947 if (TARGET_DEBUG_TARGET)
27949 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27950 fprintf (stderr, "args:");
27951 rs6000_debug_target_options (args, " ");
27952 fprintf (stderr, "\n");
27956 fprintf (stderr, "pop_target:\n");
27957 debug_tree (pop_target);
27960 fprintf (stderr, "pop_target: <NULL>\n");
27962 fprintf (stderr, "--------------------\n");
27968 cur_tree = ((pop_target)
27970 : target_option_default_node);
27971 cl_target_option_restore (&global_options,
27972 TREE_TARGET_OPTION (cur_tree));
27976 rs6000_cpu_index = rs6000_tune_index = -1;
27977 ret = rs6000_inner_target_options (args, false);
27978 cur_tree = build_target_option_node ();
27985 target_option_current_node = cur_tree;
27991 /* Remember the last target of rs6000_set_current_function. */
27992 static GTY(()) tree rs6000_previous_fndecl;
27994 /* Establish appropriate back-end context for processing the function
27995 FNDECL. The argument might be NULL to indicate processing at top
27996 level, outside of any function scope. */
27998 rs6000_set_current_function (tree fndecl)
28000 tree old_tree = (rs6000_previous_fndecl
28001 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
28004 tree new_tree = (fndecl
28005 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
28008 if (TARGET_DEBUG_TARGET)
28010 bool print_final = false;
28011 fprintf (stderr, "\n==================== rs6000_set_current_function");
28014 fprintf (stderr, ", fndecl %s (%p)",
28015 (DECL_NAME (fndecl)
28016 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
28017 : "<unknown>"), (void *)fndecl);
28019 if (rs6000_previous_fndecl)
28020 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
28022 fprintf (stderr, "\n");
28025 fprintf (stderr, "\nnew fndecl target specific options:\n");
28026 debug_tree (new_tree);
28027 print_final = true;
28032 fprintf (stderr, "\nold fndecl target specific options:\n");
28033 debug_tree (old_tree);
28034 print_final = true;
28038 fprintf (stderr, "--------------------\n");
28041 /* Only change the context if the function changes. This hook is called
28042 several times in the course of compiling a function, and we don't want to
28043 slow things down too much or call target_reinit when it isn't safe. */
28044 if (fndecl && fndecl != rs6000_previous_fndecl)
28046 rs6000_previous_fndecl = fndecl;
28047 if (old_tree == new_tree)
28052 cl_target_option_restore (&global_options,
28053 TREE_TARGET_OPTION (new_tree));
28059 struct cl_target_option *def
28060 = TREE_TARGET_OPTION (target_option_current_node);
28062 cl_target_option_restore (&global_options, def);
28069 /* Save the current options */
28072 rs6000_function_specific_save (struct cl_target_option *ptr)
28074 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28077 /* Restore the current options */
28080 rs6000_function_specific_restore (struct cl_target_option *ptr)
28082 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28083 (void) rs6000_option_override_internal (false);
28086 /* Print the current options */
28089 rs6000_function_specific_print (FILE *file, int indent,
28090 struct cl_target_option *ptr)
28093 int flags = ptr->x_target_flags;
28095 /* Print the various mask options. */
28096 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28097 if ((flags & rs6000_opt_masks[i].mask) != 0)
28099 flags &= ~ rs6000_opt_masks[i].mask;
28100 fprintf (file, "%*s-m%s%s\n", indent, "",
28101 rs6000_opt_masks[i].invert ? "no-" : "",
28102 rs6000_opt_masks[i].name);
28105 /* Print the various options that are variables. */
28106 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28108 size_t j = rs6000_opt_vars[i].target_offset;
28109 if (((signed char *) ptr)[j])
28110 fprintf (file, "%*s-m%s\n", indent, "",
28111 rs6000_opt_vars[i].name);
28116 /* Hook to determine if one function can safely inline another. */
28119 rs6000_can_inline_p (tree caller, tree callee)
28122 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28123 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28125 /* If callee has no option attributes, then it is ok to inline. */
28129 /* If caller has no option attributes, but callee does then it is not ok to
28131 else if (!caller_tree)
28136 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28137 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28139 /* Callee's options should a subset of the caller's, i.e. a vsx function
28140 can inline an altivec function but a non-vsx function can't inline a
28142 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28143 == callee_opts->x_target_flags)
28147 if (TARGET_DEBUG_TARGET)
28148 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28149 (DECL_NAME (caller)
28150 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28152 (DECL_NAME (callee)
28153 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28155 (ret ? "can" : "cannot"));
28160 /* Allocate a stack temp and fixup the address so it meets the particular
28161 memory requirements (either offetable or REG+REG addressing). */
28164 rs6000_allocate_stack_temp (enum machine_mode mode,
28165 bool offsettable_p,
28168 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28169 rtx addr = XEXP (stack, 0);
28170 int strict_p = (reload_in_progress || reload_completed);
28172 if (!legitimate_indirect_address_p (addr, strict_p))
28175 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28176 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28178 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28179 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28185 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28186 to such a form to deal with memory reference instructions like STFIWX that
28187 only take reg+reg addressing. */
28190 rs6000_address_for_fpconvert (rtx x)
28192 int strict_p = (reload_in_progress || reload_completed);
28195 gcc_assert (MEM_P (x));
28196 addr = XEXP (x, 0);
28197 if (! legitimate_indirect_address_p (addr, strict_p)
28198 && ! legitimate_indexed_address_p (addr, strict_p))
28200 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28202 rtx reg = XEXP (addr, 0);
28203 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28204 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28205 gcc_assert (REG_P (reg));
28206 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28209 else if (GET_CODE (addr) == PRE_MODIFY)
28211 rtx reg = XEXP (addr, 0);
28212 rtx expr = XEXP (addr, 1);
28213 gcc_assert (REG_P (reg));
28214 gcc_assert (GET_CODE (expr) == PLUS);
28215 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28219 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28225 /* Given a memory reference, if it is not in the form for altivec memory
28226 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28227 convert to the altivec format. */
28230 rs6000_address_for_altivec (rtx x)
28232 gcc_assert (MEM_P (x));
28233 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28235 rtx addr = XEXP (x, 0);
28236 int strict_p = (reload_in_progress || reload_completed);
28238 if (!legitimate_indexed_address_p (addr, strict_p)
28239 && !legitimate_indirect_address_p (addr, strict_p))
28240 addr = copy_to_mode_reg (Pmode, addr);
28242 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28243 x = change_address (x, GET_MODE (x), addr);
28250 #include "gt-rs6000.h"