1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
55 #include "sched-int.h"
57 #include "tree-flow.h"
60 #include "tm-constrs.h"
63 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
66 #include "gstab.h" /* for N_SLINE */
69 #ifndef TARGET_NO_PROTOTYPE
70 #define TARGET_NO_PROTOTYPE 0
73 #define min(A,B) ((A) < (B) ? (A) : (B))
74 #define max(A,B) ((A) > (B) ? (A) : (B))
76 /* Structure used to define the rs6000 stack */
77 typedef struct rs6000_stack {
78 int reload_completed; /* stack info won't change from here on */
79 int first_gp_reg_save; /* first callee saved GP register used */
80 int first_fp_reg_save; /* first callee saved FP register used */
81 int first_altivec_reg_save; /* first callee saved AltiVec register used */
82 int lr_save_p; /* true if the link reg needs to be saved */
83 int cr_save_p; /* true if the CR reg needs to be saved */
84 unsigned int vrsave_mask; /* mask of vec registers to save */
85 int push_p; /* true if we need to allocate stack space */
86 int calls_p; /* true if the function makes any calls */
87 int world_save_p; /* true if we're saving *everything*:
88 r13-r31, cr, f14-f31, vrsave, v20-v31 */
89 enum rs6000_abi abi; /* which ABI to use */
90 int gp_save_offset; /* offset to save GP regs from initial SP */
91 int fp_save_offset; /* offset to save FP regs from initial SP */
92 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
93 int lr_save_offset; /* offset to save LR from initial SP */
94 int cr_save_offset; /* offset to save CR from initial SP */
95 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
96 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
97 int varargs_save_offset; /* offset to save the varargs registers */
98 int ehrd_offset; /* offset to EH return data */
99 int reg_size; /* register size (4 or 8) */
100 HOST_WIDE_INT vars_size; /* variable save area size */
101 int parm_size; /* outgoing parameter size */
102 int save_size; /* save area size */
103 int fixed_size; /* fixed size of stack frame */
104 int gp_size; /* size of saved GP registers */
105 int fp_size; /* size of saved FP registers */
106 int altivec_size; /* size of saved AltiVec registers */
107 int cr_size; /* size to hold CR if not in save_size */
108 int vrsave_size; /* size to hold VRSAVE if not in save_size */
109 int altivec_padding_size; /* size of altivec alignment padding if
111 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
112 int spe_padding_size;
113 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
114 int spe_64bit_regs_used;
118 /* A C structure for machine-specific, per-function data.
119 This is added to the cfun structure. */
120 typedef struct GTY(()) machine_function
122 /* Some local-dynamic symbol. */
123 const char *some_ld_name;
124 /* Whether the instruction chain has been scanned already. */
125 int insn_chain_scanned_p;
126 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
127 int ra_needs_full_frame;
128 /* Flags if __builtin_return_address (0) was used. */
130 /* Cache lr_save_p after expansion of builtin_eh_return. */
132 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
133 varargs save area. */
134 HOST_WIDE_INT varargs_save_offset;
135 /* Temporary stack slot to use for SDmode copies. This slot is
136 64-bits wide and is allocated early enough so that the offset
137 does not overflow the 16-bit load/store offset field. */
138 rtx sdmode_stack_slot;
141 /* Support targetm.vectorize.builtin_mask_for_load. */
142 static GTY(()) tree altivec_builtin_mask_for_load;
144 /* Set to nonzero once AIX common-mode calls have been defined. */
145 static GTY(()) int common_mode_defined;
147 /* Label number of label created for -mrelocatable, to call to so we can
148 get the address of the GOT section */
149 static int rs6000_pic_labelno;
152 /* Counter for labels which are to be placed in .fixup. */
153 int fixuplabelno = 0;
156 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
159 /* Specify the machine mode that pointers have. After generation of rtl, the
160 compiler makes no further distinction between pointers and any other objects
161 of this machine mode. The type is unsigned since not all things that
162 include rs6000.h also include machmode.h. */
163 unsigned rs6000_pmode;
165 /* Width in bits of a pointer. */
166 unsigned rs6000_pointer_size;
168 #ifdef HAVE_AS_GNU_ATTRIBUTE
169 /* Flag whether floating point values have been passed/returned. */
170 static bool rs6000_passes_float;
171 /* Flag whether vector values have been passed/returned. */
172 static bool rs6000_passes_vector;
173 /* Flag whether small (<= 8 byte) structures have been returned. */
174 static bool rs6000_returns_struct;
177 /* Value is TRUE if register/mode pair is acceptable. */
178 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
180 /* Maximum number of registers needed for a given register class and mode. */
181 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
183 /* How many registers are needed for a given register and mode. */
184 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
186 /* Map register number to register class. */
187 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
189 /* Reload functions based on the type and the vector unit. */
190 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
192 /* Built in types. */
193 tree rs6000_builtin_types[RS6000_BTI_MAX];
194 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
196 /* Flag to say the TOC is initialized */
198 char toc_label_name[10];
200 /* Cached value of rs6000_variable_issue. This is cached in
201 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
202 static short cached_can_issue_more;
204 static GTY(()) section *read_only_data_section;
205 static GTY(()) section *private_data_section;
206 static GTY(()) section *read_only_private_data_section;
207 static GTY(()) section *sdata2_section;
208 static GTY(()) section *toc_section;
210 struct builtin_description
212 /* mask is not const because we're going to alter it below. This
213 nonsense will go away when we rewrite the -march infrastructure
214 to give us more target flag bits. */
216 const enum insn_code icode;
217 const char *const name;
218 const enum rs6000_builtins code;
221 /* Describe the vector unit used for modes. */
222 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
223 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
225 /* Register classes for various constraints that are based on the target
227 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
229 /* Describe the alignment of a vector. */
230 int rs6000_vector_align[NUM_MACHINE_MODES];
232 /* Map selected modes to types for builtins. */
233 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
235 /* What modes to automatically generate reciprocal divide estimate (fre) and
236 reciprocal sqrt (frsqrte) for. */
237 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
239 /* Masks to determine which reciprocal esitmate instructions to generate
241 enum rs6000_recip_mask {
242 RECIP_SF_DIV = 0x001, /* Use divide estimate */
243 RECIP_DF_DIV = 0x002,
244 RECIP_V4SF_DIV = 0x004,
245 RECIP_V2DF_DIV = 0x008,
247 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
248 RECIP_DF_RSQRT = 0x020,
249 RECIP_V4SF_RSQRT = 0x040,
250 RECIP_V2DF_RSQRT = 0x080,
252 /* Various combination of flags for -mrecip=xxx. */
254 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
255 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
256 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
258 RECIP_HIGH_PRECISION = RECIP_ALL,
260 /* On low precision machines like the power5, don't enable double precision
261 reciprocal square root estimate, since it isn't accurate enough. */
262 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
265 /* -mrecip options. */
268 const char *string; /* option name */
269 unsigned int mask; /* mask bits to set */
270 } recip_options[] = {
271 { "all", RECIP_ALL },
272 { "none", RECIP_NONE },
273 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
275 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
276 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
277 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
278 | RECIP_V2DF_RSQRT) },
279 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
280 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
283 /* 2 argument gen function typedef. */
284 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
287 /* Target cpu costs. */
289 struct processor_costs {
290 const int mulsi; /* cost of SImode multiplication. */
291 const int mulsi_const; /* cost of SImode multiplication by constant. */
292 const int mulsi_const9; /* cost of SImode mult by short constant. */
293 const int muldi; /* cost of DImode multiplication. */
294 const int divsi; /* cost of SImode division. */
295 const int divdi; /* cost of DImode division. */
296 const int fp; /* cost of simple SFmode and DFmode insns. */
297 const int dmul; /* cost of DFmode multiplication (and fmadd). */
298 const int sdiv; /* cost of SFmode division (fdivs). */
299 const int ddiv; /* cost of DFmode division (fdiv). */
300 const int cache_line_size; /* cache line size in bytes. */
301 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
302 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
303 const int simultaneous_prefetches; /* number of parallel prefetch
307 const struct processor_costs *rs6000_cost;
309 /* Processor costs (relative to an add) */
311 /* Instruction size costs on 32bit processors. */
313 struct processor_costs size32_cost = {
314 COSTS_N_INSNS (1), /* mulsi */
315 COSTS_N_INSNS (1), /* mulsi_const */
316 COSTS_N_INSNS (1), /* mulsi_const9 */
317 COSTS_N_INSNS (1), /* muldi */
318 COSTS_N_INSNS (1), /* divsi */
319 COSTS_N_INSNS (1), /* divdi */
320 COSTS_N_INSNS (1), /* fp */
321 COSTS_N_INSNS (1), /* dmul */
322 COSTS_N_INSNS (1), /* sdiv */
323 COSTS_N_INSNS (1), /* ddiv */
330 /* Instruction size costs on 64bit processors. */
332 struct processor_costs size64_cost = {
333 COSTS_N_INSNS (1), /* mulsi */
334 COSTS_N_INSNS (1), /* mulsi_const */
335 COSTS_N_INSNS (1), /* mulsi_const9 */
336 COSTS_N_INSNS (1), /* muldi */
337 COSTS_N_INSNS (1), /* divsi */
338 COSTS_N_INSNS (1), /* divdi */
339 COSTS_N_INSNS (1), /* fp */
340 COSTS_N_INSNS (1), /* dmul */
341 COSTS_N_INSNS (1), /* sdiv */
342 COSTS_N_INSNS (1), /* ddiv */
349 /* Instruction costs on RIOS1 processors. */
351 struct processor_costs rios1_cost = {
352 COSTS_N_INSNS (5), /* mulsi */
353 COSTS_N_INSNS (4), /* mulsi_const */
354 COSTS_N_INSNS (3), /* mulsi_const9 */
355 COSTS_N_INSNS (5), /* muldi */
356 COSTS_N_INSNS (19), /* divsi */
357 COSTS_N_INSNS (19), /* divdi */
358 COSTS_N_INSNS (2), /* fp */
359 COSTS_N_INSNS (2), /* dmul */
360 COSTS_N_INSNS (19), /* sdiv */
361 COSTS_N_INSNS (19), /* ddiv */
362 128, /* cache line size */
368 /* Instruction costs on RIOS2 processors. */
370 struct processor_costs rios2_cost = {
371 COSTS_N_INSNS (2), /* mulsi */
372 COSTS_N_INSNS (2), /* mulsi_const */
373 COSTS_N_INSNS (2), /* mulsi_const9 */
374 COSTS_N_INSNS (2), /* muldi */
375 COSTS_N_INSNS (13), /* divsi */
376 COSTS_N_INSNS (13), /* divdi */
377 COSTS_N_INSNS (2), /* fp */
378 COSTS_N_INSNS (2), /* dmul */
379 COSTS_N_INSNS (17), /* sdiv */
380 COSTS_N_INSNS (17), /* ddiv */
381 256, /* cache line size */
387 /* Instruction costs on RS64A processors. */
389 struct processor_costs rs64a_cost = {
390 COSTS_N_INSNS (20), /* mulsi */
391 COSTS_N_INSNS (12), /* mulsi_const */
392 COSTS_N_INSNS (8), /* mulsi_const9 */
393 COSTS_N_INSNS (34), /* muldi */
394 COSTS_N_INSNS (65), /* divsi */
395 COSTS_N_INSNS (67), /* divdi */
396 COSTS_N_INSNS (4), /* fp */
397 COSTS_N_INSNS (4), /* dmul */
398 COSTS_N_INSNS (31), /* sdiv */
399 COSTS_N_INSNS (31), /* ddiv */
400 128, /* cache line size */
406 /* Instruction costs on MPCCORE processors. */
408 struct processor_costs mpccore_cost = {
409 COSTS_N_INSNS (2), /* mulsi */
410 COSTS_N_INSNS (2), /* mulsi_const */
411 COSTS_N_INSNS (2), /* mulsi_const9 */
412 COSTS_N_INSNS (2), /* muldi */
413 COSTS_N_INSNS (6), /* divsi */
414 COSTS_N_INSNS (6), /* divdi */
415 COSTS_N_INSNS (4), /* fp */
416 COSTS_N_INSNS (5), /* dmul */
417 COSTS_N_INSNS (10), /* sdiv */
418 COSTS_N_INSNS (17), /* ddiv */
419 32, /* cache line size */
425 /* Instruction costs on PPC403 processors. */
427 struct processor_costs ppc403_cost = {
428 COSTS_N_INSNS (4), /* mulsi */
429 COSTS_N_INSNS (4), /* mulsi_const */
430 COSTS_N_INSNS (4), /* mulsi_const9 */
431 COSTS_N_INSNS (4), /* muldi */
432 COSTS_N_INSNS (33), /* divsi */
433 COSTS_N_INSNS (33), /* divdi */
434 COSTS_N_INSNS (11), /* fp */
435 COSTS_N_INSNS (11), /* dmul */
436 COSTS_N_INSNS (11), /* sdiv */
437 COSTS_N_INSNS (11), /* ddiv */
438 32, /* cache line size */
444 /* Instruction costs on PPC405 processors. */
446 struct processor_costs ppc405_cost = {
447 COSTS_N_INSNS (5), /* mulsi */
448 COSTS_N_INSNS (4), /* mulsi_const */
449 COSTS_N_INSNS (3), /* mulsi_const9 */
450 COSTS_N_INSNS (5), /* muldi */
451 COSTS_N_INSNS (35), /* divsi */
452 COSTS_N_INSNS (35), /* divdi */
453 COSTS_N_INSNS (11), /* fp */
454 COSTS_N_INSNS (11), /* dmul */
455 COSTS_N_INSNS (11), /* sdiv */
456 COSTS_N_INSNS (11), /* ddiv */
457 32, /* cache line size */
463 /* Instruction costs on PPC440 processors. */
465 struct processor_costs ppc440_cost = {
466 COSTS_N_INSNS (3), /* mulsi */
467 COSTS_N_INSNS (2), /* mulsi_const */
468 COSTS_N_INSNS (2), /* mulsi_const9 */
469 COSTS_N_INSNS (3), /* muldi */
470 COSTS_N_INSNS (34), /* divsi */
471 COSTS_N_INSNS (34), /* divdi */
472 COSTS_N_INSNS (5), /* fp */
473 COSTS_N_INSNS (5), /* dmul */
474 COSTS_N_INSNS (19), /* sdiv */
475 COSTS_N_INSNS (33), /* ddiv */
476 32, /* cache line size */
482 /* Instruction costs on PPC476 processors. */
484 struct processor_costs ppc476_cost = {
485 COSTS_N_INSNS (4), /* mulsi */
486 COSTS_N_INSNS (4), /* mulsi_const */
487 COSTS_N_INSNS (4), /* mulsi_const9 */
488 COSTS_N_INSNS (4), /* muldi */
489 COSTS_N_INSNS (11), /* divsi */
490 COSTS_N_INSNS (11), /* divdi */
491 COSTS_N_INSNS (6), /* fp */
492 COSTS_N_INSNS (6), /* dmul */
493 COSTS_N_INSNS (19), /* sdiv */
494 COSTS_N_INSNS (33), /* ddiv */
495 32, /* l1 cache line size */
501 /* Instruction costs on PPC601 processors. */
503 struct processor_costs ppc601_cost = {
504 COSTS_N_INSNS (5), /* mulsi */
505 COSTS_N_INSNS (5), /* mulsi_const */
506 COSTS_N_INSNS (5), /* mulsi_const9 */
507 COSTS_N_INSNS (5), /* muldi */
508 COSTS_N_INSNS (36), /* divsi */
509 COSTS_N_INSNS (36), /* divdi */
510 COSTS_N_INSNS (4), /* fp */
511 COSTS_N_INSNS (5), /* dmul */
512 COSTS_N_INSNS (17), /* sdiv */
513 COSTS_N_INSNS (31), /* ddiv */
514 32, /* cache line size */
520 /* Instruction costs on PPC603 processors. */
522 struct processor_costs ppc603_cost = {
523 COSTS_N_INSNS (5), /* mulsi */
524 COSTS_N_INSNS (3), /* mulsi_const */
525 COSTS_N_INSNS (2), /* mulsi_const9 */
526 COSTS_N_INSNS (5), /* muldi */
527 COSTS_N_INSNS (37), /* divsi */
528 COSTS_N_INSNS (37), /* divdi */
529 COSTS_N_INSNS (3), /* fp */
530 COSTS_N_INSNS (4), /* dmul */
531 COSTS_N_INSNS (18), /* sdiv */
532 COSTS_N_INSNS (33), /* ddiv */
533 32, /* cache line size */
539 /* Instruction costs on PPC604 processors. */
541 struct processor_costs ppc604_cost = {
542 COSTS_N_INSNS (4), /* mulsi */
543 COSTS_N_INSNS (4), /* mulsi_const */
544 COSTS_N_INSNS (4), /* mulsi_const9 */
545 COSTS_N_INSNS (4), /* muldi */
546 COSTS_N_INSNS (20), /* divsi */
547 COSTS_N_INSNS (20), /* divdi */
548 COSTS_N_INSNS (3), /* fp */
549 COSTS_N_INSNS (3), /* dmul */
550 COSTS_N_INSNS (18), /* sdiv */
551 COSTS_N_INSNS (32), /* ddiv */
552 32, /* cache line size */
558 /* Instruction costs on PPC604e processors. */
560 struct processor_costs ppc604e_cost = {
561 COSTS_N_INSNS (2), /* mulsi */
562 COSTS_N_INSNS (2), /* mulsi_const */
563 COSTS_N_INSNS (2), /* mulsi_const9 */
564 COSTS_N_INSNS (2), /* muldi */
565 COSTS_N_INSNS (20), /* divsi */
566 COSTS_N_INSNS (20), /* divdi */
567 COSTS_N_INSNS (3), /* fp */
568 COSTS_N_INSNS (3), /* dmul */
569 COSTS_N_INSNS (18), /* sdiv */
570 COSTS_N_INSNS (32), /* ddiv */
571 32, /* cache line size */
577 /* Instruction costs on PPC620 processors. */
579 struct processor_costs ppc620_cost = {
580 COSTS_N_INSNS (5), /* mulsi */
581 COSTS_N_INSNS (4), /* mulsi_const */
582 COSTS_N_INSNS (3), /* mulsi_const9 */
583 COSTS_N_INSNS (7), /* muldi */
584 COSTS_N_INSNS (21), /* divsi */
585 COSTS_N_INSNS (37), /* divdi */
586 COSTS_N_INSNS (3), /* fp */
587 COSTS_N_INSNS (3), /* dmul */
588 COSTS_N_INSNS (18), /* sdiv */
589 COSTS_N_INSNS (32), /* ddiv */
590 128, /* cache line size */
596 /* Instruction costs on PPC630 processors. */
598 struct processor_costs ppc630_cost = {
599 COSTS_N_INSNS (5), /* mulsi */
600 COSTS_N_INSNS (4), /* mulsi_const */
601 COSTS_N_INSNS (3), /* mulsi_const9 */
602 COSTS_N_INSNS (7), /* muldi */
603 COSTS_N_INSNS (21), /* divsi */
604 COSTS_N_INSNS (37), /* divdi */
605 COSTS_N_INSNS (3), /* fp */
606 COSTS_N_INSNS (3), /* dmul */
607 COSTS_N_INSNS (17), /* sdiv */
608 COSTS_N_INSNS (21), /* ddiv */
609 128, /* cache line size */
615 /* Instruction costs on Cell processor. */
616 /* COSTS_N_INSNS (1) ~ one add. */
618 struct processor_costs ppccell_cost = {
619 COSTS_N_INSNS (9/2)+2, /* mulsi */
620 COSTS_N_INSNS (6/2), /* mulsi_const */
621 COSTS_N_INSNS (6/2), /* mulsi_const9 */
622 COSTS_N_INSNS (15/2)+2, /* muldi */
623 COSTS_N_INSNS (38/2), /* divsi */
624 COSTS_N_INSNS (70/2), /* divdi */
625 COSTS_N_INSNS (10/2), /* fp */
626 COSTS_N_INSNS (10/2), /* dmul */
627 COSTS_N_INSNS (74/2), /* sdiv */
628 COSTS_N_INSNS (74/2), /* ddiv */
629 128, /* cache line size */
635 /* Instruction costs on PPC750 and PPC7400 processors. */
637 struct processor_costs ppc750_cost = {
638 COSTS_N_INSNS (5), /* mulsi */
639 COSTS_N_INSNS (3), /* mulsi_const */
640 COSTS_N_INSNS (2), /* mulsi_const9 */
641 COSTS_N_INSNS (5), /* muldi */
642 COSTS_N_INSNS (17), /* divsi */
643 COSTS_N_INSNS (17), /* divdi */
644 COSTS_N_INSNS (3), /* fp */
645 COSTS_N_INSNS (3), /* dmul */
646 COSTS_N_INSNS (17), /* sdiv */
647 COSTS_N_INSNS (31), /* ddiv */
648 32, /* cache line size */
654 /* Instruction costs on PPC7450 processors. */
656 struct processor_costs ppc7450_cost = {
657 COSTS_N_INSNS (4), /* mulsi */
658 COSTS_N_INSNS (3), /* mulsi_const */
659 COSTS_N_INSNS (3), /* mulsi_const9 */
660 COSTS_N_INSNS (4), /* muldi */
661 COSTS_N_INSNS (23), /* divsi */
662 COSTS_N_INSNS (23), /* divdi */
663 COSTS_N_INSNS (5), /* fp */
664 COSTS_N_INSNS (5), /* dmul */
665 COSTS_N_INSNS (21), /* sdiv */
666 COSTS_N_INSNS (35), /* ddiv */
667 32, /* cache line size */
673 /* Instruction costs on PPC8540 processors. */
675 struct processor_costs ppc8540_cost = {
676 COSTS_N_INSNS (4), /* mulsi */
677 COSTS_N_INSNS (4), /* mulsi_const */
678 COSTS_N_INSNS (4), /* mulsi_const9 */
679 COSTS_N_INSNS (4), /* muldi */
680 COSTS_N_INSNS (19), /* divsi */
681 COSTS_N_INSNS (19), /* divdi */
682 COSTS_N_INSNS (4), /* fp */
683 COSTS_N_INSNS (4), /* dmul */
684 COSTS_N_INSNS (29), /* sdiv */
685 COSTS_N_INSNS (29), /* ddiv */
686 32, /* cache line size */
689 1, /* prefetch streams /*/
692 /* Instruction costs on E300C2 and E300C3 cores. */
694 struct processor_costs ppce300c2c3_cost = {
695 COSTS_N_INSNS (4), /* mulsi */
696 COSTS_N_INSNS (4), /* mulsi_const */
697 COSTS_N_INSNS (4), /* mulsi_const9 */
698 COSTS_N_INSNS (4), /* muldi */
699 COSTS_N_INSNS (19), /* divsi */
700 COSTS_N_INSNS (19), /* divdi */
701 COSTS_N_INSNS (3), /* fp */
702 COSTS_N_INSNS (4), /* dmul */
703 COSTS_N_INSNS (18), /* sdiv */
704 COSTS_N_INSNS (33), /* ddiv */
708 1, /* prefetch streams /*/
711 /* Instruction costs on PPCE500MC processors. */
713 struct processor_costs ppce500mc_cost = {
714 COSTS_N_INSNS (4), /* mulsi */
715 COSTS_N_INSNS (4), /* mulsi_const */
716 COSTS_N_INSNS (4), /* mulsi_const9 */
717 COSTS_N_INSNS (4), /* muldi */
718 COSTS_N_INSNS (14), /* divsi */
719 COSTS_N_INSNS (14), /* divdi */
720 COSTS_N_INSNS (8), /* fp */
721 COSTS_N_INSNS (10), /* dmul */
722 COSTS_N_INSNS (36), /* sdiv */
723 COSTS_N_INSNS (66), /* ddiv */
724 64, /* cache line size */
727 1, /* prefetch streams /*/
730 /* Instruction costs on PPCE500MC64 processors. */
732 struct processor_costs ppce500mc64_cost = {
733 COSTS_N_INSNS (4), /* mulsi */
734 COSTS_N_INSNS (4), /* mulsi_const */
735 COSTS_N_INSNS (4), /* mulsi_const9 */
736 COSTS_N_INSNS (4), /* muldi */
737 COSTS_N_INSNS (14), /* divsi */
738 COSTS_N_INSNS (14), /* divdi */
739 COSTS_N_INSNS (4), /* fp */
740 COSTS_N_INSNS (10), /* dmul */
741 COSTS_N_INSNS (36), /* sdiv */
742 COSTS_N_INSNS (66), /* ddiv */
743 64, /* cache line size */
746 1, /* prefetch streams /*/
749 /* Instruction costs on AppliedMicro Titan processors. */
751 struct processor_costs titan_cost = {
752 COSTS_N_INSNS (5), /* mulsi */
753 COSTS_N_INSNS (5), /* mulsi_const */
754 COSTS_N_INSNS (5), /* mulsi_const9 */
755 COSTS_N_INSNS (5), /* muldi */
756 COSTS_N_INSNS (18), /* divsi */
757 COSTS_N_INSNS (18), /* divdi */
758 COSTS_N_INSNS (10), /* fp */
759 COSTS_N_INSNS (10), /* dmul */
760 COSTS_N_INSNS (46), /* sdiv */
761 COSTS_N_INSNS (72), /* ddiv */
762 32, /* cache line size */
765 1, /* prefetch streams /*/
768 /* Instruction costs on POWER4 and POWER5 processors. */
770 struct processor_costs power4_cost = {
771 COSTS_N_INSNS (3), /* mulsi */
772 COSTS_N_INSNS (2), /* mulsi_const */
773 COSTS_N_INSNS (2), /* mulsi_const9 */
774 COSTS_N_INSNS (4), /* muldi */
775 COSTS_N_INSNS (18), /* divsi */
776 COSTS_N_INSNS (34), /* divdi */
777 COSTS_N_INSNS (3), /* fp */
778 COSTS_N_INSNS (3), /* dmul */
779 COSTS_N_INSNS (17), /* sdiv */
780 COSTS_N_INSNS (17), /* ddiv */
781 128, /* cache line size */
784 8, /* prefetch streams /*/
787 /* Instruction costs on POWER6 processors. */
789 struct processor_costs power6_cost = {
790 COSTS_N_INSNS (8), /* mulsi */
791 COSTS_N_INSNS (8), /* mulsi_const */
792 COSTS_N_INSNS (8), /* mulsi_const9 */
793 COSTS_N_INSNS (8), /* muldi */
794 COSTS_N_INSNS (22), /* divsi */
795 COSTS_N_INSNS (28), /* divdi */
796 COSTS_N_INSNS (3), /* fp */
797 COSTS_N_INSNS (3), /* dmul */
798 COSTS_N_INSNS (13), /* sdiv */
799 COSTS_N_INSNS (16), /* ddiv */
800 128, /* cache line size */
803 16, /* prefetch streams */
806 /* Instruction costs on POWER7 processors. */
808 struct processor_costs power7_cost = {
809 COSTS_N_INSNS (2), /* mulsi */
810 COSTS_N_INSNS (2), /* mulsi_const */
811 COSTS_N_INSNS (2), /* mulsi_const9 */
812 COSTS_N_INSNS (2), /* muldi */
813 COSTS_N_INSNS (18), /* divsi */
814 COSTS_N_INSNS (34), /* divdi */
815 COSTS_N_INSNS (3), /* fp */
816 COSTS_N_INSNS (3), /* dmul */
817 COSTS_N_INSNS (13), /* sdiv */
818 COSTS_N_INSNS (16), /* ddiv */
819 128, /* cache line size */
822 12, /* prefetch streams */
825 /* Instruction costs on POWER A2 processors. */
827 struct processor_costs ppca2_cost = {
828 COSTS_N_INSNS (16), /* mulsi */
829 COSTS_N_INSNS (16), /* mulsi_const */
830 COSTS_N_INSNS (16), /* mulsi_const9 */
831 COSTS_N_INSNS (16), /* muldi */
832 COSTS_N_INSNS (22), /* divsi */
833 COSTS_N_INSNS (28), /* divdi */
834 COSTS_N_INSNS (3), /* fp */
835 COSTS_N_INSNS (3), /* dmul */
836 COSTS_N_INSNS (59), /* sdiv */
837 COSTS_N_INSNS (72), /* ddiv */
841 16, /* prefetch streams */
845 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
846 #undef RS6000_BUILTIN
847 #undef RS6000_BUILTIN_EQUATE
848 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
849 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
851 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
853 #include "rs6000-builtin.def"
856 #undef RS6000_BUILTIN
857 #undef RS6000_BUILTIN_EQUATE
859 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
860 static tree (*rs6000_veclib_handler) (tree, tree, tree);
863 static bool rs6000_function_ok_for_sibcall (tree, tree);
864 static const char *rs6000_invalid_within_doloop (const_rtx);
865 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
866 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
867 static rtx rs6000_generate_compare (rtx, enum machine_mode);
868 static void rs6000_emit_stack_tie (void);
869 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
870 static bool spe_func_has_64bit_regs_p (void);
871 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
873 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
874 static unsigned rs6000_hash_constant (rtx);
875 static unsigned toc_hash_function (const void *);
876 static int toc_hash_eq (const void *, const void *);
877 static bool reg_offset_addressing_ok_p (enum machine_mode);
878 static bool virtual_stack_registers_memory_p (rtx);
879 static bool constant_pool_expr_p (rtx);
880 static bool legitimate_small_data_p (enum machine_mode, rtx);
881 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
882 static struct machine_function * rs6000_init_machine_status (void);
883 static bool rs6000_assemble_integer (rtx, unsigned int, int);
884 static bool no_global_regs_above (int, bool);
885 #ifdef HAVE_GAS_HIDDEN
886 static void rs6000_assemble_visibility (tree, int);
888 static int rs6000_ra_ever_killed (void);
889 static bool rs6000_attribute_takes_identifier_p (const_tree);
890 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
891 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
892 static bool rs6000_ms_bitfield_layout_p (const_tree);
893 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
894 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
895 static const char *rs6000_mangle_type (const_tree);
896 static void rs6000_set_default_type_attributes (tree);
897 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
898 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
899 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
900 enum machine_mode, bool, bool, bool);
901 static bool rs6000_reg_live_or_pic_offset_p (int);
902 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
903 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
904 static void rs6000_restore_saved_cr (rtx, int);
905 static bool rs6000_output_addr_const_extra (FILE *, rtx);
906 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
907 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
908 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
910 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
911 static bool rs6000_return_in_memory (const_tree, const_tree);
912 static rtx rs6000_function_value (const_tree, const_tree, bool);
913 static void rs6000_file_start (void);
915 static int rs6000_elf_reloc_rw_mask (void);
916 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
917 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
918 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
919 static void rs6000_elf_asm_init_sections (void);
920 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
921 unsigned HOST_WIDE_INT);
922 static void rs6000_elf_encode_section_info (tree, rtx, int)
925 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
926 static void rs6000_alloc_sdmode_stack_slot (void);
927 static void rs6000_instantiate_decls (void);
929 static void rs6000_xcoff_asm_output_anchor (rtx);
930 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
931 static void rs6000_xcoff_asm_init_sections (void);
932 static int rs6000_xcoff_reloc_rw_mask (void);
933 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
934 static section *rs6000_xcoff_select_section (tree, int,
935 unsigned HOST_WIDE_INT);
936 static void rs6000_xcoff_unique_section (tree, int);
937 static section *rs6000_xcoff_select_rtx_section
938 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
939 static const char * rs6000_xcoff_strip_name_encoding (const char *);
940 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
941 static void rs6000_xcoff_file_start (void);
942 static void rs6000_xcoff_file_end (void);
944 static int rs6000_variable_issue (FILE *, int, rtx, int);
945 static int rs6000_register_move_cost (enum machine_mode,
946 reg_class_t, reg_class_t);
947 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
948 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
949 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
950 static int rs6000_debug_address_cost (rtx, bool);
951 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
952 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
953 static void rs6000_sched_init (FILE *, int, int);
954 static bool is_microcoded_insn (rtx);
955 static bool is_nonpipeline_insn (rtx);
956 static bool is_cracked_insn (rtx);
957 static bool is_branch_slot_insn (rtx);
958 static bool is_load_insn (rtx);
959 static rtx get_store_dest (rtx pat);
960 static bool is_store_insn (rtx);
961 static bool set_to_load_agen (rtx,rtx);
962 static bool adjacent_mem_locations (rtx,rtx);
963 static int rs6000_adjust_priority (rtx, int);
964 static int rs6000_issue_rate (void);
965 static bool rs6000_is_costly_dependence (dep_t, int, int);
966 static rtx get_next_active_insn (rtx, rtx);
967 static bool insn_terminates_group_p (rtx , enum group_termination);
968 static bool insn_must_be_first_in_group (rtx);
969 static bool insn_must_be_last_in_group (rtx);
970 static bool is_costly_group (rtx *, rtx);
971 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
972 static int redefine_groups (FILE *, int, rtx, rtx);
973 static int pad_groups (FILE *, int, rtx, rtx);
974 static void rs6000_sched_finish (FILE *, int);
975 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
976 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
977 static int rs6000_use_sched_lookahead (void);
978 static int rs6000_use_sched_lookahead_guard (rtx);
979 static void * rs6000_alloc_sched_context (void);
980 static void rs6000_init_sched_context (void *, bool);
981 static void rs6000_set_sched_context (void *);
982 static void rs6000_free_sched_context (void *);
983 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
984 static tree rs6000_builtin_mask_for_load (void);
985 static tree rs6000_builtin_mul_widen_even (tree);
986 static tree rs6000_builtin_mul_widen_odd (tree);
987 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
988 static tree rs6000_builtin_vec_perm (tree, tree *);
989 static bool rs6000_builtin_support_vector_misalignment (enum
993 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
995 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
997 static void def_builtin (int, const char *, tree, int);
998 static bool rs6000_vector_alignment_reachable (const_tree, bool);
999 static void rs6000_init_builtins (void);
1000 static tree rs6000_builtin_decl (unsigned, bool);
1002 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1003 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1004 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1005 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1006 static void altivec_init_builtins (void);
1007 static unsigned builtin_hash_function (const void *);
1008 static int builtin_hash_eq (const void *, const void *);
1009 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1010 enum machine_mode, enum machine_mode,
1011 enum rs6000_builtins, const char *name);
1012 static void rs6000_common_init_builtins (void);
1013 static void rs6000_init_libfuncs (void);
1015 static void paired_init_builtins (void);
1016 static rtx paired_expand_builtin (tree, rtx, bool *);
1017 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1018 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1019 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1021 static void enable_mask_for_builtins (struct builtin_description *, int,
1022 enum rs6000_builtins,
1023 enum rs6000_builtins);
1024 static void spe_init_builtins (void);
1025 static rtx spe_expand_builtin (tree, rtx, bool *);
1026 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1027 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1028 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1029 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1030 static rs6000_stack_t *rs6000_stack_info (void);
1031 static void debug_stack_info (rs6000_stack_t *);
1033 static rtx altivec_expand_builtin (tree, rtx, bool *);
1034 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1035 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1036 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1037 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1038 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1039 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1040 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1041 static rtx altivec_expand_vec_set_builtin (tree);
1042 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1043 static int get_element_number (tree, tree);
1044 static void rs6000_option_override (void);
1045 static void rs6000_option_init_struct (struct gcc_options *);
1046 static void rs6000_option_default_params (void);
1047 static bool rs6000_handle_option (struct gcc_options *, struct gcc_options *,
1048 const struct cl_decoded_option *,
1050 static int rs6000_loop_align_max_skip (rtx);
1051 static int first_altivec_reg_to_save (void);
1052 static unsigned int compute_vrsave_mask (void);
1053 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1054 static void is_altivec_return_reg (rtx, void *);
1055 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1056 int easy_vector_constant (rtx, enum machine_mode);
1057 static rtx rs6000_dwarf_register_span (rtx);
1058 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1059 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1060 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1061 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1062 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1063 static rtx rs6000_delegitimize_address (rtx);
1064 static rtx rs6000_tls_get_addr (void);
1065 static rtx rs6000_got_sym (void);
1066 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1067 static const char *rs6000_get_some_local_dynamic_name (void);
1068 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1069 static rtx rs6000_complex_function_value (enum machine_mode);
1070 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1071 enum machine_mode, const_tree);
1072 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1073 HOST_WIDE_INT, int);
1074 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1077 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1080 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1081 const_tree, HOST_WIDE_INT,
1083 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1084 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1085 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1087 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1089 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1091 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1092 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1093 enum machine_mode, tree,
1095 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1097 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1099 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1101 static void macho_branch_islands (void);
1102 static int no_previous_def (tree function_name);
1103 static tree get_prev_label (tree function_name);
1104 static void rs6000_darwin_file_start (void);
1107 static tree rs6000_build_builtin_va_list (void);
1108 static void rs6000_va_start (tree, rtx);
1109 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1110 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1111 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1112 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1113 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1114 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1116 static tree rs6000_stack_protect_fail (void);
1118 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1121 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1124 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1126 = rs6000_legitimize_reload_address;
1128 static bool rs6000_mode_dependent_address_p (const_rtx);
1129 static bool rs6000_mode_dependent_address (const_rtx);
1130 static bool rs6000_debug_mode_dependent_address (const_rtx);
1131 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1132 = rs6000_mode_dependent_address;
1134 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1135 enum machine_mode, rtx);
1136 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1139 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1140 enum machine_mode, rtx)
1141 = rs6000_secondary_reload_class;
1143 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1144 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1146 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1147 = rs6000_preferred_reload_class;
1149 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1152 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1156 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1158 = rs6000_secondary_memory_needed;
1160 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1163 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1167 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1170 = rs6000_cannot_change_mode_class;
1172 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1174 struct secondary_reload_info *);
1176 const int INSN_NOT_AVAILABLE = -1;
1177 static enum machine_mode rs6000_eh_return_filter_mode (void);
1178 static bool rs6000_can_eliminate (const int, const int);
1179 static void rs6000_conditional_register_usage (void);
1180 static void rs6000_trampoline_init (rtx, tree, rtx);
1181 static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
1182 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
1184 /* Hash table stuff for keeping track of TOC entries. */
1186 struct GTY(()) toc_hash_struct
1188 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1189 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1191 enum machine_mode key_mode;
1195 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1197 /* Hash table to keep track of the argument types for builtin functions. */
1199 struct GTY(()) builtin_hash_struct
1202 enum machine_mode mode[4]; /* return value + 3 arguments. */
1203 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1206 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1208 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1209 static void rs6000_function_specific_save (struct cl_target_option *);
1210 static void rs6000_function_specific_restore (struct cl_target_option *);
1211 static void rs6000_function_specific_print (FILE *, int,
1212 struct cl_target_option *);
1213 static bool rs6000_can_inline_p (tree, tree);
1214 static void rs6000_set_current_function (tree);
1217 /* Default register names. */
1218 char rs6000_reg_names[][8] =
1220 "0", "1", "2", "3", "4", "5", "6", "7",
1221 "8", "9", "10", "11", "12", "13", "14", "15",
1222 "16", "17", "18", "19", "20", "21", "22", "23",
1223 "24", "25", "26", "27", "28", "29", "30", "31",
1224 "0", "1", "2", "3", "4", "5", "6", "7",
1225 "8", "9", "10", "11", "12", "13", "14", "15",
1226 "16", "17", "18", "19", "20", "21", "22", "23",
1227 "24", "25", "26", "27", "28", "29", "30", "31",
1228 "mq", "lr", "ctr","ap",
1229 "0", "1", "2", "3", "4", "5", "6", "7",
1231 /* AltiVec registers. */
1232 "0", "1", "2", "3", "4", "5", "6", "7",
1233 "8", "9", "10", "11", "12", "13", "14", "15",
1234 "16", "17", "18", "19", "20", "21", "22", "23",
1235 "24", "25", "26", "27", "28", "29", "30", "31",
1237 /* SPE registers. */
1238 "spe_acc", "spefscr",
1239 /* Soft frame pointer. */
1243 #ifdef TARGET_REGNAMES
1244 static const char alt_reg_names[][8] =
1246 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1247 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1248 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1249 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1250 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1251 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1252 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1253 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1254 "mq", "lr", "ctr", "ap",
1255 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1257 /* AltiVec registers. */
1258 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1259 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1260 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1261 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1263 /* SPE registers. */
1264 "spe_acc", "spefscr",
1265 /* Soft frame pointer. */
1270 /* Table of valid machine attributes. */
1272 static const struct attribute_spec rs6000_attribute_table[] =
1274 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1275 affects_type_identity } */
1276 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1278 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1280 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1282 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1284 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1286 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1287 SUBTARGET_ATTRIBUTE_TABLE,
1289 { NULL, 0, 0, false, false, false, NULL, false }
1292 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1293 static const struct default_options rs6000_option_optimization_table[] =
1295 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1296 { OPT_LEVELS_NONE, 0, NULL, 0 }
1299 #ifndef MASK_STRICT_ALIGN
1300 #define MASK_STRICT_ALIGN 0
1302 #ifndef TARGET_PROFILE_KERNEL
1303 #define TARGET_PROFILE_KERNEL 0
1306 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1307 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1309 /* Initialize the GCC target structure. */
1310 #undef TARGET_ATTRIBUTE_TABLE
1311 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1312 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1313 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1314 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1315 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1317 #undef TARGET_ASM_ALIGNED_DI_OP
1318 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1320 /* Default unaligned ops are only provided for ELF. Find the ops needed
1321 for non-ELF systems. */
1322 #ifndef OBJECT_FORMAT_ELF
1324 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1326 #undef TARGET_ASM_UNALIGNED_HI_OP
1327 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1328 #undef TARGET_ASM_UNALIGNED_SI_OP
1329 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1330 #undef TARGET_ASM_UNALIGNED_DI_OP
1331 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1334 #undef TARGET_ASM_UNALIGNED_HI_OP
1335 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1336 #undef TARGET_ASM_UNALIGNED_SI_OP
1337 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1338 #undef TARGET_ASM_UNALIGNED_DI_OP
1339 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1340 #undef TARGET_ASM_ALIGNED_DI_OP
1341 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1345 /* This hook deals with fixups for relocatable code and DI-mode objects
1347 #undef TARGET_ASM_INTEGER
1348 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1350 #ifdef HAVE_GAS_HIDDEN
1351 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1352 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1355 #undef TARGET_HAVE_TLS
1356 #define TARGET_HAVE_TLS HAVE_AS_TLS
1358 #undef TARGET_CANNOT_FORCE_CONST_MEM
1359 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1361 #undef TARGET_DELEGITIMIZE_ADDRESS
1362 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1364 #undef TARGET_ASM_FUNCTION_PROLOGUE
1365 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1366 #undef TARGET_ASM_FUNCTION_EPILOGUE
1367 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1369 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1370 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1372 #undef TARGET_LEGITIMIZE_ADDRESS
1373 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1375 #undef TARGET_SCHED_VARIABLE_ISSUE
1376 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1378 #undef TARGET_SCHED_ISSUE_RATE
1379 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1380 #undef TARGET_SCHED_ADJUST_COST
1381 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1382 #undef TARGET_SCHED_ADJUST_PRIORITY
1383 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1384 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1385 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1386 #undef TARGET_SCHED_INIT
1387 #define TARGET_SCHED_INIT rs6000_sched_init
1388 #undef TARGET_SCHED_FINISH
1389 #define TARGET_SCHED_FINISH rs6000_sched_finish
1390 #undef TARGET_SCHED_REORDER
1391 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1392 #undef TARGET_SCHED_REORDER2
1393 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1395 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1396 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1398 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1399 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1401 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1402 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1403 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1404 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1405 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1406 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1407 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1408 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1410 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1411 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1412 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1413 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1414 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1415 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1416 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1417 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1418 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1419 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1420 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1421 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1422 rs6000_builtin_support_vector_misalignment
1423 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1424 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1425 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1426 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1427 rs6000_builtin_vectorization_cost
1428 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1429 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1430 rs6000_preferred_simd_mode
1432 #undef TARGET_INIT_BUILTINS
1433 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1434 #undef TARGET_BUILTIN_DECL
1435 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1437 #undef TARGET_EXPAND_BUILTIN
1438 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1440 #undef TARGET_MANGLE_TYPE
1441 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1443 #undef TARGET_INIT_LIBFUNCS
1444 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1447 #undef TARGET_BINDS_LOCAL_P
1448 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1451 #undef TARGET_MS_BITFIELD_LAYOUT_P
1452 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1454 #undef TARGET_ASM_OUTPUT_MI_THUNK
1455 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1457 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1458 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1460 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1461 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1463 #undef TARGET_INVALID_WITHIN_DOLOOP
1464 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1466 #undef TARGET_REGISTER_MOVE_COST
1467 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1468 #undef TARGET_MEMORY_MOVE_COST
1469 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1470 #undef TARGET_RTX_COSTS
1471 #define TARGET_RTX_COSTS rs6000_rtx_costs
1472 #undef TARGET_ADDRESS_COST
1473 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1475 #undef TARGET_DWARF_REGISTER_SPAN
1476 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1478 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1479 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1481 /* On rs6000, function arguments are promoted, as are function return
1483 #undef TARGET_PROMOTE_FUNCTION_MODE
1484 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1486 #undef TARGET_RETURN_IN_MEMORY
1487 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1489 #undef TARGET_SETUP_INCOMING_VARARGS
1490 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1492 /* Always strict argument naming on rs6000. */
1493 #undef TARGET_STRICT_ARGUMENT_NAMING
1494 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1495 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1496 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1497 #undef TARGET_SPLIT_COMPLEX_ARG
1498 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1499 #undef TARGET_MUST_PASS_IN_STACK
1500 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1501 #undef TARGET_PASS_BY_REFERENCE
1502 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1503 #undef TARGET_ARG_PARTIAL_BYTES
1504 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1505 #undef TARGET_FUNCTION_ARG_ADVANCE
1506 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1507 #undef TARGET_FUNCTION_ARG
1508 #define TARGET_FUNCTION_ARG rs6000_function_arg
1509 #undef TARGET_FUNCTION_ARG_BOUNDARY
1510 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1512 #undef TARGET_BUILD_BUILTIN_VA_LIST
1513 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1515 #undef TARGET_EXPAND_BUILTIN_VA_START
1516 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1518 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1519 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1521 #undef TARGET_EH_RETURN_FILTER_MODE
1522 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1524 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1525 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1527 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1528 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1530 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1531 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1533 #undef TARGET_HANDLE_OPTION
1534 #define TARGET_HANDLE_OPTION rs6000_handle_option
1536 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1537 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1539 #undef TARGET_OPTION_OVERRIDE
1540 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1542 #undef TARGET_OPTION_INIT_STRUCT
1543 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1545 #undef TARGET_OPTION_DEFAULT_PARAMS
1546 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1548 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1549 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1551 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1552 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1553 rs6000_builtin_vectorized_function
1555 #undef TARGET_DEFAULT_TARGET_FLAGS
1556 #define TARGET_DEFAULT_TARGET_FLAGS \
1559 #undef TARGET_STACK_PROTECT_FAIL
1560 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1562 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1563 The PowerPC architecture requires only weak consistency among
1564 processors--that is, memory accesses between processors need not be
1565 sequentially consistent and memory accesses among processors can occur
1566 in any order. The ability to order memory accesses weakly provides
1567 opportunities for more efficient use of the system bus. Unless a
1568 dependency exists, the 604e allows read operations to precede store
1570 #undef TARGET_RELAXED_ORDERING
1571 #define TARGET_RELAXED_ORDERING true
1574 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1575 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1578 /* Use a 32-bit anchor range. This leads to sequences like:
1580 addis tmp,anchor,high
1583 where tmp itself acts as an anchor, and can be shared between
1584 accesses to the same 64k page. */
1585 #undef TARGET_MIN_ANCHOR_OFFSET
1586 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1587 #undef TARGET_MAX_ANCHOR_OFFSET
1588 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1589 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1590 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1592 #undef TARGET_BUILTIN_RECIPROCAL
1593 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1595 #undef TARGET_EXPAND_TO_RTL_HOOK
1596 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1598 #undef TARGET_INSTANTIATE_DECLS
1599 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1601 #undef TARGET_SECONDARY_RELOAD
1602 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1604 #undef TARGET_LEGITIMATE_ADDRESS_P
1605 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1607 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1608 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1610 #undef TARGET_CAN_ELIMINATE
1611 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1613 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1614 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1616 #undef TARGET_TRAMPOLINE_INIT
1617 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1619 #undef TARGET_FUNCTION_VALUE
1620 #define TARGET_FUNCTION_VALUE rs6000_function_value
1622 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1623 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1625 #undef TARGET_OPTION_SAVE
1626 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1628 #undef TARGET_OPTION_RESTORE
1629 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1631 #undef TARGET_OPTION_PRINT
1632 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1634 #undef TARGET_CAN_INLINE_P
1635 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1637 #undef TARGET_SET_CURRENT_FUNCTION
1638 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1640 #undef TARGET_LEGITIMATE_CONSTANT_P
1641 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1643 struct gcc_target targetm = TARGET_INITIALIZER;
1646 /* Simplifications for entries below. */
1649 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1650 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1653 /* Some OSs don't support saving the high part of 64-bit registers on context
1654 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1655 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1656 either, the user must explicitly specify them and we won't interfere with
1657 the user's specification. */
1660 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1661 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1662 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1663 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1664 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1665 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1666 | MASK_RECIP_PRECISION)
1669 /* Masks for instructions set at various powerpc ISAs. */
1671 ISA_2_1_MASKS = MASK_MFCRF,
1672 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1673 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1675 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1676 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1677 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1678 server and embedded. */
1679 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1680 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1681 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1683 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1684 altivec is a win so enable it. */
1685 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1686 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1692 const char *const name; /* Canonical processor name. */
1693 const enum processor_type processor; /* Processor type enum value. */
1694 const int target_enable; /* Target flags to enable. */
1697 static struct rs6000_ptt const processor_target_table[] =
1699 #define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
1700 #include "rs6000-cpus.def"
1704 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1708 rs6000_cpu_name_lookup (const char *name)
1714 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1715 if (! strcmp (name, processor_target_table[i].name))
1723 /* Return number of consecutive hard regs needed starting at reg REGNO
1724 to hold something of mode MODE.
1725 This is ordinarily the length in words of a value of mode MODE
1726 but can be less for certain modes in special long registers.
1728 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1729 scalar instructions. The upper 32 bits are only available to the
1732 POWER and PowerPC GPRs hold 32 bits worth;
1733 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1736 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1738 unsigned HOST_WIDE_INT reg_size;
1740 if (FP_REGNO_P (regno))
1741 reg_size = (VECTOR_MEM_VSX_P (mode)
1742 ? UNITS_PER_VSX_WORD
1743 : UNITS_PER_FP_WORD);
1745 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1746 reg_size = UNITS_PER_SPE_WORD;
1748 else if (ALTIVEC_REGNO_P (regno))
1749 reg_size = UNITS_PER_ALTIVEC_WORD;
1751 /* The value returned for SCmode in the E500 double case is 2 for
1752 ABI compatibility; storing an SCmode value in a single register
1753 would require function_arg and rs6000_spe_function_arg to handle
1754 SCmode so as to pass the value correctly in a pair of
1756 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1757 && !DECIMAL_FLOAT_MODE_P (mode))
1758 reg_size = UNITS_PER_FP_WORD;
1761 reg_size = UNITS_PER_WORD;
1763 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1766 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1769 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1771 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1773 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1774 implementations. Don't allow an item to be split between a FP register
1775 and an Altivec register. */
1776 if (VECTOR_MEM_VSX_P (mode))
1778 if (FP_REGNO_P (regno))
1779 return FP_REGNO_P (last_regno);
1781 if (ALTIVEC_REGNO_P (regno))
1782 return ALTIVEC_REGNO_P (last_regno);
1785 /* The GPRs can hold any mode, but values bigger than one register
1786 cannot go past R31. */
1787 if (INT_REGNO_P (regno))
1788 return INT_REGNO_P (last_regno);
1790 /* The float registers (except for VSX vector modes) can only hold floating
1791 modes and DImode. This excludes the 32-bit decimal float mode for
1793 if (FP_REGNO_P (regno))
1795 if (SCALAR_FLOAT_MODE_P (mode)
1796 && (mode != TDmode || (regno % 2) == 0)
1797 && FP_REGNO_P (last_regno))
1800 if (GET_MODE_CLASS (mode) == MODE_INT
1801 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1804 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1805 && PAIRED_VECTOR_MODE (mode))
1811 /* The CR register can only hold CC modes. */
1812 if (CR_REGNO_P (regno))
1813 return GET_MODE_CLASS (mode) == MODE_CC;
1815 if (CA_REGNO_P (regno))
1816 return mode == BImode;
1818 /* AltiVec only in AldyVec registers. */
1819 if (ALTIVEC_REGNO_P (regno))
1820 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1822 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1823 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1826 /* We cannot put TImode anywhere except general register and it must be able
1827 to fit within the register set. In the future, allow TImode in the
1828 Altivec or VSX registers. */
1830 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1833 /* Print interesting facts about registers. */
1835 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1839 for (r = first_regno; r <= last_regno; ++r)
1841 const char *comma = "";
1844 if (first_regno == last_regno)
1845 fprintf (stderr, "%s:\t", reg_name);
1847 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1850 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1851 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1855 fprintf (stderr, ",\n\t");
1860 if (rs6000_hard_regno_nregs[m][r] > 1)
1861 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1862 rs6000_hard_regno_nregs[m][r]);
1864 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1869 if (call_used_regs[r])
1873 fprintf (stderr, ",\n\t");
1878 len += fprintf (stderr, "%s%s", comma, "call-used");
1886 fprintf (stderr, ",\n\t");
1891 len += fprintf (stderr, "%s%s", comma, "fixed");
1897 fprintf (stderr, ",\n\t");
1901 fprintf (stderr, "%sregno = %d\n", comma, r);
1905 #define DEBUG_FMT_D "%-32s= %d\n"
1906 #define DEBUG_FMT_S "%-32s= %s\n"
1908 /* Print various interesting information with -mdebug=reg. */
1910 rs6000_debug_reg_global (void)
1912 static const char *const tf[2] = { "false", "true" };
1913 const char *nl = (const char *)0;
1915 char costly_num[20];
1917 const char *costly_str;
1918 const char *nop_str;
1919 const char *trace_str;
1920 const char *abi_str;
1921 const char *cmodel_str;
1923 /* Map enum rs6000_vector to string. */
1924 static const char *rs6000_debug_vector_unit[] = {
1933 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1934 LAST_VIRTUAL_REGISTER);
1935 rs6000_debug_reg_print (0, 31, "gr");
1936 rs6000_debug_reg_print (32, 63, "fp");
1937 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1940 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1941 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1942 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1943 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1944 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1945 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1946 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1947 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1948 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1952 "d reg_class = %s\n"
1953 "f reg_class = %s\n"
1954 "v reg_class = %s\n"
1955 "wa reg_class = %s\n"
1956 "wd reg_class = %s\n"
1957 "wf reg_class = %s\n"
1958 "ws reg_class = %s\n\n",
1959 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1960 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1961 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1962 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1963 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1964 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1965 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1967 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1968 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1971 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1973 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1974 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1980 if (rs6000_recip_control)
1982 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1984 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1985 if (rs6000_recip_bits[m])
1988 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1990 (RS6000_RECIP_AUTO_RE_P (m)
1992 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1993 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1995 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1998 fputs ("\n", stderr);
2001 if (rs6000_cpu_index >= 0)
2002 fprintf (stderr, DEBUG_FMT_S, "cpu",
2003 processor_target_table[rs6000_cpu_index].name);
2005 if (rs6000_tune_index >= 0)
2006 fprintf (stderr, DEBUG_FMT_S, "tune",
2007 processor_target_table[rs6000_tune_index].name);
2009 switch (rs6000_sched_costly_dep)
2011 case max_dep_latency:
2012 costly_str = "max_dep_latency";
2016 costly_str = "no_dep_costly";
2019 case all_deps_costly:
2020 costly_str = "all_deps_costly";
2023 case true_store_to_load_dep_costly:
2024 costly_str = "true_store_to_load_dep_costly";
2027 case store_to_load_dep_costly:
2028 costly_str = "store_to_load_dep_costly";
2032 costly_str = costly_num;
2033 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2037 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2039 switch (rs6000_sched_insert_nops)
2041 case sched_finish_regroup_exact:
2042 nop_str = "sched_finish_regroup_exact";
2045 case sched_finish_pad_groups:
2046 nop_str = "sched_finish_pad_groups";
2049 case sched_finish_none:
2050 nop_str = "sched_finish_none";
2055 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2059 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2061 switch (rs6000_sdata)
2068 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2072 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2076 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2081 switch (rs6000_traceback)
2083 case traceback_default: trace_str = "default"; break;
2084 case traceback_none: trace_str = "none"; break;
2085 case traceback_part: trace_str = "part"; break;
2086 case traceback_full: trace_str = "full"; break;
2087 default: trace_str = "unknown"; break;
2090 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2092 switch (rs6000_current_cmodel)
2094 case CMODEL_SMALL: cmodel_str = "small"; break;
2095 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2096 case CMODEL_LARGE: cmodel_str = "large"; break;
2097 default: cmodel_str = "unknown"; break;
2100 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2102 switch (rs6000_current_abi)
2104 case ABI_NONE: abi_str = "none"; break;
2105 case ABI_AIX: abi_str = "aix"; break;
2106 case ABI_V4: abi_str = "V4"; break;
2107 case ABI_DARWIN: abi_str = "darwin"; break;
2108 default: abi_str = "unknown"; break;
2111 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2113 if (rs6000_altivec_abi)
2114 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2117 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2119 if (rs6000_darwin64_abi)
2120 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2122 if (rs6000_float_gprs)
2123 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2125 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2126 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2127 tf[!!rs6000_align_branch_targets]);
2128 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2129 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2130 rs6000_long_double_type_size);
2131 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2132 (int)rs6000_sched_restricted_insns_priority);
2135 /* Initialize the various global tables that are based on register size. */
2137 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2143 /* Precalculate REGNO_REG_CLASS. */
2144 rs6000_regno_regclass[0] = GENERAL_REGS;
2145 for (r = 1; r < 32; ++r)
2146 rs6000_regno_regclass[r] = BASE_REGS;
2148 for (r = 32; r < 64; ++r)
2149 rs6000_regno_regclass[r] = FLOAT_REGS;
2151 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2152 rs6000_regno_regclass[r] = NO_REGS;
2154 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2155 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2157 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2158 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2159 rs6000_regno_regclass[r] = CR_REGS;
2161 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2162 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2163 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2164 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2165 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2166 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2167 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2168 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2169 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2170 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2172 /* Precalculate vector information, this must be set up before the
2173 rs6000_hard_regno_nregs_internal below. */
2174 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2176 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2177 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2178 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2181 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2182 rs6000_constraints[c] = NO_REGS;
2184 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2185 believes it can use native alignment or still uses 128-bit alignment. */
2186 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2197 /* V2DF mode, VSX only. */
2200 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2201 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2202 rs6000_vector_align[V2DFmode] = align64;
2205 /* V4SF mode, either VSX or Altivec. */
2208 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2209 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2210 rs6000_vector_align[V4SFmode] = align32;
2212 else if (TARGET_ALTIVEC)
2214 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2215 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2216 rs6000_vector_align[V4SFmode] = align32;
2219 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2223 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2224 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2225 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2226 rs6000_vector_align[V4SImode] = align32;
2227 rs6000_vector_align[V8HImode] = align32;
2228 rs6000_vector_align[V16QImode] = align32;
2232 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2233 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2234 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2238 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2239 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2240 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2244 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2245 Altivec doesn't have 64-bit support. */
2248 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2249 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2250 rs6000_vector_align[V2DImode] = align64;
2253 /* DFmode, see if we want to use the VSX unit. */
2254 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2256 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2257 rs6000_vector_mem[DFmode]
2258 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2259 rs6000_vector_align[DFmode] = align64;
2262 /* TODO add SPE and paired floating point vector support. */
2264 /* Register class constaints for the constraints that depend on compile
2266 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2267 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2269 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2270 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2274 /* At present, we just use VSX_REGS, but we have different constraints
2275 based on the use, in case we want to fine tune the default register
2276 class used. wa = any VSX register, wf = register class to use for
2277 V4SF, wd = register class to use for V2DF, and ws = register classs to
2278 use for DF scalars. */
2279 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2280 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2281 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2282 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2288 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2290 /* Set up the reload helper functions. */
2291 if (TARGET_VSX || TARGET_ALTIVEC)
2295 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2296 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2297 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2298 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2299 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2300 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2301 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2302 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2303 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2304 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2305 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2306 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2310 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2311 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2312 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2313 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2314 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2315 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2316 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2317 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2318 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2319 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2320 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2321 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2325 /* Precalculate HARD_REGNO_NREGS. */
2326 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2327 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2328 rs6000_hard_regno_nregs[m][r]
2329 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2331 /* Precalculate HARD_REGNO_MODE_OK. */
2332 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2333 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2334 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2335 rs6000_hard_regno_mode_ok_p[m][r] = true;
2337 /* Precalculate CLASS_MAX_NREGS sizes. */
2338 for (c = 0; c < LIM_REG_CLASSES; ++c)
2342 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2343 reg_size = UNITS_PER_VSX_WORD;
2345 else if (c == ALTIVEC_REGS)
2346 reg_size = UNITS_PER_ALTIVEC_WORD;
2348 else if (c == FLOAT_REGS)
2349 reg_size = UNITS_PER_FP_WORD;
2352 reg_size = UNITS_PER_WORD;
2354 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2355 rs6000_class_max_nregs[m][c]
2356 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2359 if (TARGET_E500_DOUBLE)
2360 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2362 /* Calculate which modes to automatically generate code to use a the
2363 reciprocal divide and square root instructions. In the future, possibly
2364 automatically generate the instructions even if the user did not specify
2365 -mrecip. The older machines double precision reciprocal sqrt estimate is
2366 not accurate enough. */
2367 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2369 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2371 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2372 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2373 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2374 if (VECTOR_UNIT_VSX_P (V2DFmode))
2375 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2377 if (TARGET_FRSQRTES)
2378 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2380 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2381 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2382 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2383 if (VECTOR_UNIT_VSX_P (V2DFmode))
2384 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2386 if (rs6000_recip_control)
2388 if (!flag_finite_math_only)
2389 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2390 if (flag_trapping_math)
2391 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2392 if (!flag_reciprocal_math)
2393 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2394 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2396 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2397 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2398 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2400 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2401 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2402 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2404 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2405 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2406 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2408 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2409 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2410 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2412 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2413 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2414 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2416 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2417 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2418 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2420 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2421 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2422 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2424 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2425 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2426 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2430 if (global_init_p || TARGET_DEBUG_TARGET)
2432 if (TARGET_DEBUG_REG)
2433 rs6000_debug_reg_global ();
2435 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2437 "SImode variable mult cost = %d\n"
2438 "SImode constant mult cost = %d\n"
2439 "SImode short constant mult cost = %d\n"
2440 "DImode multipliciation cost = %d\n"
2441 "SImode division cost = %d\n"
2442 "DImode division cost = %d\n"
2443 "Simple fp operation cost = %d\n"
2444 "DFmode multiplication cost = %d\n"
2445 "SFmode division cost = %d\n"
2446 "DFmode division cost = %d\n"
2447 "cache line size = %d\n"
2448 "l1 cache size = %d\n"
2449 "l2 cache size = %d\n"
2450 "simultaneous prefetches = %d\n"
2453 rs6000_cost->mulsi_const,
2454 rs6000_cost->mulsi_const9,
2462 rs6000_cost->cache_line_size,
2463 rs6000_cost->l1_cache_size,
2464 rs6000_cost->l2_cache_size,
2465 rs6000_cost->simultaneous_prefetches);
2470 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2473 darwin_rs6000_override_options (void)
2475 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2477 rs6000_altivec_abi = 1;
2478 TARGET_ALTIVEC_VRSAVE = 1;
2480 if (DEFAULT_ABI == ABI_DARWIN
2482 darwin_one_byte_bool = 1;
2484 if (TARGET_64BIT && ! TARGET_POWERPC64)
2486 target_flags |= MASK_POWERPC64;
2487 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2491 rs6000_default_long_calls = 1;
2492 target_flags |= MASK_SOFT_FLOAT;
2495 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2497 if (!flag_mkernel && !flag_apple_kext
2499 && ! (target_flags_explicit & MASK_ALTIVEC))
2500 target_flags |= MASK_ALTIVEC;
2502 /* Unless the user (not the configurer) has explicitly overridden
2503 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2504 G4 unless targetting the kernel. */
2507 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2508 && ! (target_flags_explicit & MASK_ALTIVEC)
2509 && ! global_options_set.x_rs6000_cpu_index)
2511 target_flags |= MASK_ALTIVEC;
2516 /* If not otherwise specified by a target, make 'long double' equivalent to
2519 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2520 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2523 /* Override command line options. Mostly we process the processor type and
2524 sometimes adjust other TARGET_ options. */
2527 rs6000_option_override_internal (bool global_init_p)
2530 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2534 struct cl_target_option *main_target_opt
2535 = ((global_init_p || target_option_default_node == NULL)
2536 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2538 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2539 library functions, so warn about it. The flag may be useful for
2540 performance studies from time to time though, so don't disable it
2542 if (global_options_set.x_rs6000_alignment_flags
2543 && rs6000_alignment_flags == MASK_ALIGN_POWER
2544 && DEFAULT_ABI == ABI_DARWIN
2546 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2547 " it is incompatible with the installed C and C++ libraries");
2549 if (global_options_set.x_rs6000_spe_abi
2552 error ("not configured for SPE ABI");
2554 /* Numerous experiment shows that IRA based loop pressure
2555 calculation works better for RTL loop invariant motion on targets
2556 with enough (>= 32) registers. It is an expensive optimization.
2557 So it is on only for peak performance. */
2558 if (optimize >= 3 && global_init_p)
2559 flag_ira_loop_pressure = 1;
2561 /* Set the pointer size. */
2564 rs6000_pmode = (int)DImode;
2565 rs6000_pointer_size = 64;
2569 rs6000_pmode = (int)SImode;
2570 rs6000_pointer_size = 32;
2573 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2574 #ifdef OS_MISSING_POWERPC64
2575 if (OS_MISSING_POWERPC64)
2576 set_masks &= ~MASK_POWERPC64;
2578 #ifdef OS_MISSING_ALTIVEC
2579 if (OS_MISSING_ALTIVEC)
2580 set_masks &= ~MASK_ALTIVEC;
2583 /* Don't override by the processor default if given explicitly. */
2584 set_masks &= ~target_flags_explicit;
2586 /* Identify the processor type. */
2589 if (TARGET_POWERPC64)
2590 default_cpu = "powerpc64";
2591 else if (TARGET_POWERPC)
2592 default_cpu = "powerpc";
2595 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2596 the cpu in a target attribute or pragma, but did not specify a tuning
2597 option, use the cpu for the tuning option rather than the option specified
2598 with -mtune on the command line. */
2599 if (rs6000_cpu_index > 0)
2600 cpu_index = rs6000_cpu_index;
2601 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2602 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2604 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2606 if (rs6000_tune_index > 0)
2607 tune_index = rs6000_tune_index;
2609 rs6000_tune_index = tune_index = cpu_index;
2613 target_flags &= ~set_masks;
2614 target_flags |= (processor_target_table[cpu_index].target_enable
2618 rs6000_cpu = ((tune_index >= 0)
2619 ? processor_target_table[tune_index].processor
2621 ? PROCESSOR_DEFAULT64
2622 : PROCESSOR_DEFAULT));
2624 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2625 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2628 error ("AltiVec not supported in this target");
2630 error ("SPE not supported in this target");
2633 /* Disable Cell microcode if we are optimizing for the Cell
2634 and not optimizing for size. */
2635 if (rs6000_gen_cell_microcode == -1)
2636 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2639 /* If we are optimizing big endian systems for space and it's OK to
2640 use instructions that would be microcoded on the Cell, use the
2641 load/store multiple and string instructions. */
2642 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2643 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2645 /* Don't allow -mmultiple or -mstring on little endian systems
2646 unless the cpu is a 750, because the hardware doesn't support the
2647 instructions used in little endian mode, and causes an alignment
2648 trap. The 750 does not cause an alignment trap (except when the
2649 target is unaligned). */
2651 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2653 if (TARGET_MULTIPLE)
2655 target_flags &= ~MASK_MULTIPLE;
2656 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2657 warning (0, "-mmultiple is not supported on little endian systems");
2662 target_flags &= ~MASK_STRING;
2663 if ((target_flags_explicit & MASK_STRING) != 0)
2664 warning (0, "-mstring is not supported on little endian systems");
2668 /* Add some warnings for VSX. */
2671 const char *msg = NULL;
2672 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2673 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2675 if (target_flags_explicit & MASK_VSX)
2676 msg = N_("-mvsx requires hardware floating point");
2678 target_flags &= ~ MASK_VSX;
2680 else if (TARGET_PAIRED_FLOAT)
2681 msg = N_("-mvsx and -mpaired are incompatible");
2682 /* The hardware will allow VSX and little endian, but until we make sure
2683 things like vector select, etc. work don't allow VSX on little endian
2684 systems at this point. */
2685 else if (!BYTES_BIG_ENDIAN)
2686 msg = N_("-mvsx used with little endian code");
2687 else if (TARGET_AVOID_XFORM > 0)
2688 msg = N_("-mvsx needs indexed addressing");
2689 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2691 if (target_flags_explicit & MASK_VSX)
2692 msg = N_("-mvsx and -mno-altivec are incompatible");
2694 msg = N_("-mno-altivec disables vsx");
2700 target_flags &= ~ MASK_VSX;
2701 target_flags_explicit |= MASK_VSX;
2705 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2706 unless the user explicitly used the -mno-<option> to disable the code. */
2708 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2709 else if (TARGET_POPCNTD)
2710 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2711 else if (TARGET_DFP)
2712 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2713 else if (TARGET_CMPB)
2714 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2715 else if (TARGET_FPRND)
2716 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2717 else if (TARGET_POPCNTB)
2718 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2719 else if (TARGET_ALTIVEC)
2720 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2722 /* E500mc does "better" if we inline more aggressively. Respect the
2723 user's opinion, though. */
2724 if (rs6000_block_move_inline_limit == 0
2725 && (rs6000_cpu == PROCESSOR_PPCE500MC
2726 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2727 rs6000_block_move_inline_limit = 128;
2729 /* store_one_arg depends on expand_block_move to handle at least the
2730 size of reg_parm_stack_space. */
2731 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2732 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2736 /* If the appropriate debug option is enabled, replace the target hooks
2737 with debug versions that call the real version and then prints
2738 debugging information. */
2739 if (TARGET_DEBUG_COST)
2741 targetm.rtx_costs = rs6000_debug_rtx_costs;
2742 targetm.address_cost = rs6000_debug_address_cost;
2743 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2746 if (TARGET_DEBUG_ADDR)
2748 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2749 targetm.legitimize_address = rs6000_debug_legitimize_address;
2750 rs6000_secondary_reload_class_ptr
2751 = rs6000_debug_secondary_reload_class;
2752 rs6000_secondary_memory_needed_ptr
2753 = rs6000_debug_secondary_memory_needed;
2754 rs6000_cannot_change_mode_class_ptr
2755 = rs6000_debug_cannot_change_mode_class;
2756 rs6000_preferred_reload_class_ptr
2757 = rs6000_debug_preferred_reload_class;
2758 rs6000_legitimize_reload_address_ptr
2759 = rs6000_debug_legitimize_reload_address;
2760 rs6000_mode_dependent_address_ptr
2761 = rs6000_debug_mode_dependent_address;
2764 if (rs6000_veclibabi_name)
2766 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2767 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2770 error ("unknown vectorization library ABI type (%s) for "
2771 "-mveclibabi= switch", rs6000_veclibabi_name);
2777 if (!global_options_set.x_rs6000_long_double_type_size)
2779 if (main_target_opt != NULL
2780 && (main_target_opt->x_rs6000_long_double_type_size
2781 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2782 error ("target attribute or pragma changes long double size");
2784 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2787 #ifndef POWERPC_LINUX
2788 if (!global_options_set.x_rs6000_ieeequad)
2789 rs6000_ieeequad = 1;
2792 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2793 target attribute or pragma which automatically enables both options,
2794 unless the altivec ABI was set. This is set by default for 64-bit, but
2796 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2797 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2799 /* Enable Altivec ABI for AIX -maltivec. */
2800 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2802 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2803 error ("target attribute or pragma changes AltiVec ABI");
2805 rs6000_altivec_abi = 1;
2808 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2809 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2810 be explicitly overridden in either case. */
2813 if (!global_options_set.x_rs6000_altivec_abi
2814 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2816 if (main_target_opt != NULL &&
2817 !main_target_opt->x_rs6000_altivec_abi)
2818 error ("target attribute or pragma changes AltiVec ABI");
2820 rs6000_altivec_abi = 1;
2823 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2824 if (!global_options_set.x_TARGET_ALTIVEC_VRSAVE)
2825 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2828 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2829 So far, the only darwin64 targets are also MACH-O. */
2831 && DEFAULT_ABI == ABI_DARWIN
2834 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2835 error ("target attribute or pragma changes darwin64 ABI");
2838 rs6000_darwin64_abi = 1;
2839 /* Default to natural alignment, for better performance. */
2840 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2844 /* Place FP constants in the constant pool instead of TOC
2845 if section anchors enabled. */
2846 if (flag_section_anchors)
2847 TARGET_NO_FP_IN_TOC = 1;
2849 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2850 SUBTARGET_OVERRIDE_OPTIONS;
2852 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2853 SUBSUBTARGET_OVERRIDE_OPTIONS;
2855 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2856 SUB3TARGET_OVERRIDE_OPTIONS;
2859 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2860 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2862 /* The e500 and e500mc do not have string instructions, and we set
2863 MASK_STRING above when optimizing for size. */
2864 if ((target_flags & MASK_STRING) != 0)
2865 target_flags = target_flags & ~MASK_STRING;
2867 else if (global_options_set.x_rs6000_cpu_index)
2869 /* For the powerpc-eabispe configuration, we set all these by
2870 default, so let's unset them if we manually set another
2871 CPU that is not the E500. */
2872 if (main_target_opt != NULL
2873 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2874 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2875 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2876 error ("target attribute or pragma changes SPE ABI");
2879 if (!global_options_set.x_rs6000_spe_abi)
2881 if (!global_options_set.x_rs6000_spe)
2883 if (!global_options_set.x_rs6000_float_gprs)
2884 rs6000_float_gprs = 0;
2886 if (!(target_flags_explicit & MASK_ISEL))
2887 target_flags &= ~MASK_ISEL;
2890 /* Detect invalid option combinations with E500. */
2893 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2894 && rs6000_cpu != PROCESSOR_POWER5
2895 && rs6000_cpu != PROCESSOR_POWER6
2896 && rs6000_cpu != PROCESSOR_POWER7
2897 && rs6000_cpu != PROCESSOR_PPCA2
2898 && rs6000_cpu != PROCESSOR_CELL);
2899 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2900 || rs6000_cpu == PROCESSOR_POWER5
2901 || rs6000_cpu == PROCESSOR_POWER7);
2902 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2903 || rs6000_cpu == PROCESSOR_POWER5
2904 || rs6000_cpu == PROCESSOR_POWER6
2905 || rs6000_cpu == PROCESSOR_POWER7
2906 || rs6000_cpu == PROCESSOR_PPCE500MC
2907 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2909 /* Allow debug switches to override the above settings. These are set to -1
2910 in rs6000.opt to indicate the user hasn't directly set the switch. */
2911 if (TARGET_ALWAYS_HINT >= 0)
2912 rs6000_always_hint = TARGET_ALWAYS_HINT;
2914 if (TARGET_SCHED_GROUPS >= 0)
2915 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2917 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
2918 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2920 rs6000_sched_restricted_insns_priority
2921 = (rs6000_sched_groups ? 1 : 0);
2923 /* Handle -msched-costly-dep option. */
2924 rs6000_sched_costly_dep
2925 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2927 if (rs6000_sched_costly_dep_str)
2929 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2930 rs6000_sched_costly_dep = no_dep_costly;
2931 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2932 rs6000_sched_costly_dep = all_deps_costly;
2933 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2934 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2935 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2936 rs6000_sched_costly_dep = store_to_load_dep_costly;
2938 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2939 atoi (rs6000_sched_costly_dep_str));
2942 /* Handle -minsert-sched-nops option. */
2943 rs6000_sched_insert_nops
2944 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2946 if (rs6000_sched_insert_nops_str)
2948 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2949 rs6000_sched_insert_nops = sched_finish_none;
2950 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2951 rs6000_sched_insert_nops = sched_finish_pad_groups;
2952 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2953 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2955 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2956 atoi (rs6000_sched_insert_nops_str));
2961 #ifdef TARGET_REGNAMES
2962 /* If the user desires alternate register names, copy in the
2963 alternate names now. */
2964 if (TARGET_REGNAMES)
2965 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2968 /* Set aix_struct_return last, after the ABI is determined.
2969 If -maix-struct-return or -msvr4-struct-return was explicitly
2970 used, don't override with the ABI default. */
2971 if (!global_options_set.x_aix_struct_return)
2972 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2975 /* IBM XL compiler defaults to unsigned bitfields. */
2976 if (TARGET_XL_COMPAT)
2977 flag_signed_bitfields = 0;
2980 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2981 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2984 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2986 /* We can only guarantee the availability of DI pseudo-ops when
2987 assembling for 64-bit targets. */
2990 targetm.asm_out.aligned_op.di = NULL;
2991 targetm.asm_out.unaligned_op.di = NULL;
2995 /* Set branch target alignment, if not optimizing for size. */
2998 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2999 aligned 8byte to avoid misprediction by the branch predictor. */
3000 if (rs6000_cpu == PROCESSOR_TITAN
3001 || rs6000_cpu == PROCESSOR_CELL)
3003 if (align_functions <= 0)
3004 align_functions = 8;
3005 if (align_jumps <= 0)
3007 if (align_loops <= 0)
3010 if (rs6000_align_branch_targets)
3012 if (align_functions <= 0)
3013 align_functions = 16;
3014 if (align_jumps <= 0)
3016 if (align_loops <= 0)
3018 can_override_loop_align = 1;
3022 if (align_jumps_max_skip <= 0)
3023 align_jumps_max_skip = 15;
3024 if (align_loops_max_skip <= 0)
3025 align_loops_max_skip = 15;
3028 /* Arrange to save and restore machine status around nested functions. */
3029 init_machine_status = rs6000_init_machine_status;
3031 /* We should always be splitting complex arguments, but we can't break
3032 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3033 if (DEFAULT_ABI != ABI_AIX)
3034 targetm.calls.split_complex_arg = NULL;
3037 /* Initialize rs6000_cost with the appropriate target costs. */
3039 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3043 case PROCESSOR_RIOS1:
3044 rs6000_cost = &rios1_cost;
3047 case PROCESSOR_RIOS2:
3048 rs6000_cost = &rios2_cost;
3051 case PROCESSOR_RS64A:
3052 rs6000_cost = &rs64a_cost;
3055 case PROCESSOR_MPCCORE:
3056 rs6000_cost = &mpccore_cost;
3059 case PROCESSOR_PPC403:
3060 rs6000_cost = &ppc403_cost;
3063 case PROCESSOR_PPC405:
3064 rs6000_cost = &ppc405_cost;
3067 case PROCESSOR_PPC440:
3068 rs6000_cost = &ppc440_cost;
3071 case PROCESSOR_PPC476:
3072 rs6000_cost = &ppc476_cost;
3075 case PROCESSOR_PPC601:
3076 rs6000_cost = &ppc601_cost;
3079 case PROCESSOR_PPC603:
3080 rs6000_cost = &ppc603_cost;
3083 case PROCESSOR_PPC604:
3084 rs6000_cost = &ppc604_cost;
3087 case PROCESSOR_PPC604e:
3088 rs6000_cost = &ppc604e_cost;
3091 case PROCESSOR_PPC620:
3092 rs6000_cost = &ppc620_cost;
3095 case PROCESSOR_PPC630:
3096 rs6000_cost = &ppc630_cost;
3099 case PROCESSOR_CELL:
3100 rs6000_cost = &ppccell_cost;
3103 case PROCESSOR_PPC750:
3104 case PROCESSOR_PPC7400:
3105 rs6000_cost = &ppc750_cost;
3108 case PROCESSOR_PPC7450:
3109 rs6000_cost = &ppc7450_cost;
3112 case PROCESSOR_PPC8540:
3113 rs6000_cost = &ppc8540_cost;
3116 case PROCESSOR_PPCE300C2:
3117 case PROCESSOR_PPCE300C3:
3118 rs6000_cost = &ppce300c2c3_cost;
3121 case PROCESSOR_PPCE500MC:
3122 rs6000_cost = &ppce500mc_cost;
3125 case PROCESSOR_PPCE500MC64:
3126 rs6000_cost = &ppce500mc64_cost;
3129 case PROCESSOR_TITAN:
3130 rs6000_cost = &titan_cost;
3133 case PROCESSOR_POWER4:
3134 case PROCESSOR_POWER5:
3135 rs6000_cost = &power4_cost;
3138 case PROCESSOR_POWER6:
3139 rs6000_cost = &power6_cost;
3142 case PROCESSOR_POWER7:
3143 rs6000_cost = &power7_cost;
3146 case PROCESSOR_PPCA2:
3147 rs6000_cost = &ppca2_cost;
3156 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3157 rs6000_cost->simultaneous_prefetches,
3158 global_options.x_param_values,
3159 global_options_set.x_param_values);
3160 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3161 global_options.x_param_values,
3162 global_options_set.x_param_values);
3163 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3164 rs6000_cost->cache_line_size,
3165 global_options.x_param_values,
3166 global_options_set.x_param_values);
3167 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3168 global_options.x_param_values,
3169 global_options_set.x_param_values);
3171 /* If using typedef char *va_list, signal that
3172 __builtin_va_start (&ap, 0) can be optimized to
3173 ap = __builtin_next_arg (0). */
3174 if (DEFAULT_ABI != ABI_V4)
3175 targetm.expand_builtin_va_start = NULL;
3178 /* Set up single/double float flags.
3179 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3180 then set both flags. */
3181 if (TARGET_HARD_FLOAT && TARGET_FPRS
3182 && rs6000_single_float == 0 && rs6000_double_float == 0)
3183 rs6000_single_float = rs6000_double_float = 1;
3185 /* Reset single and double FP flags if target is E500. */
3188 rs6000_single_float = rs6000_double_float = 0;
3189 if (TARGET_E500_SINGLE)
3190 rs6000_single_float = 1;
3191 if (TARGET_E500_DOUBLE)
3192 rs6000_single_float = rs6000_double_float = 1;
3195 if (main_target_opt)
3197 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3198 error ("target attribute or pragma changes single precision floating "
3200 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3201 error ("target attribute or pragma changes double precision floating "
3205 /* If not explicitly specified via option, decide whether to generate indexed
3206 load/store instructions. */
3207 if (TARGET_AVOID_XFORM == -1)
3208 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3209 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3210 need indexed accesses and the type used is the scalar type of the element
3211 being loaded or stored. */
3212 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3213 && !TARGET_ALTIVEC);
3215 /* Set the -mrecip options. */
3216 if (rs6000_recip_name)
3218 char *p = ASTRDUP (rs6000_recip_name);
3220 unsigned int mask, i;
3223 while ((q = strtok (p, ",")) != NULL)
3234 if (!strcmp (q, "default"))
3235 mask = ((TARGET_RECIP_PRECISION)
3236 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3239 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3240 if (!strcmp (q, recip_options[i].string))
3242 mask = recip_options[i].mask;
3246 if (i == ARRAY_SIZE (recip_options))
3248 error ("unknown option for -mrecip=%s", q);
3256 rs6000_recip_control &= ~mask;
3258 rs6000_recip_control |= mask;
3262 rs6000_init_hard_regno_mode_ok (global_init_p);
3264 /* Save the initial options in case the user does function specific options */
3266 target_option_default_node = target_option_current_node
3267 = build_target_option_node ();
3272 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3273 define the target cpu type. */
3276 rs6000_option_override (void)
3278 (void) rs6000_option_override_internal (true);
3282 /* Implement targetm.vectorize.builtin_mask_for_load. */
3284 rs6000_builtin_mask_for_load (void)
3286 if (TARGET_ALTIVEC || TARGET_VSX)
3287 return altivec_builtin_mask_for_load;
3292 /* Implement LOOP_ALIGN. */
3294 rs6000_loop_align (rtx label)
3299 /* Don't override loop alignment if -falign-loops was specified. */
3300 if (!can_override_loop_align)
3301 return align_loops_log;
3303 bb = BLOCK_FOR_INSN (label);
3304 ninsns = num_loop_insns(bb->loop_father);
3306 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3307 if (ninsns > 4 && ninsns <= 8
3308 && (rs6000_cpu == PROCESSOR_POWER4
3309 || rs6000_cpu == PROCESSOR_POWER5
3310 || rs6000_cpu == PROCESSOR_POWER6
3311 || rs6000_cpu == PROCESSOR_POWER7))
3314 return align_loops_log;
3317 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3319 rs6000_loop_align_max_skip (rtx label)
3321 return (1 << rs6000_loop_align (label)) - 1;
3324 /* Implement targetm.vectorize.builtin_conversion.
3325 Returns a decl of a function that implements conversion of an integer vector
3326 into a floating-point vector, or vice-versa. DEST_TYPE is the
3327 destination type and SRC_TYPE the source type of the conversion.
3328 Return NULL_TREE if it is not available. */
3330 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3332 enum tree_code code = (enum tree_code) tcode;
3336 case FIX_TRUNC_EXPR:
3337 switch (TYPE_MODE (dest_type))
3340 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3343 return TYPE_UNSIGNED (dest_type)
3344 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3345 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3348 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3351 return TYPE_UNSIGNED (dest_type)
3352 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3353 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3360 switch (TYPE_MODE (src_type))
3363 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3366 return TYPE_UNSIGNED (src_type)
3367 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3368 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3371 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3374 return TYPE_UNSIGNED (src_type)
3375 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3376 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3387 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3389 rs6000_builtin_mul_widen_even (tree type)
3391 if (!TARGET_ALTIVEC)
3394 switch (TYPE_MODE (type))
3397 return TYPE_UNSIGNED (type)
3398 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3399 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3402 return TYPE_UNSIGNED (type)
3403 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3404 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3410 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3412 rs6000_builtin_mul_widen_odd (tree type)
3414 if (!TARGET_ALTIVEC)
3417 switch (TYPE_MODE (type))
3420 return TYPE_UNSIGNED (type)
3421 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3422 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3425 return TYPE_UNSIGNED (type)
3426 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3427 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3434 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3435 after applying N number of iterations. This routine does not determine
3436 how may iterations are required to reach desired alignment. */
3439 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3446 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3449 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3459 /* Assuming that all other types are naturally aligned. CHECKME! */
3464 /* Return true if the vector misalignment factor is supported by the
3467 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3474 /* Return if movmisalign pattern is not supported for this mode. */
3475 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3478 if (misalignment == -1)
3480 /* Misalignment factor is unknown at compile time but we know
3481 it's word aligned. */
3482 if (rs6000_vector_alignment_reachable (type, is_packed))
3484 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3486 if (element_size == 64 || element_size == 32)
3493 /* VSX supports word-aligned vector. */
3494 if (misalignment % 4 == 0)
3500 /* Implement targetm.vectorize.builtin_vec_perm. */
3502 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3504 tree inner_type = TREE_TYPE (type);
3505 bool uns_p = TYPE_UNSIGNED (inner_type);
3508 *mask_element_type = unsigned_char_type_node;
3510 switch (TYPE_MODE (type))
3514 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3515 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3520 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3521 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3526 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3527 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3531 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3535 if (!TARGET_ALLOW_DF_PERMUTE)
3538 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3542 if (!TARGET_ALLOW_DF_PERMUTE)
3546 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3547 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3559 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3561 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3562 tree vectype, int misalign)
3566 switch (type_of_cost)
3576 case cond_branch_not_taken:
3580 case cond_branch_taken:
3583 case unaligned_load:
3584 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3586 elements = TYPE_VECTOR_SUBPARTS (vectype);
3588 /* Double word aligned. */
3596 /* Double word aligned. */
3600 /* Unknown misalignment. */
3613 /* Misaligned loads are not supported. */
3618 case unaligned_store:
3619 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3621 elements = TYPE_VECTOR_SUBPARTS (vectype);
3623 /* Double word aligned. */
3631 /* Double word aligned. */
3635 /* Unknown misalignment. */
3648 /* Misaligned stores are not supported. */
3658 /* Implement targetm.vectorize.preferred_simd_mode. */
3660 static enum machine_mode
3661 rs6000_preferred_simd_mode (enum machine_mode mode)
3670 if (TARGET_ALTIVEC || TARGET_VSX)
3694 if (TARGET_PAIRED_FLOAT
3700 /* Implement TARGET_OPTION_INIT_STRUCT. */
3703 rs6000_option_init_struct (struct gcc_options *opts)
3705 if (DEFAULT_ABI == ABI_DARWIN)
3706 /* The Darwin libraries never set errno, so we might as well
3707 avoid calling them when that's the only reason we would. */
3708 opts->x_flag_errno_math = 0;
3710 /* Enable section anchors by default. */
3712 opts->x_flag_section_anchors = 1;
3715 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3718 rs6000_option_default_params (void)
3720 /* Double growth factor to counter reduced min jump length. */
3721 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3724 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3725 library with vectorized intrinsics. */
3728 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3731 const char *suffix = NULL;
3732 tree fntype, new_fndecl, bdecl = NULL_TREE;
3735 enum machine_mode el_mode, in_mode;
3738 /* Libmass is suitable for unsafe math only as it does not correctly support
3739 parts of IEEE with the required precision such as denormals. Only support
3740 it if we have VSX to use the simd d2 or f4 functions.
3741 XXX: Add variable length support. */
3742 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3745 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3746 n = TYPE_VECTOR_SUBPARTS (type_out);
3747 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3748 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3749 if (el_mode != in_mode
3753 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3755 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3758 case BUILT_IN_ATAN2:
3759 case BUILT_IN_HYPOT:
3765 case BUILT_IN_ACOSH:
3767 case BUILT_IN_ASINH:
3769 case BUILT_IN_ATANH:
3777 case BUILT_IN_EXPM1:
3778 case BUILT_IN_LGAMMA:
3779 case BUILT_IN_LOG10:
3780 case BUILT_IN_LOG1P:
3788 bdecl = implicit_built_in_decls[fn];
3789 suffix = "d2"; /* pow -> powd2 */
3790 if (el_mode != DFmode
3795 case BUILT_IN_ATAN2F:
3796 case BUILT_IN_HYPOTF:
3801 case BUILT_IN_ACOSF:
3802 case BUILT_IN_ACOSHF:
3803 case BUILT_IN_ASINF:
3804 case BUILT_IN_ASINHF:
3805 case BUILT_IN_ATANF:
3806 case BUILT_IN_ATANHF:
3807 case BUILT_IN_CBRTF:
3809 case BUILT_IN_COSHF:
3811 case BUILT_IN_ERFCF:
3812 case BUILT_IN_EXP2F:
3814 case BUILT_IN_EXPM1F:
3815 case BUILT_IN_LGAMMAF:
3816 case BUILT_IN_LOG10F:
3817 case BUILT_IN_LOG1PF:
3818 case BUILT_IN_LOG2F:
3821 case BUILT_IN_SINHF:
3822 case BUILT_IN_SQRTF:
3824 case BUILT_IN_TANHF:
3825 bdecl = implicit_built_in_decls[fn];
3826 suffix = "4"; /* powf -> powf4 */
3827 if (el_mode != SFmode
3839 gcc_assert (suffix != NULL);
3840 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3841 strcpy (name, bname + sizeof ("__builtin_") - 1);
3842 strcat (name, suffix);
3845 fntype = build_function_type_list (type_out, type_in, NULL);
3846 else if (n_args == 2)
3847 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3851 /* Build a function declaration for the vectorized function. */
3852 new_fndecl = build_decl (BUILTINS_LOCATION,
3853 FUNCTION_DECL, get_identifier (name), fntype);
3854 TREE_PUBLIC (new_fndecl) = 1;
3855 DECL_EXTERNAL (new_fndecl) = 1;
3856 DECL_IS_NOVOPS (new_fndecl) = 1;
3857 TREE_READONLY (new_fndecl) = 1;
3862 /* Returns a function decl for a vectorized version of the builtin function
3863 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3864 if it is not available. */
3867 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3870 enum machine_mode in_mode, out_mode;
3873 if (TREE_CODE (type_out) != VECTOR_TYPE
3874 || TREE_CODE (type_in) != VECTOR_TYPE
3875 || !TARGET_VECTORIZE_BUILTINS)
3878 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3879 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3880 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3881 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3883 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3885 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3888 case BUILT_IN_COPYSIGN:
3889 if (VECTOR_UNIT_VSX_P (V2DFmode)
3890 && out_mode == DFmode && out_n == 2
3891 && in_mode == DFmode && in_n == 2)
3892 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3894 case BUILT_IN_COPYSIGNF:
3895 if (out_mode != SFmode || out_n != 4
3896 || in_mode != SFmode || in_n != 4)
3898 if (VECTOR_UNIT_VSX_P (V4SFmode))
3899 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3900 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3901 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3904 if (VECTOR_UNIT_VSX_P (V2DFmode)
3905 && out_mode == DFmode && out_n == 2
3906 && in_mode == DFmode && in_n == 2)
3907 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3909 case BUILT_IN_SQRTF:
3910 if (VECTOR_UNIT_VSX_P (V4SFmode)
3911 && out_mode == SFmode && out_n == 4
3912 && in_mode == SFmode && in_n == 4)
3913 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3916 if (VECTOR_UNIT_VSX_P (V2DFmode)
3917 && out_mode == DFmode && out_n == 2
3918 && in_mode == DFmode && in_n == 2)
3919 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3921 case BUILT_IN_CEILF:
3922 if (out_mode != SFmode || out_n != 4
3923 || in_mode != SFmode || in_n != 4)
3925 if (VECTOR_UNIT_VSX_P (V4SFmode))
3926 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3927 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3928 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3930 case BUILT_IN_FLOOR:
3931 if (VECTOR_UNIT_VSX_P (V2DFmode)
3932 && out_mode == DFmode && out_n == 2
3933 && in_mode == DFmode && in_n == 2)
3934 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3936 case BUILT_IN_FLOORF:
3937 if (out_mode != SFmode || out_n != 4
3938 || in_mode != SFmode || in_n != 4)
3940 if (VECTOR_UNIT_VSX_P (V4SFmode))
3941 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3942 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3943 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3946 if (VECTOR_UNIT_VSX_P (V2DFmode)
3947 && out_mode == DFmode && out_n == 2
3948 && in_mode == DFmode && in_n == 2)
3949 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3952 if (VECTOR_UNIT_VSX_P (V4SFmode)
3953 && out_mode == SFmode && out_n == 4
3954 && in_mode == SFmode && in_n == 4)
3955 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3956 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3957 && out_mode == SFmode && out_n == 4
3958 && in_mode == SFmode && in_n == 4)
3959 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
3961 case BUILT_IN_TRUNC:
3962 if (VECTOR_UNIT_VSX_P (V2DFmode)
3963 && out_mode == DFmode && out_n == 2
3964 && in_mode == DFmode && in_n == 2)
3965 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3967 case BUILT_IN_TRUNCF:
3968 if (out_mode != SFmode || out_n != 4
3969 || in_mode != SFmode || in_n != 4)
3971 if (VECTOR_UNIT_VSX_P (V4SFmode))
3972 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3973 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3974 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3976 case BUILT_IN_NEARBYINT:
3977 if (VECTOR_UNIT_VSX_P (V2DFmode)
3978 && flag_unsafe_math_optimizations
3979 && out_mode == DFmode && out_n == 2
3980 && in_mode == DFmode && in_n == 2)
3981 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3983 case BUILT_IN_NEARBYINTF:
3984 if (VECTOR_UNIT_VSX_P (V4SFmode)
3985 && flag_unsafe_math_optimizations
3986 && out_mode == SFmode && out_n == 4
3987 && in_mode == SFmode && in_n == 4)
3988 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3991 if (VECTOR_UNIT_VSX_P (V2DFmode)
3992 && !flag_trapping_math
3993 && out_mode == DFmode && out_n == 2
3994 && in_mode == DFmode && in_n == 2)
3995 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3997 case BUILT_IN_RINTF:
3998 if (VECTOR_UNIT_VSX_P (V4SFmode)
3999 && !flag_trapping_math
4000 && out_mode == SFmode && out_n == 4
4001 && in_mode == SFmode && in_n == 4)
4002 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4009 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4011 enum rs6000_builtins fn
4012 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4015 case RS6000_BUILTIN_RSQRTF:
4016 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4017 && out_mode == SFmode && out_n == 4
4018 && in_mode == SFmode && in_n == 4)
4019 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4021 case RS6000_BUILTIN_RSQRT:
4022 if (VECTOR_UNIT_VSX_P (V2DFmode)
4023 && out_mode == DFmode && out_n == 2
4024 && in_mode == DFmode && in_n == 2)
4025 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4027 case RS6000_BUILTIN_RECIPF:
4028 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4029 && out_mode == SFmode && out_n == 4
4030 && in_mode == SFmode && in_n == 4)
4031 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4033 case RS6000_BUILTIN_RECIP:
4034 if (VECTOR_UNIT_VSX_P (V2DFmode)
4035 && out_mode == DFmode && out_n == 2
4036 && in_mode == DFmode && in_n == 2)
4037 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4044 /* Generate calls to libmass if appropriate. */
4045 if (rs6000_veclib_handler)
4046 return rs6000_veclib_handler (fndecl, type_out, type_in);
4052 /* Implement TARGET_HANDLE_OPTION. */
4055 rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
4056 const struct cl_decoded_option *decoded,
4059 enum fpu_type_t fpu_type = FPU_NONE;
4061 size_t code = decoded->opt_index;
4062 const char *arg = decoded->arg;
4063 int value = decoded->value;
4068 opts->x_target_flags &= ~(MASK_POWER | MASK_POWER2
4069 | MASK_MULTIPLE | MASK_STRING);
4070 opts_set->x_target_flags |= (MASK_POWER | MASK_POWER2
4071 | MASK_MULTIPLE | MASK_STRING);
4073 case OPT_mno_powerpc:
4074 opts->x_target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4075 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4076 opts_set->x_target_flags |= (MASK_POWERPC | MASK_PPC_GPOPT
4077 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4080 opts->x_target_flags &= ~MASK_MINIMAL_TOC;
4081 opts->x_TARGET_NO_FP_IN_TOC = 0;
4082 opts->x_TARGET_NO_SUM_IN_TOC = 0;
4083 opts_set->x_target_flags |= MASK_MINIMAL_TOC;
4084 #ifdef TARGET_USES_SYSV4_OPT
4085 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4086 just the same as -mminimal-toc. */
4087 opts->x_target_flags |= MASK_MINIMAL_TOC;
4088 opts_set->x_target_flags |= MASK_MINIMAL_TOC;
4092 #ifdef TARGET_USES_SYSV4_OPT
4094 /* Make -mtoc behave like -mminimal-toc. */
4095 opts->x_target_flags |= MASK_MINIMAL_TOC;
4096 opts_set->x_target_flags |= MASK_MINIMAL_TOC;
4100 #ifdef TARGET_USES_AIX64_OPT
4105 opts->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4106 opts->x_target_flags |= ~opts_set->x_target_flags & MASK_PPC_GFXOPT;
4107 opts_set->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4110 #ifdef TARGET_USES_AIX64_OPT
4115 opts->x_target_flags &= ~MASK_POWERPC64;
4116 opts_set->x_target_flags |= MASK_POWERPC64;
4119 case OPT_mminimal_toc:
4122 opts->x_TARGET_NO_FP_IN_TOC = 0;
4123 opts->x_TARGET_NO_SUM_IN_TOC = 0;
4130 opts->x_target_flags |= (MASK_MULTIPLE | MASK_STRING);
4131 opts_set->x_target_flags |= (MASK_MULTIPLE | MASK_STRING);
4138 opts->x_target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4139 opts_set->x_target_flags |= (MASK_POWER
4145 case OPT_mpowerpc_gpopt:
4146 case OPT_mpowerpc_gfxopt:
4149 opts->x_target_flags |= MASK_POWERPC;
4150 opts_set->x_target_flags |= MASK_POWERPC;
4156 opts->x_rs6000_debug = 0;
4158 while ((q = strtok (p, ",")) != NULL)
4172 if (! strcmp (q, "all"))
4173 mask = MASK_DEBUG_ALL;
4174 else if (! strcmp (q, "stack"))
4175 mask = MASK_DEBUG_STACK;
4176 else if (! strcmp (q, "arg"))
4177 mask = MASK_DEBUG_ARG;
4178 else if (! strcmp (q, "reg"))
4179 mask = MASK_DEBUG_REG;
4180 else if (! strcmp (q, "addr"))
4181 mask = MASK_DEBUG_ADDR;
4182 else if (! strcmp (q, "cost"))
4183 mask = MASK_DEBUG_COST;
4184 else if (! strcmp (q, "target"))
4185 mask = MASK_DEBUG_TARGET;
4187 error_at (loc, "unknown -mdebug-%s switch", q);
4190 opts->x_rs6000_debug &= ~mask;
4192 opts->x_rs6000_debug |= mask;
4196 #ifdef TARGET_USES_SYSV4_OPT
4197 case OPT_mrelocatable:
4200 opts->x_target_flags |= MASK_MINIMAL_TOC;
4201 opts_set->x_target_flags |= MASK_MINIMAL_TOC;
4202 opts->x_TARGET_NO_FP_IN_TOC = 1;
4206 case OPT_mrelocatable_lib:
4209 opts->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4210 opts_set->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4211 opts->x_TARGET_NO_FP_IN_TOC = 1;
4215 opts->x_target_flags &= ~MASK_RELOCATABLE;
4216 opts_set->x_target_flags |= MASK_RELOCATABLE;
4221 case OPT_mabi_altivec:
4222 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4223 opts->x_rs6000_spe_abi = 0;
4227 opts->x_rs6000_altivec_abi = 0;
4230 case OPT_mlong_double_:
4231 if (value != 64 && value != 128)
4233 error_at (loc, "unknown switch -mlong-double-%s", arg);
4234 opts->x_rs6000_long_double_type_size
4235 = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4240 case OPT_msingle_float:
4241 if (!TARGET_SINGLE_FPU)
4243 "-msingle-float option equivalent to -mhard-float");
4244 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4245 opts->x_rs6000_double_float = 0;
4246 opts->x_target_flags &= ~MASK_SOFT_FLOAT;
4247 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
4250 case OPT_mdouble_float:
4251 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4252 opts->x_rs6000_single_float = 1;
4253 opts->x_target_flags &= ~MASK_SOFT_FLOAT;
4254 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
4257 case OPT_msimple_fpu:
4258 if (!TARGET_SINGLE_FPU)
4259 warning_at (loc, 0, "-msimple-fpu option ignored");
4262 case OPT_mhard_float:
4263 /* -mhard_float implies -msingle-float and -mdouble-float. */
4264 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
4267 case OPT_msoft_float:
4268 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4269 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
4273 fpu_type = (enum fpu_type_t) value;
4274 if (fpu_type != FPU_NONE)
4276 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on
4278 opts->x_target_flags &= ~MASK_SOFT_FLOAT;
4279 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
4280 opts->x_rs6000_xilinx_fpu = 1;
4281 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4282 opts->x_rs6000_single_float = 1;
4283 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4284 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
4285 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4286 opts->x_rs6000_simple_fpu = 1;
4290 /* -mfpu=none is equivalent to -msoft-float. */
4291 opts->x_target_flags |= MASK_SOFT_FLOAT;
4292 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
4293 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
4298 opts->x_rs6000_recip_name = (value) ? "default" : "none";
4304 /* Default CPU string for rs6000*_file_start functions. */
4305 static const char *rs6000_default_cpu;
4307 /* Do anything needed at the start of the asm file. */
4310 rs6000_file_start (void)
4313 const char *start = buffer;
4314 FILE *file = asm_out_file;
4316 rs6000_default_cpu = TARGET_CPU_DEFAULT;
4318 default_file_start ();
4320 #ifdef TARGET_BI_ARCH
4321 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4322 rs6000_default_cpu = 0;
4325 if (flag_verbose_asm)
4327 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4329 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
4331 fprintf (file, "%s --with-cpu=%s", start, rs6000_default_cpu);
4335 if (global_options_set.x_rs6000_cpu_index)
4337 fprintf (file, "%s -mcpu=%s", start,
4338 processor_target_table[rs6000_cpu_index].name);
4342 if (global_options_set.x_rs6000_tune_index)
4344 fprintf (file, "%s -mtune=%s", start,
4345 processor_target_table[rs6000_tune_index].name);
4349 if (PPC405_ERRATUM77)
4351 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4355 #ifdef USING_ELFOS_H
4356 switch (rs6000_sdata)
4358 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4359 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4360 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4361 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4364 if (rs6000_sdata && g_switch_value)
4366 fprintf (file, "%s -G %d", start,
4376 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4378 switch_to_section (toc_section);
4379 switch_to_section (text_section);
4384 /* Return nonzero if this function is known to have a null epilogue. */
4387 direct_return (void)
4389 if (reload_completed)
4391 rs6000_stack_t *info = rs6000_stack_info ();
4393 if (info->first_gp_reg_save == 32
4394 && info->first_fp_reg_save == 64
4395 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4396 && ! info->lr_save_p
4397 && ! info->cr_save_p
4398 && info->vrsave_mask == 0
4406 /* Return the number of instructions it takes to form a constant in an
4407 integer register. */
4410 num_insns_constant_wide (HOST_WIDE_INT value)
4412 /* signed constant loadable with {cal|addi} */
4413 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4416 /* constant loadable with {cau|addis} */
4417 else if ((value & 0xffff) == 0
4418 && (value >> 31 == -1 || value >> 31 == 0))
4421 #if HOST_BITS_PER_WIDE_INT == 64
4422 else if (TARGET_POWERPC64)
4424 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4425 HOST_WIDE_INT high = value >> 31;
4427 if (high == 0 || high == -1)
4433 return num_insns_constant_wide (high) + 1;
4435 return num_insns_constant_wide (low) + 1;
4437 return (num_insns_constant_wide (high)
4438 + num_insns_constant_wide (low) + 1);
4447 num_insns_constant (rtx op, enum machine_mode mode)
4449 HOST_WIDE_INT low, high;
4451 switch (GET_CODE (op))
4454 #if HOST_BITS_PER_WIDE_INT == 64
4455 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4456 && mask64_operand (op, mode))
4460 return num_insns_constant_wide (INTVAL (op));
4463 if (mode == SFmode || mode == SDmode)
4468 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4469 if (DECIMAL_FLOAT_MODE_P (mode))
4470 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4472 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4473 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4476 if (mode == VOIDmode || mode == DImode)
4478 high = CONST_DOUBLE_HIGH (op);
4479 low = CONST_DOUBLE_LOW (op);
4486 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4487 if (DECIMAL_FLOAT_MODE_P (mode))
4488 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4490 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4491 high = l[WORDS_BIG_ENDIAN == 0];
4492 low = l[WORDS_BIG_ENDIAN != 0];
4496 return (num_insns_constant_wide (low)
4497 + num_insns_constant_wide (high));
4500 if ((high == 0 && low >= 0)
4501 || (high == -1 && low < 0))
4502 return num_insns_constant_wide (low);
4504 else if (mask64_operand (op, mode))
4508 return num_insns_constant_wide (high) + 1;
4511 return (num_insns_constant_wide (high)
4512 + num_insns_constant_wide (low) + 1);
4520 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4521 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4522 corresponding element of the vector, but for V4SFmode and V2SFmode,
4523 the corresponding "float" is interpreted as an SImode integer. */
4526 const_vector_elt_as_int (rtx op, unsigned int elt)
4530 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4531 gcc_assert (GET_MODE (op) != V2DImode
4532 && GET_MODE (op) != V2DFmode);
4534 tmp = CONST_VECTOR_ELT (op, elt);
4535 if (GET_MODE (op) == V4SFmode
4536 || GET_MODE (op) == V2SFmode)
4537 tmp = gen_lowpart (SImode, tmp);
4538 return INTVAL (tmp);
4541 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4542 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4543 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4544 all items are set to the same value and contain COPIES replicas of the
4545 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4546 operand and the others are set to the value of the operand's msb. */
4549 vspltis_constant (rtx op, unsigned step, unsigned copies)
4551 enum machine_mode mode = GET_MODE (op);
4552 enum machine_mode inner = GET_MODE_INNER (mode);
4560 HOST_WIDE_INT splat_val;
4561 HOST_WIDE_INT msb_val;
4563 if (mode == V2DImode || mode == V2DFmode)
4566 nunits = GET_MODE_NUNITS (mode);
4567 bitsize = GET_MODE_BITSIZE (inner);
4568 mask = GET_MODE_MASK (inner);
4570 val = const_vector_elt_as_int (op, nunits - 1);
4572 msb_val = val > 0 ? 0 : -1;
4574 /* Construct the value to be splatted, if possible. If not, return 0. */
4575 for (i = 2; i <= copies; i *= 2)
4577 HOST_WIDE_INT small_val;
4579 small_val = splat_val >> bitsize;
4581 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4583 splat_val = small_val;
4586 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4587 if (EASY_VECTOR_15 (splat_val))
4590 /* Also check if we can splat, and then add the result to itself. Do so if
4591 the value is positive, of if the splat instruction is using OP's mode;
4592 for splat_val < 0, the splat and the add should use the same mode. */
4593 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4594 && (splat_val >= 0 || (step == 1 && copies == 1)))
4597 /* Also check if are loading up the most significant bit which can be done by
4598 loading up -1 and shifting the value left by -1. */
4599 else if (EASY_VECTOR_MSB (splat_val, inner))
4605 /* Check if VAL is present in every STEP-th element, and the
4606 other elements are filled with its most significant bit. */
4607 for (i = 0; i < nunits - 1; ++i)
4609 HOST_WIDE_INT desired_val;
4610 if (((i + 1) & (step - 1)) == 0)
4613 desired_val = msb_val;
4615 if (desired_val != const_vector_elt_as_int (op, i))
4623 /* Return true if OP is of the given MODE and can be synthesized
4624 with a vspltisb, vspltish or vspltisw. */
4627 easy_altivec_constant (rtx op, enum machine_mode mode)
4629 unsigned step, copies;
4631 if (mode == VOIDmode)
4632 mode = GET_MODE (op);
4633 else if (mode != GET_MODE (op))
4636 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4638 if (mode == V2DFmode)
4639 return zero_constant (op, mode);
4641 if (mode == V2DImode)
4643 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4645 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4646 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4649 if (zero_constant (op, mode))
4652 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4653 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4659 /* Start with a vspltisw. */
4660 step = GET_MODE_NUNITS (mode) / 4;
4663 if (vspltis_constant (op, step, copies))
4666 /* Then try with a vspltish. */
4672 if (vspltis_constant (op, step, copies))
4675 /* And finally a vspltisb. */
4681 if (vspltis_constant (op, step, copies))
4687 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4688 result is OP. Abort if it is not possible. */
4691 gen_easy_altivec_constant (rtx op)
4693 enum machine_mode mode = GET_MODE (op);
4694 int nunits = GET_MODE_NUNITS (mode);
4695 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4696 unsigned step = nunits / 4;
4697 unsigned copies = 1;
4699 /* Start with a vspltisw. */
4700 if (vspltis_constant (op, step, copies))
4701 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4703 /* Then try with a vspltish. */
4709 if (vspltis_constant (op, step, copies))
4710 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4712 /* And finally a vspltisb. */
4718 if (vspltis_constant (op, step, copies))
4719 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4725 output_vec_const_move (rtx *operands)
4728 enum machine_mode mode;
4733 mode = GET_MODE (dest);
4737 if (zero_constant (vec, mode))
4738 return "xxlxor %x0,%x0,%x0";
4740 if (mode == V2DImode
4741 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
4742 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
4743 return "vspltisw %0,-1";
4749 if (zero_constant (vec, mode))
4750 return "vxor %0,%0,%0";
4752 splat_vec = gen_easy_altivec_constant (vec);
4753 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4754 operands[1] = XEXP (splat_vec, 0);
4755 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4758 switch (GET_MODE (splat_vec))
4761 return "vspltisw %0,%1";
4764 return "vspltish %0,%1";
4767 return "vspltisb %0,%1";
4774 gcc_assert (TARGET_SPE);
4776 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4777 pattern of V1DI, V4HI, and V2SF.
4779 FIXME: We should probably return # and add post reload
4780 splitters for these, but this way is so easy ;-). */
4781 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4782 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4783 operands[1] = CONST_VECTOR_ELT (vec, 0);
4784 operands[2] = CONST_VECTOR_ELT (vec, 1);
4786 return "li %0,%1\n\tevmergelo %0,%0,%0";
4788 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4791 /* Initialize TARGET of vector PAIRED to VALS. */
4794 paired_expand_vector_init (rtx target, rtx vals)
4796 enum machine_mode mode = GET_MODE (target);
4797 int n_elts = GET_MODE_NUNITS (mode);
4799 rtx x, new_rtx, tmp, constant_op, op1, op2;
4802 for (i = 0; i < n_elts; ++i)
4804 x = XVECEXP (vals, 0, i);
4805 if (!CONSTANT_P (x))
4810 /* Load from constant pool. */
4811 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4817 /* The vector is initialized only with non-constants. */
4818 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4819 XVECEXP (vals, 0, 1));
4821 emit_move_insn (target, new_rtx);
4825 /* One field is non-constant and the other one is a constant. Load the
4826 constant from the constant pool and use ps_merge instruction to
4827 construct the whole vector. */
4828 op1 = XVECEXP (vals, 0, 0);
4829 op2 = XVECEXP (vals, 0, 1);
4831 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4833 tmp = gen_reg_rtx (GET_MODE (constant_op));
4834 emit_move_insn (tmp, constant_op);
4836 if (CONSTANT_P (op1))
4837 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4839 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4841 emit_move_insn (target, new_rtx);
4845 paired_expand_vector_move (rtx operands[])
4847 rtx op0 = operands[0], op1 = operands[1];
4849 emit_move_insn (op0, op1);
4852 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4853 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4854 operands for the relation operation COND. This is a recursive
4858 paired_emit_vector_compare (enum rtx_code rcode,
4859 rtx dest, rtx op0, rtx op1,
4860 rtx cc_op0, rtx cc_op1)
4862 rtx tmp = gen_reg_rtx (V2SFmode);
4865 gcc_assert (TARGET_PAIRED_FLOAT);
4866 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4872 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4876 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4877 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4881 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4884 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4887 tmp1 = gen_reg_rtx (V2SFmode);
4888 max = gen_reg_rtx (V2SFmode);
4889 min = gen_reg_rtx (V2SFmode);
4890 gen_reg_rtx (V2SFmode);
4892 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4893 emit_insn (gen_selv2sf4
4894 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4895 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4896 emit_insn (gen_selv2sf4
4897 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4898 emit_insn (gen_subv2sf3 (tmp1, min, max));
4899 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4902 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4905 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4908 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4911 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4914 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4923 /* Emit vector conditional expression.
4924 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4925 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4928 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4929 rtx cond, rtx cc_op0, rtx cc_op1)
4931 enum rtx_code rcode = GET_CODE (cond);
4933 if (!TARGET_PAIRED_FLOAT)
4936 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4941 /* Initialize vector TARGET to VALS. */
4944 rs6000_expand_vector_init (rtx target, rtx vals)
4946 enum machine_mode mode = GET_MODE (target);
4947 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4948 int n_elts = GET_MODE_NUNITS (mode);
4949 int n_var = 0, one_var = -1;
4950 bool all_same = true, all_const_zero = true;
4954 for (i = 0; i < n_elts; ++i)
4956 x = XVECEXP (vals, 0, i);
4957 if (!CONSTANT_P (x))
4958 ++n_var, one_var = i;
4959 else if (x != CONST0_RTX (inner_mode))
4960 all_const_zero = false;
4962 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4968 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4969 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4970 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4972 /* Zero register. */
4973 emit_insn (gen_rtx_SET (VOIDmode, target,
4974 gen_rtx_XOR (mode, target, target)));
4977 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4979 /* Splat immediate. */
4980 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4985 /* Load from constant pool. */
4986 emit_move_insn (target, const_vec);
4991 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4992 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4996 rtx element = XVECEXP (vals, 0, 0);
4997 if (mode == V2DFmode)
4998 emit_insn (gen_vsx_splat_v2df (target, element));
5000 emit_insn (gen_vsx_splat_v2di (target, element));
5004 if (mode == V2DFmode)
5006 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5007 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5008 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5012 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5013 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5014 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5020 /* With single precision floating point on VSX, know that internally single
5021 precision is actually represented as a double, and either make 2 V2DF
5022 vectors, and convert these vectors to single precision, or do one
5023 conversion, and splat the result to the other elements. */
5024 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5028 rtx freg = gen_reg_rtx (V4SFmode);
5029 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5031 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5032 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5036 rtx dbl_even = gen_reg_rtx (V2DFmode);
5037 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5038 rtx flt_even = gen_reg_rtx (V4SFmode);
5039 rtx flt_odd = gen_reg_rtx (V4SFmode);
5041 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5042 copy_to_reg (XVECEXP (vals, 0, 0)),
5043 copy_to_reg (XVECEXP (vals, 0, 1))));
5044 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5045 copy_to_reg (XVECEXP (vals, 0, 2)),
5046 copy_to_reg (XVECEXP (vals, 0, 3))));
5047 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5048 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5049 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5054 /* Store value to stack temp. Load vector element. Splat. However, splat
5055 of 64-bit items is not supported on Altivec. */
5056 if (all_same && GET_MODE_SIZE (mode) <= 4)
5058 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5059 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5060 XVECEXP (vals, 0, 0));
5061 x = gen_rtx_UNSPEC (VOIDmode,
5062 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5063 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5065 gen_rtx_SET (VOIDmode,
5068 x = gen_rtx_VEC_SELECT (inner_mode, target,
5069 gen_rtx_PARALLEL (VOIDmode,
5070 gen_rtvec (1, const0_rtx)));
5071 emit_insn (gen_rtx_SET (VOIDmode, target,
5072 gen_rtx_VEC_DUPLICATE (mode, x)));
5076 /* One field is non-constant. Load constant then overwrite
5080 rtx copy = copy_rtx (vals);
5082 /* Load constant part of vector, substitute neighboring value for
5084 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5085 rs6000_expand_vector_init (target, copy);
5087 /* Insert variable. */
5088 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5092 /* Construct the vector in memory one field at a time
5093 and load the whole vector. */
5094 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5095 for (i = 0; i < n_elts; i++)
5096 emit_move_insn (adjust_address_nv (mem, inner_mode,
5097 i * GET_MODE_SIZE (inner_mode)),
5098 XVECEXP (vals, 0, i));
5099 emit_move_insn (target, mem);
5102 /* Set field ELT of TARGET to VAL. */
5105 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5107 enum machine_mode mode = GET_MODE (target);
5108 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5109 rtx reg = gen_reg_rtx (mode);
5111 int width = GET_MODE_SIZE (inner_mode);
5114 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5116 rtx (*set_func) (rtx, rtx, rtx, rtx)
5117 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5118 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5122 /* Load single variable value. */
5123 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5124 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5125 x = gen_rtx_UNSPEC (VOIDmode,
5126 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5127 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5129 gen_rtx_SET (VOIDmode,
5133 /* Linear sequence. */
5134 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5135 for (i = 0; i < 16; ++i)
5136 XVECEXP (mask, 0, i) = GEN_INT (i);
5138 /* Set permute mask to insert element into target. */
5139 for (i = 0; i < width; ++i)
5140 XVECEXP (mask, 0, elt*width + i)
5141 = GEN_INT (i + 0x10);
5142 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5143 x = gen_rtx_UNSPEC (mode,
5144 gen_rtvec (3, target, reg,
5145 force_reg (V16QImode, x)),
5147 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5150 /* Extract field ELT from VEC into TARGET. */
5153 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5155 enum machine_mode mode = GET_MODE (vec);
5156 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5159 if (VECTOR_MEM_VSX_P (mode))
5166 emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
5169 emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
5172 emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt)));
5177 /* Allocate mode-sized buffer. */
5178 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5180 emit_move_insn (mem, vec);
5182 /* Add offset to field within buffer matching vector element. */
5183 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5185 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5188 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5189 implement ANDing by the mask IN. */
5191 build_mask64_2_operands (rtx in, rtx *out)
5193 #if HOST_BITS_PER_WIDE_INT >= 64
5194 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5197 gcc_assert (GET_CODE (in) == CONST_INT);
5202 /* Assume c initially something like 0x00fff000000fffff. The idea
5203 is to rotate the word so that the middle ^^^^^^ group of zeros
5204 is at the MS end and can be cleared with an rldicl mask. We then
5205 rotate back and clear off the MS ^^ group of zeros with a
5207 c = ~c; /* c == 0xff000ffffff00000 */
5208 lsb = c & -c; /* lsb == 0x0000000000100000 */
5209 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5210 c = ~c; /* c == 0x00fff000000fffff */
5211 c &= -lsb; /* c == 0x00fff00000000000 */
5212 lsb = c & -c; /* lsb == 0x0000100000000000 */
5213 c = ~c; /* c == 0xff000fffffffffff */
5214 c &= -lsb; /* c == 0xff00000000000000 */
5216 while ((lsb >>= 1) != 0)
5217 shift++; /* shift == 44 on exit from loop */
5218 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5219 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5220 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5224 /* Assume c initially something like 0xff000f0000000000. The idea
5225 is to rotate the word so that the ^^^ middle group of zeros
5226 is at the LS end and can be cleared with an rldicr mask. We then
5227 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5229 lsb = c & -c; /* lsb == 0x0000010000000000 */
5230 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5231 c = ~c; /* c == 0x00fff0ffffffffff */
5232 c &= -lsb; /* c == 0x00fff00000000000 */
5233 lsb = c & -c; /* lsb == 0x0000100000000000 */
5234 c = ~c; /* c == 0xff000fffffffffff */
5235 c &= -lsb; /* c == 0xff00000000000000 */
5237 while ((lsb >>= 1) != 0)
5238 shift++; /* shift == 44 on exit from loop */
5239 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5240 m1 >>= shift; /* m1 == 0x0000000000000fff */
5241 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5244 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5245 masks will be all 1's. We are guaranteed more than one transition. */
5246 out[0] = GEN_INT (64 - shift);
5247 out[1] = GEN_INT (m1);
5248 out[2] = GEN_INT (shift);
5249 out[3] = GEN_INT (m2);
5257 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5260 invalid_e500_subreg (rtx op, enum machine_mode mode)
5262 if (TARGET_E500_DOUBLE)
5264 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5265 subreg:TI and reg:TF. Decimal float modes are like integer
5266 modes (only low part of each register used) for this
5268 if (GET_CODE (op) == SUBREG
5269 && (mode == SImode || mode == DImode || mode == TImode
5270 || mode == DDmode || mode == TDmode)
5271 && REG_P (SUBREG_REG (op))
5272 && (GET_MODE (SUBREG_REG (op)) == DFmode
5273 || GET_MODE (SUBREG_REG (op)) == TFmode))
5276 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5278 if (GET_CODE (op) == SUBREG
5279 && (mode == DFmode || mode == TFmode)
5280 && REG_P (SUBREG_REG (op))
5281 && (GET_MODE (SUBREG_REG (op)) == DImode
5282 || GET_MODE (SUBREG_REG (op)) == TImode
5283 || GET_MODE (SUBREG_REG (op)) == DDmode
5284 || GET_MODE (SUBREG_REG (op)) == TDmode))
5289 && GET_CODE (op) == SUBREG
5291 && REG_P (SUBREG_REG (op))
5292 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5298 /* AIX increases natural record alignment to doubleword if the first
5299 field is an FP double while the FP fields remain word aligned. */
5302 rs6000_special_round_type_align (tree type, unsigned int computed,
5303 unsigned int specified)
5305 unsigned int align = MAX (computed, specified);
5306 tree field = TYPE_FIELDS (type);
5308 /* Skip all non field decls */
5309 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5310 field = DECL_CHAIN (field);
5312 if (field != NULL && field != type)
5314 type = TREE_TYPE (field);
5315 while (TREE_CODE (type) == ARRAY_TYPE)
5316 type = TREE_TYPE (type);
5318 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5319 align = MAX (align, 64);
5325 /* Darwin increases record alignment to the natural alignment of
5329 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5330 unsigned int specified)
5332 unsigned int align = MAX (computed, specified);
5334 if (TYPE_PACKED (type))
5337 /* Find the first field, looking down into aggregates. */
5339 tree field = TYPE_FIELDS (type);
5340 /* Skip all non field decls */
5341 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5342 field = DECL_CHAIN (field);
5345 /* A packed field does not contribute any extra alignment. */
5346 if (DECL_PACKED (field))
5348 type = TREE_TYPE (field);
5349 while (TREE_CODE (type) == ARRAY_TYPE)
5350 type = TREE_TYPE (type);
5351 } while (AGGREGATE_TYPE_P (type));
5353 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5354 align = MAX (align, TYPE_ALIGN (type));
5359 /* Return 1 for an operand in small memory on V.4/eabi. */
5362 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5363 enum machine_mode mode ATTRIBUTE_UNUSED)
5368 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5371 if (DEFAULT_ABI != ABI_V4)
5374 /* Vector and float memory instructions have a limited offset on the
5375 SPE, so using a vector or float variable directly as an operand is
5378 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5381 if (GET_CODE (op) == SYMBOL_REF)
5384 else if (GET_CODE (op) != CONST
5385 || GET_CODE (XEXP (op, 0)) != PLUS
5386 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5387 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5392 rtx sum = XEXP (op, 0);
5393 HOST_WIDE_INT summand;
5395 /* We have to be careful here, because it is the referenced address
5396 that must be 32k from _SDA_BASE_, not just the symbol. */
5397 summand = INTVAL (XEXP (sum, 1));
5398 if (summand < 0 || summand > g_switch_value)
5401 sym_ref = XEXP (sum, 0);
5404 return SYMBOL_REF_SMALL_P (sym_ref);
5410 /* Return true if either operand is a general purpose register. */
5413 gpr_or_gpr_p (rtx op0, rtx op1)
5415 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5416 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5420 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5423 reg_offset_addressing_ok_p (enum machine_mode mode)
5433 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5434 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5442 /* Paired vector modes. Only reg+reg addressing is valid. */
5443 if (TARGET_PAIRED_FLOAT)
5455 virtual_stack_registers_memory_p (rtx op)
5459 if (GET_CODE (op) == REG)
5460 regnum = REGNO (op);
5462 else if (GET_CODE (op) == PLUS
5463 && GET_CODE (XEXP (op, 0)) == REG
5464 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5465 regnum = REGNO (XEXP (op, 0));
5470 return (regnum >= FIRST_VIRTUAL_REGISTER
5471 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5474 /* Return true if memory accesses to OP are known to never straddle
5478 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5479 enum machine_mode mode)
5482 unsigned HOST_WIDE_INT dsize, dalign;
5484 if (GET_CODE (op) != SYMBOL_REF)
5487 decl = SYMBOL_REF_DECL (op);
5490 if (GET_MODE_SIZE (mode) == 0)
5493 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5494 replacing memory addresses with an anchor plus offset. We
5495 could find the decl by rummaging around in the block->objects
5496 VEC for the given offset but that seems like too much work. */
5498 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5499 && SYMBOL_REF_ANCHOR_P (op)
5500 && SYMBOL_REF_BLOCK (op) != NULL)
5502 struct object_block *block = SYMBOL_REF_BLOCK (op);
5503 HOST_WIDE_INT lsb, mask;
5505 /* Given the alignment of the block.. */
5506 dalign = block->alignment;
5507 mask = dalign / BITS_PER_UNIT - 1;
5509 /* ..and the combined offset of the anchor and any offset
5510 to this block object.. */
5511 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5512 lsb = offset & -offset;
5514 /* ..find how many bits of the alignment we know for the
5519 return dalign >= GET_MODE_SIZE (mode);
5524 if (TREE_CODE (decl) == FUNCTION_DECL)
5527 if (!DECL_SIZE_UNIT (decl))
5530 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5533 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5537 dalign = DECL_ALIGN_UNIT (decl);
5538 return dalign >= dsize;
5541 type = TREE_TYPE (decl);
5543 if (TREE_CODE (decl) == STRING_CST)
5544 dsize = TREE_STRING_LENGTH (decl);
5545 else if (TYPE_SIZE_UNIT (type)
5546 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5547 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5553 dalign = TYPE_ALIGN (type);
5554 if (CONSTANT_CLASS_P (decl))
5555 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5557 dalign = DATA_ALIGNMENT (decl, dalign);
5558 dalign /= BITS_PER_UNIT;
5559 return dalign >= dsize;
5563 constant_pool_expr_p (rtx op)
5567 split_const (op, &base, &offset);
5568 return (GET_CODE (base) == SYMBOL_REF
5569 && CONSTANT_POOL_ADDRESS_P (base)
5570 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5573 static rtx tocrel_base, tocrel_offset;
5576 toc_relative_expr_p (rtx op)
5578 if (GET_CODE (op) != CONST)
5581 split_const (op, &tocrel_base, &tocrel_offset);
5582 return (GET_CODE (tocrel_base) == UNSPEC
5583 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5586 /* Return true if X is a constant pool address, and also for cmodel=medium
5587 if X is a toc-relative address known to be offsettable within MODE. */
5590 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5594 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5595 && GET_CODE (XEXP (x, 0)) == REG
5596 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5597 || ((TARGET_MINIMAL_TOC
5598 || TARGET_CMODEL != CMODEL_SMALL)
5599 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5600 && toc_relative_expr_p (XEXP (x, 1))
5601 && (TARGET_CMODEL != CMODEL_MEDIUM
5602 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5604 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5605 INTVAL (tocrel_offset), mode)));
5609 legitimate_small_data_p (enum machine_mode mode, rtx x)
5611 return (DEFAULT_ABI == ABI_V4
5612 && !flag_pic && !TARGET_TOC
5613 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5614 && small_data_operand (x, mode));
5617 /* SPE offset addressing is limited to 5-bits worth of double words. */
5618 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5621 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5623 unsigned HOST_WIDE_INT offset, extra;
5625 if (GET_CODE (x) != PLUS)
5627 if (GET_CODE (XEXP (x, 0)) != REG)
5629 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5631 if (!reg_offset_addressing_ok_p (mode))
5632 return virtual_stack_registers_memory_p (x);
5633 if (legitimate_constant_pool_address_p (x, mode, strict))
5635 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5638 offset = INTVAL (XEXP (x, 1));
5646 /* SPE vector modes. */
5647 return SPE_CONST_OFFSET_OK (offset);
5650 if (TARGET_E500_DOUBLE)
5651 return SPE_CONST_OFFSET_OK (offset);
5653 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5655 if (VECTOR_MEM_VSX_P (DFmode))
5660 /* On e500v2, we may have:
5662 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5664 Which gets addressed with evldd instructions. */
5665 if (TARGET_E500_DOUBLE)
5666 return SPE_CONST_OFFSET_OK (offset);
5668 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5670 else if (offset & 3)
5675 if (TARGET_E500_DOUBLE)
5676 return (SPE_CONST_OFFSET_OK (offset)
5677 && SPE_CONST_OFFSET_OK (offset + 8));
5681 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5683 else if (offset & 3)
5694 return (offset < 0x10000) && (offset + extra < 0x10000);
5698 legitimate_indexed_address_p (rtx x, int strict)
5702 if (GET_CODE (x) != PLUS)
5708 /* Recognize the rtl generated by reload which we know will later be
5709 replaced with proper base and index regs. */
5711 && reload_in_progress
5712 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5716 return (REG_P (op0) && REG_P (op1)
5717 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5718 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5719 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5720 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5724 avoiding_indexed_address_p (enum machine_mode mode)
5726 /* Avoid indexed addressing for modes that have non-indexed
5727 load/store instruction forms. */
5728 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5732 legitimate_indirect_address_p (rtx x, int strict)
5734 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5738 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5740 if (!TARGET_MACHO || !flag_pic
5741 || mode != SImode || GET_CODE (x) != MEM)
5745 if (GET_CODE (x) != LO_SUM)
5747 if (GET_CODE (XEXP (x, 0)) != REG)
5749 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5753 return CONSTANT_P (x);
5757 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5759 if (GET_CODE (x) != LO_SUM)
5761 if (GET_CODE (XEXP (x, 0)) != REG)
5763 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5765 /* Restrict addressing for DI because of our SUBREG hackery. */
5766 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5767 || mode == DDmode || mode == TDmode
5772 if (TARGET_ELF || TARGET_MACHO)
5774 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5778 if (GET_MODE_NUNITS (mode) != 1)
5780 if (GET_MODE_BITSIZE (mode) > 64
5781 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5782 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5783 && (mode == DFmode || mode == DDmode))))
5786 return CONSTANT_P (x);
5793 /* Try machine-dependent ways of modifying an illegitimate address
5794 to be legitimate. If we find one, return the new, valid address.
5795 This is used from only one place: `memory_address' in explow.c.
5797 OLDX is the address as it was before break_out_memory_refs was
5798 called. In some cases it is useful to look at this to decide what
5801 It is always safe for this function to do nothing. It exists to
5802 recognize opportunities to optimize the output.
5804 On RS/6000, first check for the sum of a register with a constant
5805 integer that is out of range. If so, generate code to add the
5806 constant with the low-order 16 bits masked to the register and force
5807 this result into another register (this can be done with `cau').
5808 Then generate an address of REG+(CONST&0xffff), allowing for the
5809 possibility of bit 16 being a one.
5811 Then check for the sum of a register and something not constant, try to
5812 load the other things into a register and return the sum. */
5815 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5816 enum machine_mode mode)
5818 unsigned int extra = 0;
5820 if (!reg_offset_addressing_ok_p (mode))
5822 if (virtual_stack_registers_memory_p (x))
5825 /* In theory we should not be seeing addresses of the form reg+0,
5826 but just in case it is generated, optimize it away. */
5827 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5828 return force_reg (Pmode, XEXP (x, 0));
5830 /* Make sure both operands are registers. */
5831 else if (GET_CODE (x) == PLUS)
5832 return gen_rtx_PLUS (Pmode,
5833 force_reg (Pmode, XEXP (x, 0)),
5834 force_reg (Pmode, XEXP (x, 1)));
5836 return force_reg (Pmode, x);
5838 if (GET_CODE (x) == SYMBOL_REF)
5840 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5842 return rs6000_legitimize_tls_address (x, model);
5852 if (!TARGET_POWERPC64)
5860 extra = TARGET_POWERPC64 ? 8 : 12;
5866 if (GET_CODE (x) == PLUS
5867 && GET_CODE (XEXP (x, 0)) == REG
5868 && GET_CODE (XEXP (x, 1)) == CONST_INT
5869 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5871 && !((TARGET_POWERPC64
5872 && (mode == DImode || mode == TImode)
5873 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5874 || SPE_VECTOR_MODE (mode)
5875 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5876 || mode == DImode || mode == DDmode
5877 || mode == TDmode))))
5879 HOST_WIDE_INT high_int, low_int;
5881 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5882 if (low_int >= 0x8000 - extra)
5884 high_int = INTVAL (XEXP (x, 1)) - low_int;
5885 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5886 GEN_INT (high_int)), 0);
5887 return plus_constant (sum, low_int);
5889 else if (GET_CODE (x) == PLUS
5890 && GET_CODE (XEXP (x, 0)) == REG
5891 && GET_CODE (XEXP (x, 1)) != CONST_INT
5892 && GET_MODE_NUNITS (mode) == 1
5893 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5895 || ((mode != DImode && mode != DFmode && mode != DDmode)
5896 || (TARGET_E500_DOUBLE && mode != DDmode)))
5897 && (TARGET_POWERPC64 || mode != DImode)
5898 && !avoiding_indexed_address_p (mode)
5903 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5904 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5906 else if (SPE_VECTOR_MODE (mode)
5907 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5908 || mode == DDmode || mode == TDmode
5909 || mode == DImode)))
5913 /* We accept [reg + reg] and [reg + OFFSET]. */
5915 if (GET_CODE (x) == PLUS)
5917 rtx op1 = XEXP (x, 0);
5918 rtx op2 = XEXP (x, 1);
5921 op1 = force_reg (Pmode, op1);
5923 if (GET_CODE (op2) != REG
5924 && (GET_CODE (op2) != CONST_INT
5925 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5926 || (GET_MODE_SIZE (mode) > 8
5927 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5928 op2 = force_reg (Pmode, op2);
5930 /* We can't always do [reg + reg] for these, because [reg +
5931 reg + offset] is not a legitimate addressing mode. */
5932 y = gen_rtx_PLUS (Pmode, op1, op2);
5934 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5935 return force_reg (Pmode, y);
5940 return force_reg (Pmode, x);
5946 && GET_CODE (x) != CONST_INT
5947 && GET_CODE (x) != CONST_DOUBLE
5949 && GET_MODE_NUNITS (mode) == 1
5950 && (GET_MODE_BITSIZE (mode) <= 32
5951 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5952 && (mode == DFmode || mode == DDmode))))
5954 rtx reg = gen_reg_rtx (Pmode);
5955 emit_insn (gen_elf_high (reg, x));
5956 return gen_rtx_LO_SUM (Pmode, reg, x);
5958 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5961 && ! MACHO_DYNAMIC_NO_PIC_P
5963 && GET_CODE (x) != CONST_INT
5964 && GET_CODE (x) != CONST_DOUBLE
5966 && GET_MODE_NUNITS (mode) == 1
5967 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5968 || (mode != DFmode && mode != DDmode))
5972 rtx reg = gen_reg_rtx (Pmode);
5973 emit_insn (gen_macho_high (reg, x));
5974 return gen_rtx_LO_SUM (Pmode, reg, x);
5977 && GET_CODE (x) == SYMBOL_REF
5978 && constant_pool_expr_p (x)
5979 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5981 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5982 return create_TOC_reference (x, reg);
5988 /* Debug version of rs6000_legitimize_address. */
5990 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5996 ret = rs6000_legitimize_address (x, oldx, mode);
5997 insns = get_insns ();
6003 "\nrs6000_legitimize_address: mode %s, old code %s, "
6004 "new code %s, modified\n",
6005 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6006 GET_RTX_NAME (GET_CODE (ret)));
6008 fprintf (stderr, "Original address:\n");
6011 fprintf (stderr, "oldx:\n");
6014 fprintf (stderr, "New address:\n");
6019 fprintf (stderr, "Insns added:\n");
6020 debug_rtx_list (insns, 20);
6026 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6027 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6038 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6039 We need to emit DTP-relative relocations. */
6042 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6047 fputs ("\t.long\t", file);
6050 fputs (DOUBLE_INT_ASM_OP, file);
6055 output_addr_const (file, x);
6056 fputs ("@dtprel+0x8000", file);
6059 /* In the name of slightly smaller debug output, and to cater to
6060 general assembler lossage, recognize various UNSPEC sequences
6061 and turn them back into a direct symbol reference. */
6064 rs6000_delegitimize_address (rtx orig_x)
6068 orig_x = delegitimize_mem_from_attrs (orig_x);
6073 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6074 && GET_CODE (XEXP (x, 1)) == CONST)
6076 rtx offset = NULL_RTX;
6078 y = XEXP (XEXP (x, 1), 0);
6079 if (GET_CODE (y) == PLUS
6080 && GET_MODE (y) == Pmode
6081 && CONST_INT_P (XEXP (y, 1)))
6083 offset = XEXP (y, 1);
6086 if (GET_CODE (y) == UNSPEC
6087 && XINT (y, 1) == UNSPEC_TOCREL
6088 && ((GET_CODE (XEXP (x, 0)) == REG
6089 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6090 || TARGET_MINIMAL_TOC
6091 || TARGET_CMODEL != CMODEL_SMALL))
6092 || (TARGET_CMODEL != CMODEL_SMALL
6093 && GET_CODE (XEXP (x, 0)) == PLUS
6094 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6095 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6096 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6097 && rtx_equal_p (XEXP (x, 1),
6098 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6100 y = XVECEXP (y, 0, 0);
6101 if (offset != NULL_RTX)
6102 y = gen_rtx_PLUS (Pmode, y, offset);
6103 if (!MEM_P (orig_x))
6106 return replace_equiv_address_nv (orig_x, y);
6111 && GET_CODE (orig_x) == LO_SUM
6112 && GET_CODE (XEXP (orig_x, 1)) == CONST)
6114 y = XEXP (XEXP (orig_x, 1), 0);
6115 if (GET_CODE (y) == UNSPEC
6116 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6117 return XVECEXP (y, 0, 0);
6123 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6125 static GTY(()) rtx rs6000_tls_symbol;
6127 rs6000_tls_get_addr (void)
6129 if (!rs6000_tls_symbol)
6130 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6132 return rs6000_tls_symbol;
6135 /* Construct the SYMBOL_REF for TLS GOT references. */
6137 static GTY(()) rtx rs6000_got_symbol;
6139 rs6000_got_sym (void)
6141 if (!rs6000_got_symbol)
6143 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6144 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6145 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6148 return rs6000_got_symbol;
6151 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6152 this (thread-local) address. */
6155 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6159 dest = gen_reg_rtx (Pmode);
6160 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6166 tlsreg = gen_rtx_REG (Pmode, 13);
6167 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6171 tlsreg = gen_rtx_REG (Pmode, 2);
6172 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6176 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6180 tmp = gen_reg_rtx (Pmode);
6183 tlsreg = gen_rtx_REG (Pmode, 13);
6184 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6188 tlsreg = gen_rtx_REG (Pmode, 2);
6189 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6193 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6195 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6200 rtx r3, got, tga, tmp1, tmp2, call_insn;
6202 /* We currently use relocations like @got@tlsgd for tls, which
6203 means the linker will handle allocation of tls entries, placing
6204 them in the .got section. So use a pointer to the .got section,
6205 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6206 or to secondary GOT sections used by 32-bit -fPIC. */
6208 got = gen_rtx_REG (Pmode, 2);
6212 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6215 rtx gsym = rs6000_got_sym ();
6216 got = gen_reg_rtx (Pmode);
6218 rs6000_emit_move (got, gsym, Pmode);
6223 tmp1 = gen_reg_rtx (Pmode);
6224 tmp2 = gen_reg_rtx (Pmode);
6225 mem = gen_const_mem (Pmode, tmp1);
6226 lab = gen_label_rtx ();
6227 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6228 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6229 emit_move_insn (tmp2, mem);
6230 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6231 set_unique_reg_note (last, REG_EQUAL, gsym);
6236 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6238 tga = rs6000_tls_get_addr ();
6239 emit_library_call_value (tga, dest, LCT_CONST, Pmode,
6240 1, const0_rtx, Pmode);
6242 r3 = gen_rtx_REG (Pmode, 3);
6243 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6244 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6245 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6246 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6247 else if (DEFAULT_ABI == ABI_V4)
6248 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6251 call_insn = last_call_insn ();
6252 PATTERN (call_insn) = insn;
6253 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6254 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6255 pic_offset_table_rtx);
6257 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6259 tga = rs6000_tls_get_addr ();
6260 tmp1 = gen_reg_rtx (Pmode);
6261 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
6262 1, const0_rtx, Pmode);
6264 r3 = gen_rtx_REG (Pmode, 3);
6265 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6266 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6267 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6268 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6269 else if (DEFAULT_ABI == ABI_V4)
6270 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6273 call_insn = last_call_insn ();
6274 PATTERN (call_insn) = insn;
6275 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6276 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6277 pic_offset_table_rtx);
6279 if (rs6000_tls_size == 16)
6282 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6284 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6286 else if (rs6000_tls_size == 32)
6288 tmp2 = gen_reg_rtx (Pmode);
6290 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6292 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6295 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6297 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6301 tmp2 = gen_reg_rtx (Pmode);
6303 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6305 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6307 insn = gen_rtx_SET (Pmode, dest,
6308 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6314 /* IE, or 64-bit offset LE. */
6315 tmp2 = gen_reg_rtx (Pmode);
6317 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6319 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6322 insn = gen_tls_tls_64 (dest, tmp2, addr);
6324 insn = gen_tls_tls_32 (dest, tmp2, addr);
6332 /* Return 1 if X contains a thread-local symbol. */
6335 rs6000_tls_referenced_p (rtx x)
6337 if (! TARGET_HAVE_TLS)
6340 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6343 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6346 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
6348 return rs6000_tls_referenced_p (x);
6351 /* Return 1 if *X is a thread-local symbol. This is the same as
6352 rs6000_tls_symbol_ref except for the type of the unused argument. */
6355 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6357 return RS6000_SYMBOL_REF_TLS_P (*x);
6360 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6361 replace the input X, or the original X if no replacement is called for.
6362 The output parameter *WIN is 1 if the calling macro should goto WIN,
6365 For RS/6000, we wish to handle large displacements off a base
6366 register by splitting the addend across an addiu/addis and the mem insn.
6367 This cuts number of extra insns needed from 3 to 1.
6369 On Darwin, we use this to generate code for floating point constants.
6370 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6371 The Darwin code is inside #if TARGET_MACHO because only then are the
6372 machopic_* functions defined. */
6374 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6375 int opnum, int type,
6376 int ind_levels ATTRIBUTE_UNUSED, int *win)
6378 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6380 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6381 DFmode/DImode MEM. */
6384 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6385 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6386 reg_offset_p = false;
6388 /* We must recognize output that we have already generated ourselves. */
6389 if (GET_CODE (x) == PLUS
6390 && GET_CODE (XEXP (x, 0)) == PLUS
6391 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6392 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6393 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6395 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6396 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6397 opnum, (enum reload_type)type);
6402 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6403 if (GET_CODE (x) == LO_SUM
6404 && GET_CODE (XEXP (x, 0)) == HIGH)
6406 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6407 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6408 opnum, (enum reload_type)type);
6414 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6415 && GET_CODE (x) == LO_SUM
6416 && GET_CODE (XEXP (x, 0)) == PLUS
6417 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6418 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6419 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6420 && machopic_operand_p (XEXP (x, 1)))
6422 /* Result of previous invocation of this function on Darwin
6423 floating point constant. */
6424 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6425 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6426 opnum, (enum reload_type)type);
6432 if (TARGET_CMODEL != CMODEL_SMALL
6433 && GET_CODE (x) == LO_SUM
6434 && GET_CODE (XEXP (x, 0)) == PLUS
6435 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6436 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6437 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6438 && GET_CODE (XEXP (x, 1)) == CONST
6439 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6440 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6441 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6443 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6444 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6445 opnum, (enum reload_type) type);
6450 /* Force ld/std non-word aligned offset into base register by wrapping
6452 if (GET_CODE (x) == PLUS
6453 && GET_CODE (XEXP (x, 0)) == REG
6454 && REGNO (XEXP (x, 0)) < 32
6455 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6456 && GET_CODE (XEXP (x, 1)) == CONST_INT
6458 && (INTVAL (XEXP (x, 1)) & 3) != 0
6459 && VECTOR_MEM_NONE_P (mode)
6460 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6461 && TARGET_POWERPC64)
6463 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6464 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6465 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6466 opnum, (enum reload_type) type);
6471 if (GET_CODE (x) == PLUS
6472 && GET_CODE (XEXP (x, 0)) == REG
6473 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6474 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6475 && GET_CODE (XEXP (x, 1)) == CONST_INT
6477 && !SPE_VECTOR_MODE (mode)
6478 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6479 || mode == DDmode || mode == TDmode
6481 && VECTOR_MEM_NONE_P (mode))
6483 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6484 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6486 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6488 /* Check for 32-bit overflow. */
6489 if (high + low != val)
6495 /* Reload the high part into a base reg; leave the low part
6496 in the mem directly. */
6498 x = gen_rtx_PLUS (GET_MODE (x),
6499 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6503 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6504 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6505 opnum, (enum reload_type)type);
6510 if (GET_CODE (x) == SYMBOL_REF
6512 && VECTOR_MEM_NONE_P (mode)
6513 && !SPE_VECTOR_MODE (mode)
6515 && DEFAULT_ABI == ABI_DARWIN
6516 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6518 && DEFAULT_ABI == ABI_V4
6521 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6522 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6526 && (mode != DImode || TARGET_POWERPC64)
6527 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6528 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6533 rtx offset = machopic_gen_offset (x);
6534 x = gen_rtx_LO_SUM (GET_MODE (x),
6535 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6536 gen_rtx_HIGH (Pmode, offset)), offset);
6540 x = gen_rtx_LO_SUM (GET_MODE (x),
6541 gen_rtx_HIGH (Pmode, x), x);
6543 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6544 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6545 opnum, (enum reload_type)type);
6550 /* Reload an offset address wrapped by an AND that represents the
6551 masking of the lower bits. Strip the outer AND and let reload
6552 convert the offset address into an indirect address. For VSX,
6553 force reload to create the address with an AND in a separate
6554 register, because we can't guarantee an altivec register will
6556 if (VECTOR_MEM_ALTIVEC_P (mode)
6557 && GET_CODE (x) == AND
6558 && GET_CODE (XEXP (x, 0)) == PLUS
6559 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6560 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6561 && GET_CODE (XEXP (x, 1)) == CONST_INT
6562 && INTVAL (XEXP (x, 1)) == -16)
6571 && GET_CODE (x) == SYMBOL_REF
6572 && constant_pool_expr_p (x)
6573 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6575 x = create_TOC_reference (x, NULL_RTX);
6576 if (TARGET_CMODEL != CMODEL_SMALL)
6577 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6578 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6579 opnum, (enum reload_type) type);
6587 /* Debug version of rs6000_legitimize_reload_address. */
6589 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6590 int opnum, int type,
6591 int ind_levels, int *win)
6593 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6596 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6597 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6598 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6602 fprintf (stderr, "Same address returned\n");
6604 fprintf (stderr, "NULL returned\n");
6607 fprintf (stderr, "New address:\n");
6614 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6615 that is a valid memory address for an instruction.
6616 The MODE argument is the machine mode for the MEM expression
6617 that wants to use this address.
6619 On the RS/6000, there are four valid address: a SYMBOL_REF that
6620 refers to a constant pool entry of an address (or the sum of it
6621 plus a constant), a short (16-bit signed) constant plus a register,
6622 the sum of two registers, or a register indirect, possibly with an
6623 auto-increment. For DFmode, DDmode and DImode with a constant plus
6624 register, we must ensure that both words are addressable or PowerPC64
6625 with offset word aligned.
6627 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6628 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6629 because adjacent memory cells are accessed by adding word-sized offsets
6630 during assembly output. */
6632 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6634 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6636 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6637 if (VECTOR_MEM_ALTIVEC_P (mode)
6638 && GET_CODE (x) == AND
6639 && GET_CODE (XEXP (x, 1)) == CONST_INT
6640 && INTVAL (XEXP (x, 1)) == -16)
6643 if (RS6000_SYMBOL_REF_TLS_P (x))
6645 if (legitimate_indirect_address_p (x, reg_ok_strict))
6647 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6648 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6649 && !SPE_VECTOR_MODE (mode)
6652 /* Restrict addressing for DI because of our SUBREG hackery. */
6653 && !(TARGET_E500_DOUBLE
6654 && (mode == DFmode || mode == DDmode || mode == DImode))
6656 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6658 if (virtual_stack_registers_memory_p (x))
6660 if (reg_offset_p && legitimate_small_data_p (mode, x))
6663 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6665 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6668 && GET_CODE (x) == PLUS
6669 && GET_CODE (XEXP (x, 0)) == REG
6670 && (XEXP (x, 0) == virtual_stack_vars_rtx
6671 || XEXP (x, 0) == arg_pointer_rtx)
6672 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6674 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6679 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6681 || (mode != DFmode && mode != DDmode)
6682 || (TARGET_E500_DOUBLE && mode != DDmode))
6683 && (TARGET_POWERPC64 || mode != DImode)
6684 && !avoiding_indexed_address_p (mode)
6685 && legitimate_indexed_address_p (x, reg_ok_strict))
6687 if (GET_CODE (x) == PRE_MODIFY
6691 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6693 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6694 && (TARGET_POWERPC64 || mode != DImode)
6695 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6696 && !SPE_VECTOR_MODE (mode)
6697 /* Restrict addressing for DI because of our SUBREG hackery. */
6698 && !(TARGET_E500_DOUBLE
6699 && (mode == DFmode || mode == DDmode || mode == DImode))
6701 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6702 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6703 || (!avoiding_indexed_address_p (mode)
6704 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6705 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6707 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6712 /* Debug version of rs6000_legitimate_address_p. */
6714 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6717 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6719 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6720 "strict = %d, code = %s\n",
6721 ret ? "true" : "false",
6722 GET_MODE_NAME (mode),
6724 GET_RTX_NAME (GET_CODE (x)));
6730 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6733 rs6000_mode_dependent_address_p (const_rtx addr)
6735 return rs6000_mode_dependent_address_ptr (addr);
6738 /* Go to LABEL if ADDR (a legitimate address expression)
6739 has an effect that depends on the machine mode it is used for.
6741 On the RS/6000 this is true of all integral offsets (since AltiVec
6742 and VSX modes don't allow them) or is a pre-increment or decrement.
6744 ??? Except that due to conceptual problems in offsettable_address_p
6745 we can't really report the problems of integral offsets. So leave
6746 this assuming that the adjustable offset must be valid for the
6747 sub-words of a TFmode operand, which is what we had before. */
6750 rs6000_mode_dependent_address (const_rtx addr)
6752 switch (GET_CODE (addr))
6755 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6756 is considered a legitimate address before reload, so there
6757 are no offset restrictions in that case. Note that this
6758 condition is safe in strict mode because any address involving
6759 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6760 been rejected as illegitimate. */
6761 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6762 && XEXP (addr, 0) != arg_pointer_rtx
6763 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6765 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6766 return val + 12 + 0x8000 >= 0x10000;
6771 /* Anything in the constant pool is sufficiently aligned that
6772 all bytes have the same high part address. */
6773 return !legitimate_constant_pool_address_p (addr, QImode, false);
6775 /* Auto-increment cases are now treated generically in recog.c. */
6777 return TARGET_UPDATE;
6779 /* AND is only allowed in Altivec loads. */
6790 /* Debug version of rs6000_mode_dependent_address. */
6792 rs6000_debug_mode_dependent_address (const_rtx addr)
6794 bool ret = rs6000_mode_dependent_address (addr);
6796 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6797 ret ? "true" : "false");
6803 /* Implement FIND_BASE_TERM. */
6806 rs6000_find_base_term (rtx op)
6810 split_const (op, &base, &offset);
6811 if (GET_CODE (base) == UNSPEC)
6812 switch (XINT (base, 1))
6815 case UNSPEC_MACHOPIC_OFFSET:
6816 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6817 for aliasing purposes. */
6818 return XVECEXP (base, 0, 0);
6824 /* More elaborate version of recog's offsettable_memref_p predicate
6825 that works around the ??? note of rs6000_mode_dependent_address.
6826 In particular it accepts
6828 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6830 in 32-bit mode, that the recog predicate rejects. */
6833 rs6000_offsettable_memref_p (rtx op)
6838 /* First mimic offsettable_memref_p. */
6839 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6842 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6843 the latter predicate knows nothing about the mode of the memory
6844 reference and, therefore, assumes that it is the largest supported
6845 mode (TFmode). As a consequence, legitimate offsettable memory
6846 references are rejected. rs6000_legitimate_offset_address_p contains
6847 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6848 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6851 /* Change register usage conditional on target flags. */
6853 rs6000_conditional_register_usage (void)
6857 if (TARGET_DEBUG_TARGET)
6858 fprintf (stderr, "rs6000_conditional_register_usage called\n");
6860 /* Set MQ register fixed (already call_used) if not POWER
6861 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6866 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6868 fixed_regs[13] = call_used_regs[13]
6869 = call_really_used_regs[13] = 1;
6871 /* Conditionally disable FPRs. */
6872 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6873 for (i = 32; i < 64; i++)
6874 fixed_regs[i] = call_used_regs[i]
6875 = call_really_used_regs[i] = 1;
6877 /* The TOC register is not killed across calls in a way that is
6878 visible to the compiler. */
6879 if (DEFAULT_ABI == ABI_AIX)
6880 call_really_used_regs[2] = 0;
6882 if (DEFAULT_ABI == ABI_V4
6883 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6885 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6887 if (DEFAULT_ABI == ABI_V4
6888 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6890 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6891 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6892 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6894 if (DEFAULT_ABI == ABI_DARWIN
6895 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6896 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6897 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6898 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6900 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6901 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6902 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6906 global_regs[SPEFSCR_REGNO] = 1;
6907 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6908 registers in prologues and epilogues. We no longer use r14
6909 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6910 pool for link-compatibility with older versions of GCC. Once
6911 "old" code has died out, we can return r14 to the allocation
6914 = call_used_regs[14]
6915 = call_really_used_regs[14] = 1;
6918 if (!TARGET_ALTIVEC && !TARGET_VSX)
6920 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6921 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6922 call_really_used_regs[VRSAVE_REGNO] = 1;
6925 if (TARGET_ALTIVEC || TARGET_VSX)
6926 global_regs[VSCR_REGNO] = 1;
6928 if (TARGET_ALTIVEC_ABI)
6930 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6931 call_used_regs[i] = call_really_used_regs[i] = 1;
6933 /* AIX reserves VR20:31 in non-extended ABI mode. */
6935 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6936 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6940 /* Try to output insns to set TARGET equal to the constant C if it can
6941 be done in less than N insns. Do all computations in MODE.
6942 Returns the place where the output has been placed if it can be
6943 done and the insns have been emitted. If it would take more than N
6944 insns, zero is returned and no insns and emitted. */
6947 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6948 rtx source, int n ATTRIBUTE_UNUSED)
6950 rtx result, insn, set;
6951 HOST_WIDE_INT c0, c1;
6958 dest = gen_reg_rtx (mode);
6959 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6963 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6965 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6966 GEN_INT (INTVAL (source)
6967 & (~ (HOST_WIDE_INT) 0xffff))));
6968 emit_insn (gen_rtx_SET (VOIDmode, dest,
6969 gen_rtx_IOR (SImode, copy_rtx (result),
6970 GEN_INT (INTVAL (source) & 0xffff))));
6975 switch (GET_CODE (source))
6978 c0 = INTVAL (source);
6983 #if HOST_BITS_PER_WIDE_INT >= 64
6984 c0 = CONST_DOUBLE_LOW (source);
6987 c0 = CONST_DOUBLE_LOW (source);
6988 c1 = CONST_DOUBLE_HIGH (source);
6996 result = rs6000_emit_set_long_const (dest, c0, c1);
7003 insn = get_last_insn ();
7004 set = single_set (insn);
7005 if (! CONSTANT_P (SET_SRC (set)))
7006 set_unique_reg_note (insn, REG_EQUAL, source);
7011 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7012 fall back to a straight forward decomposition. We do this to avoid
7013 exponential run times encountered when looking for longer sequences
7014 with rs6000_emit_set_const. */
7016 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7018 if (!TARGET_POWERPC64)
7020 rtx operand1, operand2;
7022 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7024 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7026 emit_move_insn (operand1, GEN_INT (c1));
7027 emit_move_insn (operand2, GEN_INT (c2));
7031 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7034 ud2 = (c1 & 0xffff0000) >> 16;
7035 #if HOST_BITS_PER_WIDE_INT >= 64
7039 ud4 = (c2 & 0xffff0000) >> 16;
7041 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7042 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7045 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7047 emit_move_insn (dest, GEN_INT (ud1));
7050 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7051 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7054 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7057 emit_move_insn (dest, GEN_INT (ud2 << 16));
7059 emit_move_insn (copy_rtx (dest),
7060 gen_rtx_IOR (DImode, copy_rtx (dest),
7063 else if (ud3 == 0 && ud4 == 0)
7065 gcc_assert (ud2 & 0x8000);
7066 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7069 emit_move_insn (copy_rtx (dest),
7070 gen_rtx_IOR (DImode, copy_rtx (dest),
7072 emit_move_insn (copy_rtx (dest),
7073 gen_rtx_ZERO_EXTEND (DImode,
7074 gen_lowpart (SImode,
7077 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7078 || (ud4 == 0 && ! (ud3 & 0x8000)))
7081 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7084 emit_move_insn (dest, GEN_INT (ud3 << 16));
7087 emit_move_insn (copy_rtx (dest),
7088 gen_rtx_IOR (DImode, copy_rtx (dest),
7090 emit_move_insn (copy_rtx (dest),
7091 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7094 emit_move_insn (copy_rtx (dest),
7095 gen_rtx_IOR (DImode, copy_rtx (dest),
7101 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7104 emit_move_insn (dest, GEN_INT (ud4 << 16));
7107 emit_move_insn (copy_rtx (dest),
7108 gen_rtx_IOR (DImode, copy_rtx (dest),
7111 emit_move_insn (copy_rtx (dest),
7112 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7115 emit_move_insn (copy_rtx (dest),
7116 gen_rtx_IOR (DImode, copy_rtx (dest),
7117 GEN_INT (ud2 << 16)));
7119 emit_move_insn (copy_rtx (dest),
7120 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7126 /* Helper for the following. Get rid of [r+r] memory refs
7127 in cases where it won't work (TImode, TFmode, TDmode). */
7130 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7132 if (reload_in_progress)
7135 if (GET_CODE (operands[0]) == MEM
7136 && GET_CODE (XEXP (operands[0], 0)) != REG
7137 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7138 GET_MODE (operands[0]), false))
7140 = replace_equiv_address (operands[0],
7141 copy_addr_to_reg (XEXP (operands[0], 0)));
7143 if (GET_CODE (operands[1]) == MEM
7144 && GET_CODE (XEXP (operands[1], 0)) != REG
7145 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7146 GET_MODE (operands[1]), false))
7148 = replace_equiv_address (operands[1],
7149 copy_addr_to_reg (XEXP (operands[1], 0)));
7152 /* Emit a move from SOURCE to DEST in mode MODE. */
7154 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7158 operands[1] = source;
7160 if (TARGET_DEBUG_ADDR)
7163 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7164 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7165 GET_MODE_NAME (mode),
7168 can_create_pseudo_p ());
7170 fprintf (stderr, "source:\n");
7174 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7175 if (GET_CODE (operands[1]) == CONST_DOUBLE
7176 && ! FLOAT_MODE_P (mode)
7177 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7179 /* FIXME. This should never happen. */
7180 /* Since it seems that it does, do the safe thing and convert
7182 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7184 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7185 || FLOAT_MODE_P (mode)
7186 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7187 || CONST_DOUBLE_LOW (operands[1]) < 0)
7188 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7189 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7191 /* Check if GCC is setting up a block move that will end up using FP
7192 registers as temporaries. We must make sure this is acceptable. */
7193 if (GET_CODE (operands[0]) == MEM
7194 && GET_CODE (operands[1]) == MEM
7196 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7197 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7198 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7199 ? 32 : MEM_ALIGN (operands[0])))
7200 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7202 : MEM_ALIGN (operands[1]))))
7203 && ! MEM_VOLATILE_P (operands [0])
7204 && ! MEM_VOLATILE_P (operands [1]))
7206 emit_move_insn (adjust_address (operands[0], SImode, 0),
7207 adjust_address (operands[1], SImode, 0));
7208 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7209 adjust_address (copy_rtx (operands[1]), SImode, 4));
7213 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7214 && !gpc_reg_operand (operands[1], mode))
7215 operands[1] = force_reg (mode, operands[1]);
7217 if (mode == SFmode && ! TARGET_POWERPC
7218 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7219 && GET_CODE (operands[0]) == MEM)
7223 if (reload_in_progress || reload_completed)
7224 regnum = true_regnum (operands[1]);
7225 else if (GET_CODE (operands[1]) == REG)
7226 regnum = REGNO (operands[1]);
7230 /* If operands[1] is a register, on POWER it may have
7231 double-precision data in it, so truncate it to single
7233 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7236 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7237 : gen_reg_rtx (mode));
7238 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7239 operands[1] = newreg;
7243 /* Recognize the case where operand[1] is a reference to thread-local
7244 data and load its address to a register. */
7245 if (rs6000_tls_referenced_p (operands[1]))
7247 enum tls_model model;
7248 rtx tmp = operands[1];
7251 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7253 addend = XEXP (XEXP (tmp, 0), 1);
7254 tmp = XEXP (XEXP (tmp, 0), 0);
7257 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7258 model = SYMBOL_REF_TLS_MODEL (tmp);
7259 gcc_assert (model != 0);
7261 tmp = rs6000_legitimize_tls_address (tmp, model);
7264 tmp = gen_rtx_PLUS (mode, tmp, addend);
7265 tmp = force_operand (tmp, operands[0]);
7270 /* Handle the case where reload calls us with an invalid address. */
7271 if (reload_in_progress && mode == Pmode
7272 && (! general_operand (operands[1], mode)
7273 || ! nonimmediate_operand (operands[0], mode)))
7276 /* 128-bit constant floating-point values on Darwin should really be
7277 loaded as two parts. */
7278 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7279 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7281 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7282 know how to get a DFmode SUBREG of a TFmode. */
7283 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7284 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7285 simplify_gen_subreg (imode, operands[1], mode, 0),
7287 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7288 GET_MODE_SIZE (imode)),
7289 simplify_gen_subreg (imode, operands[1], mode,
7290 GET_MODE_SIZE (imode)),
7295 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7296 cfun->machine->sdmode_stack_slot =
7297 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7299 if (reload_in_progress
7301 && MEM_P (operands[0])
7302 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7303 && REG_P (operands[1]))
7305 if (FP_REGNO_P (REGNO (operands[1])))
7307 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7308 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7309 emit_insn (gen_movsd_store (mem, operands[1]));
7311 else if (INT_REGNO_P (REGNO (operands[1])))
7313 rtx mem = adjust_address_nv (operands[0], mode, 4);
7314 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7315 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7321 if (reload_in_progress
7323 && REG_P (operands[0])
7324 && MEM_P (operands[1])
7325 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7327 if (FP_REGNO_P (REGNO (operands[0])))
7329 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7330 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7331 emit_insn (gen_movsd_load (operands[0], mem));
7333 else if (INT_REGNO_P (REGNO (operands[0])))
7335 rtx mem = adjust_address_nv (operands[1], mode, 4);
7336 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7337 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7344 /* FIXME: In the long term, this switch statement should go away
7345 and be replaced by a sequence of tests based on things like
7351 if (CONSTANT_P (operands[1])
7352 && GET_CODE (operands[1]) != CONST_INT)
7353 operands[1] = force_const_mem (mode, operands[1]);
7358 rs6000_eliminate_indexed_memrefs (operands);
7365 if (CONSTANT_P (operands[1])
7366 && ! easy_fp_constant (operands[1], mode))
7367 operands[1] = force_const_mem (mode, operands[1]);
7380 if (CONSTANT_P (operands[1])
7381 && !easy_vector_constant (operands[1], mode))
7382 operands[1] = force_const_mem (mode, operands[1]);
7387 /* Use default pattern for address of ELF small data */
7390 && DEFAULT_ABI == ABI_V4
7391 && (GET_CODE (operands[1]) == SYMBOL_REF
7392 || GET_CODE (operands[1]) == CONST)
7393 && small_data_operand (operands[1], mode))
7395 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7399 if (DEFAULT_ABI == ABI_V4
7400 && mode == Pmode && mode == SImode
7401 && flag_pic == 1 && got_operand (operands[1], mode))
7403 emit_insn (gen_movsi_got (operands[0], operands[1]));
7407 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7411 && CONSTANT_P (operands[1])
7412 && GET_CODE (operands[1]) != HIGH
7413 && GET_CODE (operands[1]) != CONST_INT)
7415 rtx target = (!can_create_pseudo_p ()
7417 : gen_reg_rtx (mode));
7419 /* If this is a function address on -mcall-aixdesc,
7420 convert it to the address of the descriptor. */
7421 if (DEFAULT_ABI == ABI_AIX
7422 && GET_CODE (operands[1]) == SYMBOL_REF
7423 && XSTR (operands[1], 0)[0] == '.')
7425 const char *name = XSTR (operands[1], 0);
7427 while (*name == '.')
7429 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7430 CONSTANT_POOL_ADDRESS_P (new_ref)
7431 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7432 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7433 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7434 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7435 operands[1] = new_ref;
7438 if (DEFAULT_ABI == ABI_DARWIN)
7441 if (MACHO_DYNAMIC_NO_PIC_P)
7443 /* Take care of any required data indirection. */
7444 operands[1] = rs6000_machopic_legitimize_pic_address (
7445 operands[1], mode, operands[0]);
7446 if (operands[0] != operands[1])
7447 emit_insn (gen_rtx_SET (VOIDmode,
7448 operands[0], operands[1]));
7452 emit_insn (gen_macho_high (target, operands[1]));
7453 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7457 emit_insn (gen_elf_high (target, operands[1]));
7458 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7462 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7463 and we have put it in the TOC, we just need to make a TOC-relative
7466 && GET_CODE (operands[1]) == SYMBOL_REF
7467 && constant_pool_expr_p (operands[1])
7468 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7469 get_pool_mode (operands[1])))
7470 || (TARGET_CMODEL == CMODEL_MEDIUM
7471 && GET_CODE (operands[1]) == SYMBOL_REF
7472 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7473 && SYMBOL_REF_LOCAL_P (operands[1])))
7476 if (TARGET_CMODEL != CMODEL_SMALL)
7478 if (can_create_pseudo_p ())
7479 reg = gen_reg_rtx (Pmode);
7483 operands[1] = create_TOC_reference (operands[1], reg);
7485 else if (mode == Pmode
7486 && CONSTANT_P (operands[1])
7487 && ((GET_CODE (operands[1]) != CONST_INT
7488 && ! easy_fp_constant (operands[1], mode))
7489 || (GET_CODE (operands[1]) == CONST_INT
7490 && (num_insns_constant (operands[1], mode)
7491 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7492 || (GET_CODE (operands[0]) == REG
7493 && FP_REGNO_P (REGNO (operands[0]))))
7494 && GET_CODE (operands[1]) != HIGH
7495 && ! legitimate_constant_pool_address_p (operands[1], mode,
7497 && ! toc_relative_expr_p (operands[1])
7498 && (TARGET_CMODEL == CMODEL_SMALL
7499 || can_create_pseudo_p ()
7500 || (REG_P (operands[0])
7501 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7505 /* Darwin uses a special PIC legitimizer. */
7506 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7509 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7511 if (operands[0] != operands[1])
7512 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7517 /* If we are to limit the number of things we put in the TOC and
7518 this is a symbol plus a constant we can add in one insn,
7519 just put the symbol in the TOC and add the constant. Don't do
7520 this if reload is in progress. */
7521 if (GET_CODE (operands[1]) == CONST
7522 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7523 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7524 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7525 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7526 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7527 && ! side_effects_p (operands[0]))
7530 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7531 rtx other = XEXP (XEXP (operands[1], 0), 1);
7533 sym = force_reg (mode, sym);
7534 emit_insn (gen_add3_insn (operands[0], sym, other));
7538 operands[1] = force_const_mem (mode, operands[1]);
7541 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7542 && constant_pool_expr_p (XEXP (operands[1], 0))
7543 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7544 get_pool_constant (XEXP (operands[1], 0)),
7545 get_pool_mode (XEXP (operands[1], 0))))
7549 if (TARGET_CMODEL != CMODEL_SMALL)
7551 if (can_create_pseudo_p ())
7552 reg = gen_reg_rtx (Pmode);
7556 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7557 operands[1] = gen_const_mem (mode, tocref);
7558 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7564 rs6000_eliminate_indexed_memrefs (operands);
7568 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7570 gen_rtx_SET (VOIDmode,
7571 operands[0], operands[1]),
7572 gen_rtx_CLOBBER (VOIDmode,
7573 gen_rtx_SCRATCH (SImode)))));
7579 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7582 /* Above, we may have called force_const_mem which may have returned
7583 an invalid address. If we can, fix this up; otherwise, reload will
7584 have to deal with it. */
7585 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7586 operands[1] = validize_mem (operands[1]);
7589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7592 /* Nonzero if we can use a floating-point register to pass this arg. */
7593 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7594 (SCALAR_FLOAT_MODE_P (MODE) \
7595 && (CUM)->fregno <= FP_ARG_MAX_REG \
7596 && TARGET_HARD_FLOAT && TARGET_FPRS)
7598 /* Nonzero if we can use an AltiVec register to pass this arg. */
7599 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7600 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7601 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7602 && TARGET_ALTIVEC_ABI \
7605 /* Return a nonzero value to say to return the function value in
7606 memory, just as large structures are always returned. TYPE will be
7607 the data type of the value, and FNTYPE will be the type of the
7608 function doing the returning, or @code{NULL} for libcalls.
7610 The AIX ABI for the RS/6000 specifies that all structures are
7611 returned in memory. The Darwin ABI does the same.
7613 For the Darwin 64 Bit ABI, a function result can be returned in
7614 registers or in memory, depending on the size of the return data
7615 type. If it is returned in registers, the value occupies the same
7616 registers as it would if it were the first and only function
7617 argument. Otherwise, the function places its result in memory at
7618 the location pointed to by GPR3.
7620 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7621 but a draft put them in memory, and GCC used to implement the draft
7622 instead of the final standard. Therefore, aix_struct_return
7623 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7624 compatibility can change DRAFT_V4_STRUCT_RET to override the
7625 default, and -m switches get the final word. See
7626 rs6000_option_override_internal for more details.
7628 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7629 long double support is enabled. These values are returned in memory.
7631 int_size_in_bytes returns -1 for variable size objects, which go in
7632 memory always. The cast to unsigned makes -1 > 8. */
7635 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7637 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7639 && rs6000_darwin64_abi
7640 && TREE_CODE (type) == RECORD_TYPE
7641 && int_size_in_bytes (type) > 0)
7643 CUMULATIVE_ARGS valcum;
7647 valcum.fregno = FP_ARG_MIN_REG;
7648 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7649 /* Do a trial code generation as if this were going to be passed
7650 as an argument; if any part goes in memory, we return NULL. */
7651 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7654 /* Otherwise fall through to more conventional ABI rules. */
7657 if (AGGREGATE_TYPE_P (type)
7658 && (aix_struct_return
7659 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7662 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7663 modes only exist for GCC vector types if -maltivec. */
7664 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7665 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7668 /* Return synthetic vectors in memory. */
7669 if (TREE_CODE (type) == VECTOR_TYPE
7670 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7672 static bool warned_for_return_big_vectors = false;
7673 if (!warned_for_return_big_vectors)
7675 warning (0, "GCC vector returned by reference: "
7676 "non-standard ABI extension with no compatibility guarantee");
7677 warned_for_return_big_vectors = true;
7682 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7688 #ifdef HAVE_AS_GNU_ATTRIBUTE
7689 /* Return TRUE if a call to function FNDECL may be one that
7690 potentially affects the function calling ABI of the object file. */
7693 call_ABI_of_interest (tree fndecl)
7695 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7697 struct cgraph_node *c_node;
7699 /* Libcalls are always interesting. */
7700 if (fndecl == NULL_TREE)
7703 /* Any call to an external function is interesting. */
7704 if (DECL_EXTERNAL (fndecl))
7707 /* Interesting functions that we are emitting in this object file. */
7708 c_node = cgraph_get_node (fndecl);
7709 return !cgraph_only_called_directly_p (c_node);
7715 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7716 for a call to a function whose data type is FNTYPE.
7717 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7719 For incoming args we set the number of arguments in the prototype large
7720 so we never return a PARALLEL. */
7723 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7724 rtx libname ATTRIBUTE_UNUSED, int incoming,
7725 int libcall, int n_named_args,
7726 tree fndecl ATTRIBUTE_UNUSED,
7727 enum machine_mode return_mode ATTRIBUTE_UNUSED)
7729 static CUMULATIVE_ARGS zero_cumulative;
7731 *cum = zero_cumulative;
7733 cum->fregno = FP_ARG_MIN_REG;
7734 cum->vregno = ALTIVEC_ARG_MIN_REG;
7735 cum->prototype = (fntype && prototype_p (fntype));
7736 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7737 ? CALL_LIBCALL : CALL_NORMAL);
7738 cum->sysv_gregno = GP_ARG_MIN_REG;
7739 cum->stdarg = stdarg_p (fntype);
7741 cum->nargs_prototype = 0;
7742 if (incoming || cum->prototype)
7743 cum->nargs_prototype = n_named_args;
7745 /* Check for a longcall attribute. */
7746 if ((!fntype && rs6000_default_long_calls)
7748 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7749 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7750 cum->call_cookie |= CALL_LONG;
7752 if (TARGET_DEBUG_ARG)
7754 fprintf (stderr, "\ninit_cumulative_args:");
7757 tree ret_type = TREE_TYPE (fntype);
7758 fprintf (stderr, " ret code = %s,",
7759 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7762 if (cum->call_cookie & CALL_LONG)
7763 fprintf (stderr, " longcall,");
7765 fprintf (stderr, " proto = %d, nargs = %d\n",
7766 cum->prototype, cum->nargs_prototype);
7769 #ifdef HAVE_AS_GNU_ATTRIBUTE
7770 if (DEFAULT_ABI == ABI_V4)
7772 cum->escapes = call_ABI_of_interest (fndecl);
7779 return_type = TREE_TYPE (fntype);
7780 return_mode = TYPE_MODE (return_type);
7783 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
7785 if (return_type != NULL)
7787 if (TREE_CODE (return_type) == RECORD_TYPE
7788 && TYPE_TRANSPARENT_AGGR (return_type))
7790 return_type = TREE_TYPE (first_field (return_type));
7791 return_mode = TYPE_MODE (return_type);
7793 if (AGGREGATE_TYPE_P (return_type)
7794 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
7796 rs6000_returns_struct = true;
7798 if (SCALAR_FLOAT_MODE_P (return_mode))
7799 rs6000_passes_float = true;
7800 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
7801 || SPE_VECTOR_MODE (return_mode))
7802 rs6000_passes_vector = true;
7809 && TARGET_ALTIVEC_ABI
7810 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7812 error ("cannot return value in vector register because"
7813 " altivec instructions are disabled, use -maltivec"
7818 /* Return true if TYPE must be passed on the stack and not in registers. */
7821 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7823 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7824 return must_pass_in_stack_var_size (mode, type);
7826 return must_pass_in_stack_var_size_or_pad (mode, type);
7829 /* If defined, a C expression which determines whether, and in which
7830 direction, to pad out an argument with extra space. The value
7831 should be of type `enum direction': either `upward' to pad above
7832 the argument, `downward' to pad below, or `none' to inhibit
7835 For the AIX ABI structs are always stored left shifted in their
7839 function_arg_padding (enum machine_mode mode, const_tree type)
7841 #ifndef AGGREGATE_PADDING_FIXED
7842 #define AGGREGATE_PADDING_FIXED 0
7844 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7845 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7848 if (!AGGREGATE_PADDING_FIXED)
7850 /* GCC used to pass structures of the same size as integer types as
7851 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7852 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7853 passed padded downward, except that -mstrict-align further
7854 muddied the water in that multi-component structures of 2 and 4
7855 bytes in size were passed padded upward.
7857 The following arranges for best compatibility with previous
7858 versions of gcc, but removes the -mstrict-align dependency. */
7859 if (BYTES_BIG_ENDIAN)
7861 HOST_WIDE_INT size = 0;
7863 if (mode == BLKmode)
7865 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7866 size = int_size_in_bytes (type);
7869 size = GET_MODE_SIZE (mode);
7871 if (size == 1 || size == 2 || size == 4)
7877 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7879 if (type != 0 && AGGREGATE_TYPE_P (type))
7883 /* Fall back to the default. */
7884 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7887 /* If defined, a C expression that gives the alignment boundary, in bits,
7888 of an argument with the specified mode and type. If it is not defined,
7889 PARM_BOUNDARY is used for all arguments.
7891 V.4 wants long longs and doubles to be double word aligned. Just
7892 testing the mode size is a boneheaded way to do this as it means
7893 that other types such as complex int are also double word aligned.
7894 However, we're stuck with this because changing the ABI might break
7895 existing library interfaces.
7897 Doubleword align SPE vectors.
7898 Quadword align Altivec/VSX vectors.
7899 Quadword align large synthetic vector types. */
7902 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
7904 if (DEFAULT_ABI == ABI_V4
7905 && (GET_MODE_SIZE (mode) == 8
7906 || (TARGET_HARD_FLOAT
7908 && (mode == TFmode || mode == TDmode))))
7910 else if (SPE_VECTOR_MODE (mode)
7911 || (type && TREE_CODE (type) == VECTOR_TYPE
7912 && int_size_in_bytes (type) >= 8
7913 && int_size_in_bytes (type) < 16))
7915 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
7916 || (type && TREE_CODE (type) == VECTOR_TYPE
7917 && int_size_in_bytes (type) >= 16))
7919 else if (TARGET_MACHO
7920 && rs6000_darwin64_abi
7922 && type && TYPE_ALIGN (type) > 64)
7925 return PARM_BOUNDARY;
7928 /* For a function parm of MODE and TYPE, return the starting word in
7929 the parameter area. NWORDS of the parameter area are already used. */
7932 rs6000_parm_start (enum machine_mode mode, const_tree type,
7933 unsigned int nwords)
7936 unsigned int parm_offset;
7938 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7939 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7940 return nwords + (-(parm_offset + nwords) & align);
7943 /* Compute the size (in words) of a function argument. */
7945 static unsigned long
7946 rs6000_arg_size (enum machine_mode mode, const_tree type)
7950 if (mode != BLKmode)
7951 size = GET_MODE_SIZE (mode);
7953 size = int_size_in_bytes (type);
7956 return (size + 3) >> 2;
7958 return (size + 7) >> 3;
7961 /* Use this to flush pending int fields. */
7964 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7965 HOST_WIDE_INT bitpos, int final)
7967 unsigned int startbit, endbit;
7968 int intregs, intoffset;
7969 enum machine_mode mode;
7971 /* Handle the situations where a float is taking up the first half
7972 of the GPR, and the other half is empty (typically due to
7973 alignment restrictions). We can detect this by a 8-byte-aligned
7974 int field, or by seeing that this is the final flush for this
7975 argument. Count the word and continue on. */
7976 if (cum->floats_in_gpr == 1
7977 && (cum->intoffset % 64 == 0
7978 || (cum->intoffset == -1 && final)))
7981 cum->floats_in_gpr = 0;
7984 if (cum->intoffset == -1)
7987 intoffset = cum->intoffset;
7988 cum->intoffset = -1;
7989 cum->floats_in_gpr = 0;
7991 if (intoffset % BITS_PER_WORD != 0)
7993 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7995 if (mode == BLKmode)
7997 /* We couldn't find an appropriate mode, which happens,
7998 e.g., in packed structs when there are 3 bytes to load.
7999 Back intoffset back to the beginning of the word in this
8001 intoffset = intoffset & -BITS_PER_WORD;
8005 startbit = intoffset & -BITS_PER_WORD;
8006 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8007 intregs = (endbit - startbit) / BITS_PER_WORD;
8008 cum->words += intregs;
8009 /* words should be unsigned. */
8010 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8012 int pad = (endbit/BITS_PER_WORD) - cum->words;
8017 /* The darwin64 ABI calls for us to recurse down through structs,
8018 looking for elements passed in registers. Unfortunately, we have
8019 to track int register count here also because of misalignments
8020 in powerpc alignment mode. */
8023 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8025 HOST_WIDE_INT startbitpos)
8029 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8030 if (TREE_CODE (f) == FIELD_DECL)
8032 HOST_WIDE_INT bitpos = startbitpos;
8033 tree ftype = TREE_TYPE (f);
8034 enum machine_mode mode;
8035 if (ftype == error_mark_node)
8037 mode = TYPE_MODE (ftype);
8039 if (DECL_SIZE (f) != 0
8040 && host_integerp (bit_position (f), 1))
8041 bitpos += int_bit_position (f);
8043 /* ??? FIXME: else assume zero offset. */
8045 if (TREE_CODE (ftype) == RECORD_TYPE)
8046 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8047 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8049 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8050 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8051 cum->fregno += n_fpregs;
8052 /* Single-precision floats present a special problem for
8053 us, because they are smaller than an 8-byte GPR, and so
8054 the structure-packing rules combined with the standard
8055 varargs behavior mean that we want to pack float/float
8056 and float/int combinations into a single register's
8057 space. This is complicated by the arg advance flushing,
8058 which works on arbitrarily large groups of int-type
8062 if (cum->floats_in_gpr == 1)
8064 /* Two floats in a word; count the word and reset
8067 cum->floats_in_gpr = 0;
8069 else if (bitpos % 64 == 0)
8071 /* A float at the beginning of an 8-byte word;
8072 count it and put off adjusting cum->words until
8073 we see if a arg advance flush is going to do it
8075 cum->floats_in_gpr++;
8079 /* The float is at the end of a word, preceded
8080 by integer fields, so the arg advance flush
8081 just above has already set cum->words and
8082 everything is taken care of. */
8086 cum->words += n_fpregs;
8088 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8090 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8094 else if (cum->intoffset == -1)
8095 cum->intoffset = bitpos;
8099 /* Check for an item that needs to be considered specially under the darwin 64
8100 bit ABI. These are record types where the mode is BLK or the structure is
8103 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8105 return rs6000_darwin64_abi
8106 && ((mode == BLKmode
8107 && TREE_CODE (type) == RECORD_TYPE
8108 && int_size_in_bytes (type) > 0)
8109 || (type && TREE_CODE (type) == RECORD_TYPE
8110 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8113 /* Update the data in CUM to advance over an argument
8114 of mode MODE and data type TYPE.
8115 (TYPE is null for libcalls where that information may not be available.)
8117 Note that for args passed by reference, function_arg will be called
8118 with MODE and TYPE set to that of the pointer to the arg, not the arg
8122 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8123 const_tree type, bool named, int depth)
8125 /* Only tick off an argument if we're not recursing. */
8127 cum->nargs_prototype--;
8129 #ifdef HAVE_AS_GNU_ATTRIBUTE
8130 if (DEFAULT_ABI == ABI_V4
8133 if (SCALAR_FLOAT_MODE_P (mode))
8134 rs6000_passes_float = true;
8135 else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
8136 rs6000_passes_vector = true;
8137 else if (SPE_VECTOR_MODE (mode)
8139 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8140 rs6000_passes_vector = true;
8144 if (TARGET_ALTIVEC_ABI
8145 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8146 || (type && TREE_CODE (type) == VECTOR_TYPE
8147 && int_size_in_bytes (type) == 16)))
8151 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8154 if (!TARGET_ALTIVEC)
8155 error ("cannot pass argument in vector register because"
8156 " altivec instructions are disabled, use -maltivec"
8159 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8160 even if it is going to be passed in a vector register.
8161 Darwin does the same for variable-argument functions. */
8162 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8163 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8173 /* Vector parameters must be 16-byte aligned. This places
8174 them at 2 mod 4 in terms of words in 32-bit mode, since
8175 the parameter save area starts at offset 24 from the
8176 stack. In 64-bit mode, they just have to start on an
8177 even word, since the parameter save area is 16-byte
8178 aligned. Space for GPRs is reserved even if the argument
8179 will be passed in memory. */
8181 align = (2 - cum->words) & 3;
8183 align = cum->words & 1;
8184 cum->words += align + rs6000_arg_size (mode, type);
8186 if (TARGET_DEBUG_ARG)
8188 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8190 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8191 cum->nargs_prototype, cum->prototype,
8192 GET_MODE_NAME (mode));
8196 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8198 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8201 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8203 int size = int_size_in_bytes (type);
8204 /* Variable sized types have size == -1 and are
8205 treated as if consisting entirely of ints.
8206 Pad to 16 byte boundary if needed. */
8207 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8208 && (cum->words % 2) != 0)
8210 /* For varargs, we can just go up by the size of the struct. */
8212 cum->words += (size + 7) / 8;
8215 /* It is tempting to say int register count just goes up by
8216 sizeof(type)/8, but this is wrong in a case such as
8217 { int; double; int; } [powerpc alignment]. We have to
8218 grovel through the fields for these too. */
8220 cum->floats_in_gpr = 0;
8221 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8222 rs6000_darwin64_record_arg_advance_flush (cum,
8223 size * BITS_PER_UNIT, 1);
8225 if (TARGET_DEBUG_ARG)
8227 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8228 cum->words, TYPE_ALIGN (type), size);
8230 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8231 cum->nargs_prototype, cum->prototype,
8232 GET_MODE_NAME (mode));
8235 else if (DEFAULT_ABI == ABI_V4)
8237 if (TARGET_HARD_FLOAT && TARGET_FPRS
8238 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8239 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8240 || (mode == TFmode && !TARGET_IEEEQUAD)
8241 || mode == SDmode || mode == DDmode || mode == TDmode))
8243 /* _Decimal128 must use an even/odd register pair. This assumes
8244 that the register number is odd when fregno is odd. */
8245 if (mode == TDmode && (cum->fregno % 2) == 1)
8248 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8249 <= FP_ARG_V4_MAX_REG)
8250 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8253 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8254 if (mode == DFmode || mode == TFmode
8255 || mode == DDmode || mode == TDmode)
8256 cum->words += cum->words & 1;
8257 cum->words += rs6000_arg_size (mode, type);
8262 int n_words = rs6000_arg_size (mode, type);
8263 int gregno = cum->sysv_gregno;
8265 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8266 (r7,r8) or (r9,r10). As does any other 2 word item such
8267 as complex int due to a historical mistake. */
8269 gregno += (1 - gregno) & 1;
8271 /* Multi-reg args are not split between registers and stack. */
8272 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8274 /* Long long and SPE vectors are aligned on the stack.
8275 So are other 2 word items such as complex int due to
8276 a historical mistake. */
8278 cum->words += cum->words & 1;
8279 cum->words += n_words;
8282 /* Note: continuing to accumulate gregno past when we've started
8283 spilling to the stack indicates the fact that we've started
8284 spilling to the stack to expand_builtin_saveregs. */
8285 cum->sysv_gregno = gregno + n_words;
8288 if (TARGET_DEBUG_ARG)
8290 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8291 cum->words, cum->fregno);
8292 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8293 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8294 fprintf (stderr, "mode = %4s, named = %d\n",
8295 GET_MODE_NAME (mode), named);
8300 int n_words = rs6000_arg_size (mode, type);
8301 int start_words = cum->words;
8302 int align_words = rs6000_parm_start (mode, type, start_words);
8304 cum->words = align_words + n_words;
8306 if (SCALAR_FLOAT_MODE_P (mode)
8307 && TARGET_HARD_FLOAT && TARGET_FPRS)
8309 /* _Decimal128 must be passed in an even/odd float register pair.
8310 This assumes that the register number is odd when fregno is
8312 if (mode == TDmode && (cum->fregno % 2) == 1)
8314 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8317 if (TARGET_DEBUG_ARG)
8319 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8320 cum->words, cum->fregno);
8321 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8322 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8323 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8324 named, align_words - start_words, depth);
8330 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8331 const_tree type, bool named)
8333 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8337 spe_build_register_parallel (enum machine_mode mode, int gregno)
8344 r1 = gen_rtx_REG (DImode, gregno);
8345 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8346 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8350 r1 = gen_rtx_REG (DImode, gregno);
8351 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8352 r3 = gen_rtx_REG (DImode, gregno + 2);
8353 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8354 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8357 r1 = gen_rtx_REG (DImode, gregno);
8358 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8359 r3 = gen_rtx_REG (DImode, gregno + 2);
8360 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8361 r5 = gen_rtx_REG (DImode, gregno + 4);
8362 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8363 r7 = gen_rtx_REG (DImode, gregno + 6);
8364 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8365 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8372 /* Determine where to put a SIMD argument on the SPE. */
8374 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8377 int gregno = cum->sysv_gregno;
8379 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8380 are passed and returned in a pair of GPRs for ABI compatibility. */
8381 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8382 || mode == DCmode || mode == TCmode))
8384 int n_words = rs6000_arg_size (mode, type);
8386 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8388 gregno += (1 - gregno) & 1;
8390 /* Multi-reg args are not split between registers and stack. */
8391 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8394 return spe_build_register_parallel (mode, gregno);
8398 int n_words = rs6000_arg_size (mode, type);
8400 /* SPE vectors are put in odd registers. */
8401 if (n_words == 2 && (gregno & 1) == 0)
8404 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8407 enum machine_mode m = SImode;
8409 r1 = gen_rtx_REG (m, gregno);
8410 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8411 r2 = gen_rtx_REG (m, gregno + 1);
8412 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8413 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8420 if (gregno <= GP_ARG_MAX_REG)
8421 return gen_rtx_REG (mode, gregno);
8427 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8428 structure between cum->intoffset and bitpos to integer registers. */
8431 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8432 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8434 enum machine_mode mode;
8436 unsigned int startbit, endbit;
8437 int this_regno, intregs, intoffset;
8440 if (cum->intoffset == -1)
8443 intoffset = cum->intoffset;
8444 cum->intoffset = -1;
8446 /* If this is the trailing part of a word, try to only load that
8447 much into the register. Otherwise load the whole register. Note
8448 that in the latter case we may pick up unwanted bits. It's not a
8449 problem at the moment but may wish to revisit. */
8451 if (intoffset % BITS_PER_WORD != 0)
8453 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8455 if (mode == BLKmode)
8457 /* We couldn't find an appropriate mode, which happens,
8458 e.g., in packed structs when there are 3 bytes to load.
8459 Back intoffset back to the beginning of the word in this
8461 intoffset = intoffset & -BITS_PER_WORD;
8468 startbit = intoffset & -BITS_PER_WORD;
8469 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8470 intregs = (endbit - startbit) / BITS_PER_WORD;
8471 this_regno = cum->words + intoffset / BITS_PER_WORD;
8473 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8476 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8480 intoffset /= BITS_PER_UNIT;
8483 regno = GP_ARG_MIN_REG + this_regno;
8484 reg = gen_rtx_REG (mode, regno);
8486 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8489 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8493 while (intregs > 0);
8496 /* Recursive workhorse for the following. */
8499 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8500 HOST_WIDE_INT startbitpos, rtx rvec[],
8505 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8506 if (TREE_CODE (f) == FIELD_DECL)
8508 HOST_WIDE_INT bitpos = startbitpos;
8509 tree ftype = TREE_TYPE (f);
8510 enum machine_mode mode;
8511 if (ftype == error_mark_node)
8513 mode = TYPE_MODE (ftype);
8515 if (DECL_SIZE (f) != 0
8516 && host_integerp (bit_position (f), 1))
8517 bitpos += int_bit_position (f);
8519 /* ??? FIXME: else assume zero offset. */
8521 if (TREE_CODE (ftype) == RECORD_TYPE)
8522 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8523 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8525 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8529 case SCmode: mode = SFmode; break;
8530 case DCmode: mode = DFmode; break;
8531 case TCmode: mode = TFmode; break;
8535 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8536 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8538 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8539 && (mode == TFmode || mode == TDmode));
8540 /* Long double or _Decimal128 split over regs and memory. */
8541 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8545 = gen_rtx_EXPR_LIST (VOIDmode,
8546 gen_rtx_REG (mode, cum->fregno++),
8547 GEN_INT (bitpos / BITS_PER_UNIT));
8548 if (mode == TFmode || mode == TDmode)
8551 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8553 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8555 = gen_rtx_EXPR_LIST (VOIDmode,
8556 gen_rtx_REG (mode, cum->vregno++),
8557 GEN_INT (bitpos / BITS_PER_UNIT));
8559 else if (cum->intoffset == -1)
8560 cum->intoffset = bitpos;
8564 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8565 the register(s) to be used for each field and subfield of a struct
8566 being passed by value, along with the offset of where the
8567 register's value may be found in the block. FP fields go in FP
8568 register, vector fields go in vector registers, and everything
8569 else goes in int registers, packed as in memory.
8571 This code is also used for function return values. RETVAL indicates
8572 whether this is the case.
8574 Much of this is taken from the SPARC V9 port, which has a similar
8575 calling convention. */
8578 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8579 bool named, bool retval)
8581 rtx rvec[FIRST_PSEUDO_REGISTER];
8582 int k = 1, kbase = 1;
8583 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8584 /* This is a copy; modifications are not visible to our caller. */
8585 CUMULATIVE_ARGS copy_cum = *orig_cum;
8586 CUMULATIVE_ARGS *cum = ©_cum;
8588 /* Pad to 16 byte boundary if needed. */
8589 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8590 && (cum->words % 2) != 0)
8597 /* Put entries into rvec[] for individual FP and vector fields, and
8598 for the chunks of memory that go in int regs. Note we start at
8599 element 1; 0 is reserved for an indication of using memory, and
8600 may or may not be filled in below. */
8601 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8602 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8604 /* If any part of the struct went on the stack put all of it there.
8605 This hack is because the generic code for
8606 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8607 parts of the struct are not at the beginning. */
8611 return NULL_RTX; /* doesn't go in registers at all */
8613 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8615 if (k > 1 || cum->use_stack)
8616 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8621 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8624 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8629 rtx rvec[GP_ARG_NUM_REG + 1];
8631 if (align_words >= GP_ARG_NUM_REG)
8634 n_units = rs6000_arg_size (mode, type);
8636 /* Optimize the simple case where the arg fits in one gpr, except in
8637 the case of BLKmode due to assign_parms assuming that registers are
8638 BITS_PER_WORD wide. */
8640 || (n_units == 1 && mode != BLKmode))
8641 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8644 if (align_words + n_units > GP_ARG_NUM_REG)
8645 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8646 using a magic NULL_RTX component.
8647 This is not strictly correct. Only some of the arg belongs in
8648 memory, not all of it. However, the normal scheme using
8649 function_arg_partial_nregs can result in unusual subregs, eg.
8650 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8651 store the whole arg to memory is often more efficient than code
8652 to store pieces, and we know that space is available in the right
8653 place for the whole arg. */
8654 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8659 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8660 rtx off = GEN_INT (i++ * 4);
8661 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8663 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8665 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8668 /* Determine where to put an argument to a function.
8669 Value is zero to push the argument on the stack,
8670 or a hard register in which to store the argument.
8672 MODE is the argument's machine mode.
8673 TYPE is the data type of the argument (as a tree).
8674 This is null for libcalls where that information may
8676 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8677 the preceding args and about the function being called. It is
8678 not modified in this routine.
8679 NAMED is nonzero if this argument is a named parameter
8680 (otherwise it is an extra parameter matching an ellipsis).
8682 On RS/6000 the first eight words of non-FP are normally in registers
8683 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8684 Under V.4, the first 8 FP args are in registers.
8686 If this is floating-point and no prototype is specified, we use
8687 both an FP and integer register (or possibly FP reg and stack). Library
8688 functions (when CALL_LIBCALL is set) always have the proper types for args,
8689 so we can pass the FP value just in one register. emit_library_function
8690 doesn't support PARALLEL anyway.
8692 Note that for args passed by reference, function_arg will be called
8693 with MODE and TYPE set to that of the pointer to the arg, not the arg
8697 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8698 const_tree type, bool named)
8700 enum rs6000_abi abi = DEFAULT_ABI;
8702 /* Return a marker to indicate whether CR1 needs to set or clear the
8703 bit that V.4 uses to say fp args were passed in registers.
8704 Assume that we don't need the marker for software floating point,
8705 or compiler generated library calls. */
8706 if (mode == VOIDmode)
8709 && (cum->call_cookie & CALL_LIBCALL) == 0
8711 || (cum->nargs_prototype < 0
8712 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8714 /* For the SPE, we need to crxor CR6 always. */
8716 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8717 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8718 return GEN_INT (cum->call_cookie
8719 | ((cum->fregno == FP_ARG_MIN_REG)
8720 ? CALL_V4_SET_FP_ARGS
8721 : CALL_V4_CLEAR_FP_ARGS));
8724 return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
8727 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8729 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
8730 if (rslt != NULL_RTX)
8732 /* Else fall through to usual handling. */
8735 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8736 if (TARGET_64BIT && ! cum->prototype)
8738 /* Vector parameters get passed in vector register
8739 and also in GPRs or memory, in absence of prototype. */
8742 align_words = (cum->words + 1) & ~1;
8744 if (align_words >= GP_ARG_NUM_REG)
8750 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8752 return gen_rtx_PARALLEL (mode,
8754 gen_rtx_EXPR_LIST (VOIDmode,
8756 gen_rtx_EXPR_LIST (VOIDmode,
8757 gen_rtx_REG (mode, cum->vregno),
8761 return gen_rtx_REG (mode, cum->vregno);
8762 else if (TARGET_ALTIVEC_ABI
8763 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
8764 || (type && TREE_CODE (type) == VECTOR_TYPE
8765 && int_size_in_bytes (type) == 16)))
8767 if (named || abi == ABI_V4)
8771 /* Vector parameters to varargs functions under AIX or Darwin
8772 get passed in memory and possibly also in GPRs. */
8773 int align, align_words, n_words;
8774 enum machine_mode part_mode;
8776 /* Vector parameters must be 16-byte aligned. This places them at
8777 2 mod 4 in terms of words in 32-bit mode, since the parameter
8778 save area starts at offset 24 from the stack. In 64-bit mode,
8779 they just have to start on an even word, since the parameter
8780 save area is 16-byte aligned. */
8782 align = (2 - cum->words) & 3;
8784 align = cum->words & 1;
8785 align_words = cum->words + align;
8787 /* Out of registers? Memory, then. */
8788 if (align_words >= GP_ARG_NUM_REG)
8791 if (TARGET_32BIT && TARGET_POWERPC64)
8792 return rs6000_mixed_function_arg (mode, type, align_words);
8794 /* The vector value goes in GPRs. Only the part of the
8795 value in GPRs is reported here. */
8797 n_words = rs6000_arg_size (mode, type);
8798 if (align_words + n_words > GP_ARG_NUM_REG)
8799 /* Fortunately, there are only two possibilities, the value
8800 is either wholly in GPRs or half in GPRs and half not. */
8803 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8806 else if (TARGET_SPE_ABI && TARGET_SPE
8807 && (SPE_VECTOR_MODE (mode)
8808 || (TARGET_E500_DOUBLE && (mode == DFmode
8811 || mode == TCmode))))
8812 return rs6000_spe_function_arg (cum, mode, type);
8814 else if (abi == ABI_V4)
8816 if (TARGET_HARD_FLOAT && TARGET_FPRS
8817 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8818 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8819 || (mode == TFmode && !TARGET_IEEEQUAD)
8820 || mode == SDmode || mode == DDmode || mode == TDmode))
8822 /* _Decimal128 must use an even/odd register pair. This assumes
8823 that the register number is odd when fregno is odd. */
8824 if (mode == TDmode && (cum->fregno % 2) == 1)
8827 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8828 <= FP_ARG_V4_MAX_REG)
8829 return gen_rtx_REG (mode, cum->fregno);
8835 int n_words = rs6000_arg_size (mode, type);
8836 int gregno = cum->sysv_gregno;
8838 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8839 (r7,r8) or (r9,r10). As does any other 2 word item such
8840 as complex int due to a historical mistake. */
8842 gregno += (1 - gregno) & 1;
8844 /* Multi-reg args are not split between registers and stack. */
8845 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8848 if (TARGET_32BIT && TARGET_POWERPC64)
8849 return rs6000_mixed_function_arg (mode, type,
8850 gregno - GP_ARG_MIN_REG);
8851 return gen_rtx_REG (mode, gregno);
8856 int align_words = rs6000_parm_start (mode, type, cum->words);
8858 /* _Decimal128 must be passed in an even/odd float register pair.
8859 This assumes that the register number is odd when fregno is odd. */
8860 if (mode == TDmode && (cum->fregno % 2) == 1)
8863 if (USE_FP_FOR_ARG_P (cum, mode, type))
8865 rtx rvec[GP_ARG_NUM_REG + 1];
8869 enum machine_mode fmode = mode;
8870 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8872 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8874 /* Currently, we only ever need one reg here because complex
8875 doubles are split. */
8876 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8877 && (fmode == TFmode || fmode == TDmode));
8879 /* Long double or _Decimal128 split over regs and memory. */
8880 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8883 /* Do we also need to pass this arg in the parameter save
8886 && (cum->nargs_prototype <= 0
8887 || (DEFAULT_ABI == ABI_AIX
8889 && align_words >= GP_ARG_NUM_REG)));
8891 if (!needs_psave && mode == fmode)
8892 return gen_rtx_REG (fmode, cum->fregno);
8897 /* Describe the part that goes in gprs or the stack.
8898 This piece must come first, before the fprs. */
8899 if (align_words < GP_ARG_NUM_REG)
8901 unsigned long n_words = rs6000_arg_size (mode, type);
8903 if (align_words + n_words > GP_ARG_NUM_REG
8904 || (TARGET_32BIT && TARGET_POWERPC64))
8906 /* If this is partially on the stack, then we only
8907 include the portion actually in registers here. */
8908 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8911 if (align_words + n_words > GP_ARG_NUM_REG)
8912 /* Not all of the arg fits in gprs. Say that it
8913 goes in memory too, using a magic NULL_RTX
8914 component. Also see comment in
8915 rs6000_mixed_function_arg for why the normal
8916 function_arg_partial_nregs scheme doesn't work
8918 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8922 r = gen_rtx_REG (rmode,
8923 GP_ARG_MIN_REG + align_words);
8924 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8925 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8927 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8931 /* The whole arg fits in gprs. */
8932 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8933 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8937 /* It's entirely in memory. */
8938 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8941 /* Describe where this piece goes in the fprs. */
8942 r = gen_rtx_REG (fmode, cum->fregno);
8943 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8945 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8947 else if (align_words < GP_ARG_NUM_REG)
8949 if (TARGET_32BIT && TARGET_POWERPC64)
8950 return rs6000_mixed_function_arg (mode, type, align_words);
8952 if (mode == BLKmode)
8955 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8962 /* For an arg passed partly in registers and partly in memory, this is
8963 the number of bytes passed in registers. For args passed entirely in
8964 registers or entirely in memory, zero. When an arg is described by a
8965 PARALLEL, perhaps using more than one register type, this function
8966 returns the number of bytes used by the first element of the PARALLEL. */
8969 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8970 tree type, bool named)
8975 if (DEFAULT_ABI == ABI_V4)
8978 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8979 && cum->nargs_prototype >= 0)
8982 /* In this complicated case we just disable the partial_nregs code. */
8983 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8986 align_words = rs6000_parm_start (mode, type, cum->words);
8988 if (USE_FP_FOR_ARG_P (cum, mode, type))
8990 /* If we are passing this arg in the fixed parameter save area
8991 (gprs or memory) as well as fprs, then this function should
8992 return the number of partial bytes passed in the parameter
8993 save area rather than partial bytes passed in fprs. */
8995 && (cum->nargs_prototype <= 0
8996 || (DEFAULT_ABI == ABI_AIX
8998 && align_words >= GP_ARG_NUM_REG)))
9000 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9001 > FP_ARG_MAX_REG + 1)
9002 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9003 else if (cum->nargs_prototype >= 0)
9007 if (align_words < GP_ARG_NUM_REG
9008 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9009 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9011 if (ret != 0 && TARGET_DEBUG_ARG)
9012 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9017 /* A C expression that indicates when an argument must be passed by
9018 reference. If nonzero for an argument, a copy of that argument is
9019 made in memory and a pointer to the argument is passed instead of
9020 the argument itself. The pointer is passed in whatever way is
9021 appropriate for passing a pointer to that type.
9023 Under V.4, aggregates and long double are passed by reference.
9025 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9026 reference unless the AltiVec vector extension ABI is in force.
9028 As an extension to all ABIs, variable sized types are passed by
9032 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9033 enum machine_mode mode, const_tree type,
9034 bool named ATTRIBUTE_UNUSED)
9036 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9038 if (TARGET_DEBUG_ARG)
9039 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9046 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9048 if (TARGET_DEBUG_ARG)
9049 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9053 if (int_size_in_bytes (type) < 0)
9055 if (TARGET_DEBUG_ARG)
9056 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9060 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9061 modes only exist for GCC vector types if -maltivec. */
9062 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9064 if (TARGET_DEBUG_ARG)
9065 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9069 /* Pass synthetic vectors in memory. */
9070 if (TREE_CODE (type) == VECTOR_TYPE
9071 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9073 static bool warned_for_pass_big_vectors = false;
9074 if (TARGET_DEBUG_ARG)
9075 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9076 if (!warned_for_pass_big_vectors)
9078 warning (0, "GCC vector passed by reference: "
9079 "non-standard ABI extension with no compatibility guarantee");
9080 warned_for_pass_big_vectors = true;
9089 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9092 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9097 for (i = 0; i < nregs; i++)
9099 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9100 if (reload_completed)
9102 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9105 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9106 i * GET_MODE_SIZE (reg_mode));
9109 tem = replace_equiv_address (tem, XEXP (tem, 0));
9113 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9117 /* Perform any needed actions needed for a function that is receiving a
9118 variable number of arguments.
9122 MODE and TYPE are the mode and type of the current parameter.
9124 PRETEND_SIZE is a variable that should be set to the amount of stack
9125 that must be pushed by the prolog to pretend that our caller pushed
9128 Normally, this macro will push all remaining incoming registers on the
9129 stack and set PRETEND_SIZE to the length of the registers pushed. */
9132 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9133 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9136 CUMULATIVE_ARGS next_cum;
9137 int reg_size = TARGET_32BIT ? 4 : 8;
9138 rtx save_area = NULL_RTX, mem;
9139 int first_reg_offset;
9142 /* Skip the last named argument. */
9144 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9146 if (DEFAULT_ABI == ABI_V4)
9148 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9152 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9153 HOST_WIDE_INT offset = 0;
9155 /* Try to optimize the size of the varargs save area.
9156 The ABI requires that ap.reg_save_area is doubleword
9157 aligned, but we don't need to allocate space for all
9158 the bytes, only those to which we actually will save
9160 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9161 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9162 if (TARGET_HARD_FLOAT && TARGET_FPRS
9163 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9164 && cfun->va_list_fpr_size)
9167 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9168 * UNITS_PER_FP_WORD;
9169 if (cfun->va_list_fpr_size
9170 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9171 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9173 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9174 * UNITS_PER_FP_WORD;
9178 offset = -((first_reg_offset * reg_size) & ~7);
9179 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9181 gpr_reg_num = cfun->va_list_gpr_size;
9182 if (reg_size == 4 && (first_reg_offset & 1))
9185 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9188 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9190 - (int) (GP_ARG_NUM_REG * reg_size);
9192 if (gpr_size + fpr_size)
9195 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9196 gcc_assert (GET_CODE (reg_save_area) == MEM);
9197 reg_save_area = XEXP (reg_save_area, 0);
9198 if (GET_CODE (reg_save_area) == PLUS)
9200 gcc_assert (XEXP (reg_save_area, 0)
9201 == virtual_stack_vars_rtx);
9202 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9203 offset += INTVAL (XEXP (reg_save_area, 1));
9206 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9209 cfun->machine->varargs_save_offset = offset;
9210 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9215 first_reg_offset = next_cum.words;
9216 save_area = virtual_incoming_args_rtx;
9218 if (targetm.calls.must_pass_in_stack (mode, type))
9219 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9222 set = get_varargs_alias_set ();
9223 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9224 && cfun->va_list_gpr_size)
9226 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9228 if (va_list_gpr_counter_field)
9230 /* V4 va_list_gpr_size counts number of registers needed. */
9231 if (nregs > cfun->va_list_gpr_size)
9232 nregs = cfun->va_list_gpr_size;
9236 /* char * va_list instead counts number of bytes needed. */
9237 if (nregs > cfun->va_list_gpr_size / reg_size)
9238 nregs = cfun->va_list_gpr_size / reg_size;
9241 mem = gen_rtx_MEM (BLKmode,
9242 plus_constant (save_area,
9243 first_reg_offset * reg_size));
9244 MEM_NOTRAP_P (mem) = 1;
9245 set_mem_alias_set (mem, set);
9246 set_mem_align (mem, BITS_PER_WORD);
9248 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9252 /* Save FP registers if needed. */
9253 if (DEFAULT_ABI == ABI_V4
9254 && TARGET_HARD_FLOAT && TARGET_FPRS
9256 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9257 && cfun->va_list_fpr_size)
9259 int fregno = next_cum.fregno, nregs;
9260 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9261 rtx lab = gen_label_rtx ();
9262 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9263 * UNITS_PER_FP_WORD);
9266 (gen_rtx_SET (VOIDmode,
9268 gen_rtx_IF_THEN_ELSE (VOIDmode,
9269 gen_rtx_NE (VOIDmode, cr1,
9271 gen_rtx_LABEL_REF (VOIDmode, lab),
9275 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9276 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9278 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9280 plus_constant (save_area, off));
9281 MEM_NOTRAP_P (mem) = 1;
9282 set_mem_alias_set (mem, set);
9283 set_mem_align (mem, GET_MODE_ALIGNMENT (
9284 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9285 ? DFmode : SFmode));
9286 emit_move_insn (mem, gen_rtx_REG (
9287 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9288 ? DFmode : SFmode, fregno));
9295 /* Create the va_list data type. */
9298 rs6000_build_builtin_va_list (void)
9300 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9302 /* For AIX, prefer 'char *' because that's what the system
9303 header files like. */
9304 if (DEFAULT_ABI != ABI_V4)
9305 return build_pointer_type (char_type_node);
9307 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9308 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9309 get_identifier ("__va_list_tag"), record);
9311 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9312 unsigned_char_type_node);
9313 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9314 unsigned_char_type_node);
9315 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9317 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9318 get_identifier ("reserved"), short_unsigned_type_node);
9319 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9320 get_identifier ("overflow_arg_area"),
9322 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9323 get_identifier ("reg_save_area"),
9326 va_list_gpr_counter_field = f_gpr;
9327 va_list_fpr_counter_field = f_fpr;
9329 DECL_FIELD_CONTEXT (f_gpr) = record;
9330 DECL_FIELD_CONTEXT (f_fpr) = record;
9331 DECL_FIELD_CONTEXT (f_res) = record;
9332 DECL_FIELD_CONTEXT (f_ovf) = record;
9333 DECL_FIELD_CONTEXT (f_sav) = record;
9335 TYPE_STUB_DECL (record) = type_decl;
9336 TYPE_NAME (record) = type_decl;
9337 TYPE_FIELDS (record) = f_gpr;
9338 DECL_CHAIN (f_gpr) = f_fpr;
9339 DECL_CHAIN (f_fpr) = f_res;
9340 DECL_CHAIN (f_res) = f_ovf;
9341 DECL_CHAIN (f_ovf) = f_sav;
9343 layout_type (record);
9345 /* The correct type is an array type of one element. */
9346 return build_array_type (record, build_index_type (size_zero_node));
9349 /* Implement va_start. */
9352 rs6000_va_start (tree valist, rtx nextarg)
9354 HOST_WIDE_INT words, n_gpr, n_fpr;
9355 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9356 tree gpr, fpr, ovf, sav, t;
9358 /* Only SVR4 needs something special. */
9359 if (DEFAULT_ABI != ABI_V4)
9361 std_expand_builtin_va_start (valist, nextarg);
9365 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9366 f_fpr = DECL_CHAIN (f_gpr);
9367 f_res = DECL_CHAIN (f_fpr);
9368 f_ovf = DECL_CHAIN (f_res);
9369 f_sav = DECL_CHAIN (f_ovf);
9371 valist = build_simple_mem_ref (valist);
9372 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9373 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9375 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9377 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9380 /* Count number of gp and fp argument registers used. */
9381 words = crtl->args.info.words;
9382 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9384 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9387 if (TARGET_DEBUG_ARG)
9388 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9389 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9390 words, n_gpr, n_fpr);
9392 if (cfun->va_list_gpr_size)
9394 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9395 build_int_cst (NULL_TREE, n_gpr));
9396 TREE_SIDE_EFFECTS (t) = 1;
9397 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9400 if (cfun->va_list_fpr_size)
9402 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9403 build_int_cst (NULL_TREE, n_fpr));
9404 TREE_SIDE_EFFECTS (t) = 1;
9405 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9407 #ifdef HAVE_AS_GNU_ATTRIBUTE
9408 if (call_ABI_of_interest (cfun->decl))
9409 rs6000_passes_float = true;
9413 /* Find the overflow area. */
9414 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9416 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9417 size_int (words * UNITS_PER_WORD));
9418 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9419 TREE_SIDE_EFFECTS (t) = 1;
9420 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9422 /* If there were no va_arg invocations, don't set up the register
9424 if (!cfun->va_list_gpr_size
9425 && !cfun->va_list_fpr_size
9426 && n_gpr < GP_ARG_NUM_REG
9427 && n_fpr < FP_ARG_V4_MAX_REG)
9430 /* Find the register save area. */
9431 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9432 if (cfun->machine->varargs_save_offset)
9433 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9434 size_int (cfun->machine->varargs_save_offset));
9435 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9436 TREE_SIDE_EFFECTS (t) = 1;
9437 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9440 /* Implement va_arg. */
9443 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9446 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9447 tree gpr, fpr, ovf, sav, reg, t, u;
9448 int size, rsize, n_reg, sav_ofs, sav_scale;
9449 tree lab_false, lab_over, addr;
9451 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9455 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9457 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9458 return build_va_arg_indirect_ref (t);
9461 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9462 earlier version of gcc, with the property that it always applied alignment
9463 adjustments to the va-args (even for zero-sized types). The cheapest way
9464 to deal with this is to replicate the effect of the part of
9465 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9467 We don't need to check for pass-by-reference because of the test above.
9468 We can return a simplifed answer, since we know there's no offset to add. */
9471 && rs6000_darwin64_abi
9472 && integer_zerop (TYPE_SIZE (type)))
9474 unsigned HOST_WIDE_INT align, boundary;
9475 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9476 align = PARM_BOUNDARY / BITS_PER_UNIT;
9477 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9478 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9479 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9480 boundary /= BITS_PER_UNIT;
9481 if (boundary > align)
9484 /* This updates arg ptr by the amount that would be necessary
9485 to align the zero-sized (but not zero-alignment) item. */
9486 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9487 fold_build2 (POINTER_PLUS_EXPR,
9489 valist_tmp, size_int (boundary - 1)));
9490 gimplify_and_add (t, pre_p);
9492 t = fold_convert (sizetype, valist_tmp);
9493 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9494 fold_convert (TREE_TYPE (valist),
9495 fold_build2 (BIT_AND_EXPR, sizetype, t,
9496 size_int (-boundary))));
9497 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9498 gimplify_and_add (t, pre_p);
9500 /* Since it is zero-sized there's no increment for the item itself. */
9501 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9502 return build_va_arg_indirect_ref (valist_tmp);
9505 if (DEFAULT_ABI != ABI_V4)
9507 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9509 tree elem_type = TREE_TYPE (type);
9510 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9511 int elem_size = GET_MODE_SIZE (elem_mode);
9513 if (elem_size < UNITS_PER_WORD)
9515 tree real_part, imag_part;
9516 gimple_seq post = NULL;
9518 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9520 /* Copy the value into a temporary, lest the formal temporary
9521 be reused out from under us. */
9522 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9523 gimple_seq_add_seq (pre_p, post);
9525 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9528 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9532 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9535 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9536 f_fpr = DECL_CHAIN (f_gpr);
9537 f_res = DECL_CHAIN (f_fpr);
9538 f_ovf = DECL_CHAIN (f_res);
9539 f_sav = DECL_CHAIN (f_ovf);
9541 valist = build_va_arg_indirect_ref (valist);
9542 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9543 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9545 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9547 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9550 size = int_size_in_bytes (type);
9551 rsize = (size + 3) / 4;
9554 if (TARGET_HARD_FLOAT && TARGET_FPRS
9555 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9556 || (TARGET_DOUBLE_FLOAT
9557 && (TYPE_MODE (type) == DFmode
9558 || TYPE_MODE (type) == TFmode
9559 || TYPE_MODE (type) == SDmode
9560 || TYPE_MODE (type) == DDmode
9561 || TYPE_MODE (type) == TDmode))))
9563 /* FP args go in FP registers, if present. */
9565 n_reg = (size + 7) / 8;
9566 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9567 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9568 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9573 /* Otherwise into GP registers. */
9582 /* Pull the value out of the saved registers.... */
9585 addr = create_tmp_var (ptr_type_node, "addr");
9587 /* AltiVec vectors never go in registers when -mabi=altivec. */
9588 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9592 lab_false = create_artificial_label (input_location);
9593 lab_over = create_artificial_label (input_location);
9595 /* Long long and SPE vectors are aligned in the registers.
9596 As are any other 2 gpr item such as complex int due to a
9597 historical mistake. */
9599 if (n_reg == 2 && reg == gpr)
9602 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9603 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9604 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9605 unshare_expr (reg), u);
9607 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9608 reg number is 0 for f1, so we want to make it odd. */
9609 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9611 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9612 build_int_cst (TREE_TYPE (reg), 1));
9613 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9616 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9617 t = build2 (GE_EXPR, boolean_type_node, u, t);
9618 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9619 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9620 gimplify_and_add (t, pre_p);
9624 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9626 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9627 build_int_cst (TREE_TYPE (reg), n_reg));
9628 u = fold_convert (sizetype, u);
9629 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9630 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9632 /* _Decimal32 varargs are located in the second word of the 64-bit
9633 FP register for 32-bit binaries. */
9634 if (!TARGET_POWERPC64
9635 && TARGET_HARD_FLOAT && TARGET_FPRS
9636 && TYPE_MODE (type) == SDmode)
9637 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9639 gimplify_assign (addr, t, pre_p);
9641 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9643 stmt = gimple_build_label (lab_false);
9644 gimple_seq_add_stmt (pre_p, stmt);
9646 if ((n_reg == 2 && !regalign) || n_reg > 2)
9648 /* Ensure that we don't find any more args in regs.
9649 Alignment has taken care of for special cases. */
9650 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9654 /* ... otherwise out of the overflow area. */
9656 /* Care for on-stack alignment if needed. */
9660 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9661 t = fold_convert (sizetype, t);
9662 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9664 t = fold_convert (TREE_TYPE (ovf), t);
9666 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9668 gimplify_assign (unshare_expr (addr), t, pre_p);
9670 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9671 gimplify_assign (unshare_expr (ovf), t, pre_p);
9675 stmt = gimple_build_label (lab_over);
9676 gimple_seq_add_stmt (pre_p, stmt);
9679 if (STRICT_ALIGNMENT
9680 && (TYPE_ALIGN (type)
9681 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9683 /* The value (of type complex double, for example) may not be
9684 aligned in memory in the saved registers, so copy via a
9685 temporary. (This is the same code as used for SPARC.) */
9686 tree tmp = create_tmp_var (type, "va_arg_tmp");
9687 tree dest_addr = build_fold_addr_expr (tmp);
9689 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9690 3, dest_addr, addr, size_int (rsize * 4));
9692 gimplify_and_add (copy, pre_p);
9696 addr = fold_convert (ptrtype, addr);
9697 return build_va_arg_indirect_ref (addr);
9703 def_builtin (int mask, const char *name, tree type, int code)
9705 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9708 if (rs6000_builtin_decls[code])
9709 fatal_error ("internal error: builtin function to %s already processed",
9712 rs6000_builtin_decls[code] = t =
9713 add_builtin_function (name, type, code, BUILT_IN_MD,
9716 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9717 switch (builtin_classify[code])
9722 /* assume builtin can do anything. */
9723 case RS6000_BTC_MISC:
9726 /* const function, function only depends on the inputs. */
9727 case RS6000_BTC_CONST:
9728 TREE_READONLY (t) = 1;
9729 TREE_NOTHROW (t) = 1;
9732 /* pure function, function can read global memory. */
9733 case RS6000_BTC_PURE:
9734 DECL_PURE_P (t) = 1;
9735 TREE_NOTHROW (t) = 1;
9738 /* Function is a math function. If rounding mode is on, then treat
9739 the function as not reading global memory, but it can have
9740 arbitrary side effects. If it is off, then assume the function is
9741 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9742 attribute in builtin-attribute.def that is used for the math
9744 case RS6000_BTC_FP_PURE:
9745 TREE_NOTHROW (t) = 1;
9746 if (flag_rounding_math)
9748 DECL_PURE_P (t) = 1;
9749 DECL_IS_NOVOPS (t) = 1;
9752 TREE_READONLY (t) = 1;
9758 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9760 static const struct builtin_description bdesc_3arg[] =
9762 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9763 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9764 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9765 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9766 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9767 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9768 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9769 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9770 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9771 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9772 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9773 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9774 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9775 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9776 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9777 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9778 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9779 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9782 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9783 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9784 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9785 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9786 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9787 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9788 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9789 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9790 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9791 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9792 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9793 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9794 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9795 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9796 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9814 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9815 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9816 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9817 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9819 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9820 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9821 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9822 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9827 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9828 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9829 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9830 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9831 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9832 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9833 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9834 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9835 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9836 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9838 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9839 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9840 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9841 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9842 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9843 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9844 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9845 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9846 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9847 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9849 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9850 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9851 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9852 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9853 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9854 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9855 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9856 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9857 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9859 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9860 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9861 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9862 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9863 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9864 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9865 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9867 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9868 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9869 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9870 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9871 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9872 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9873 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9874 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9875 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9878 /* DST operations: void foo (void *, const int, const char). */
9880 static const struct builtin_description bdesc_dst[] =
9882 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9883 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9884 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9885 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9893 /* Simple binary operations: VECc = foo (VECa, VECb). */
9895 static struct builtin_description bdesc_2arg[] =
9897 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9898 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9899 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9900 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9901 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9902 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9903 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9904 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9905 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9906 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9907 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9908 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9909 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9910 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9911 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9912 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9913 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9914 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9915 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9916 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9917 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9918 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9919 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9920 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9921 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9922 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9923 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9924 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9925 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9926 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9927 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9928 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9929 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9930 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9931 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9932 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9933 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9934 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9935 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9936 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9937 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9938 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9939 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9940 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9941 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9942 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9943 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9944 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9945 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9946 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9947 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9948 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9949 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9950 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9951 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9952 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9953 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9954 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9955 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9956 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9957 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9958 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9959 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9960 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9961 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9962 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9963 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9964 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9965 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9966 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9967 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9968 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9969 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9970 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9971 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9972 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9973 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9974 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9975 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9976 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9977 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9978 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9979 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9980 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9981 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9982 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9983 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9984 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9985 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9986 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9987 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9988 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9989 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9990 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9991 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9992 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9993 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9994 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9995 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9996 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9997 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9998 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9999 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10000 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10001 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10002 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10003 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10004 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10005 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10006 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10007 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10008 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10009 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10010 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10011 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10012 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10013 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10015 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10016 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10017 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10018 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10019 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10020 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10021 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10022 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10023 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10024 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10025 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10026 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10028 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10029 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10030 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10031 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10032 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10033 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10034 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10035 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10036 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10037 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10038 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10039 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10041 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10042 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10043 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10044 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10045 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10046 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10048 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10049 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10050 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10051 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10052 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10053 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10054 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10055 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10056 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10057 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10058 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10059 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10061 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10062 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10074 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10075 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10076 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10077 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10080 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10087 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10088 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10092 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10093 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10095 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10096 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10097 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10100 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10101 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10102 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10103 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10104 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10105 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10106 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10107 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10108 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10109 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10110 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10111 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10113 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10114 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10115 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10116 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10117 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10118 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10119 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10120 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10121 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10122 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10123 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10124 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10125 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10126 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10127 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10128 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10129 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10130 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10131 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10132 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10133 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10134 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10135 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10136 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10137 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10138 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10139 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10140 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10141 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10142 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10143 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10144 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10145 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10146 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10147 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10148 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10149 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10150 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10151 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10152 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10153 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10154 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10155 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10156 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10157 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10158 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10159 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10160 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10161 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10162 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10163 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10164 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10165 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10166 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10167 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10168 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10169 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10170 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10171 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10172 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10173 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10178 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10179 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10180 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10181 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10182 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10183 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10184 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10185 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10186 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10187 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10188 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10189 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10191 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10192 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10194 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10195 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10196 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10197 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10198 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10199 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10200 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10201 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10202 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10203 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10205 /* Place holder, leave as first spe builtin. */
10206 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10207 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10208 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10209 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10210 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10211 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10212 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10213 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10214 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10215 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10216 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10217 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10218 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10219 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10220 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10221 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10222 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10223 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10224 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10225 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10226 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10227 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10228 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10229 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10230 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10231 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10232 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10233 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10234 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10235 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10236 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10237 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10238 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10239 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10240 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10241 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10242 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10243 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10244 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10245 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10246 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10247 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10248 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10249 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10250 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10251 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10252 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10253 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10254 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10255 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10256 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10257 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10258 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10259 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10260 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10261 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10262 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10263 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10264 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10265 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10266 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10267 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10268 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10269 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10270 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10271 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10272 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10273 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10274 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10275 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10276 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10277 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10278 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10279 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10280 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10281 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10282 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10283 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10284 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10285 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10286 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10287 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10288 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10289 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10290 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10291 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10292 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10293 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10294 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10295 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10296 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10297 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10298 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10299 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10300 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10301 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10302 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10303 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10304 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10305 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10306 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10307 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10308 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10309 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10310 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10311 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10312 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10313 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10314 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10316 /* SPE binary operations expecting a 5-bit unsigned literal. */
10317 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10319 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10320 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10321 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10322 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10323 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10324 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10325 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10326 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10327 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10328 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10329 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10330 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10331 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10332 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10333 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10334 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10335 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10336 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10337 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10338 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10339 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10340 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10341 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10342 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10343 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10344 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10346 /* Place-holder. Leave as last binary SPE builtin. */
10347 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10350 /* AltiVec predicates. */
10352 struct builtin_description_predicates
10354 const unsigned int mask;
10355 const enum insn_code icode;
10356 const char *const name;
10357 const enum rs6000_builtins code;
10360 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10362 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10363 ALTIVEC_BUILTIN_VCMPBFP_P },
10364 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10365 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10366 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10367 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10368 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10369 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10370 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10371 ALTIVEC_BUILTIN_VCMPEQUW_P },
10372 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10373 ALTIVEC_BUILTIN_VCMPGTSW_P },
10374 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10375 ALTIVEC_BUILTIN_VCMPGTUW_P },
10376 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10377 ALTIVEC_BUILTIN_VCMPEQUH_P },
10378 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10379 ALTIVEC_BUILTIN_VCMPGTSH_P },
10380 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10381 ALTIVEC_BUILTIN_VCMPGTUH_P },
10382 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10383 ALTIVEC_BUILTIN_VCMPEQUB_P },
10384 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10385 ALTIVEC_BUILTIN_VCMPGTSB_P },
10386 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10387 ALTIVEC_BUILTIN_VCMPGTUB_P },
10389 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10390 VSX_BUILTIN_XVCMPEQSP_P },
10391 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10392 VSX_BUILTIN_XVCMPGESP_P },
10393 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10394 VSX_BUILTIN_XVCMPGTSP_P },
10395 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10396 VSX_BUILTIN_XVCMPEQDP_P },
10397 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10398 VSX_BUILTIN_XVCMPGEDP_P },
10399 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10400 VSX_BUILTIN_XVCMPGTDP_P },
10402 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10403 ALTIVEC_BUILTIN_VCMPEQ_P },
10404 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10405 ALTIVEC_BUILTIN_VCMPGT_P },
10406 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10407 ALTIVEC_BUILTIN_VCMPGE_P }
10410 /* SPE predicates. */
10411 static struct builtin_description bdesc_spe_predicates[] =
10413 /* Place-holder. Leave as first. */
10414 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10415 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10416 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10417 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10418 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10419 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10420 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10421 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10422 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10423 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10424 /* Place-holder. Leave as last. */
10425 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10428 /* SPE evsel predicates. */
10429 static struct builtin_description bdesc_spe_evsel[] =
10431 /* Place-holder. Leave as first. */
10432 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10433 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10434 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10435 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10436 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10437 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10438 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10439 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10440 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10441 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10442 /* Place-holder. Leave as last. */
10443 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10446 /* PAIRED predicates. */
10447 static const struct builtin_description bdesc_paired_preds[] =
10449 /* Place-holder. Leave as first. */
10450 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10451 /* Place-holder. Leave as last. */
10452 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10455 /* ABS* operations. */
10457 static const struct builtin_description bdesc_abs[] =
10459 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10460 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10461 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10462 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10463 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10464 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10465 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10466 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10467 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10468 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10469 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10472 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10475 static struct builtin_description bdesc_1arg[] =
10477 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10478 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10479 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10480 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10481 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10482 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10483 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10484 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10485 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10486 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10487 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10488 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10489 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10490 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10491 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10492 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10493 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10494 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10496 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10497 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10498 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10499 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10500 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10501 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10502 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10504 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10505 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10506 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10507 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10508 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10509 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10510 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10512 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10513 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10514 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10515 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10516 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10517 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10519 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10520 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10521 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10522 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10523 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10524 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10526 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10527 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10528 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10529 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10531 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10532 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10533 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10534 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10535 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10536 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10537 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10538 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10539 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10541 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10542 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10543 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10544 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10545 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10546 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10547 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10548 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10549 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10551 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10552 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10553 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10554 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10555 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10562 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10563 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10564 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10565 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10566 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10567 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10568 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10569 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10570 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10571 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10572 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10574 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10575 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10576 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10578 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10579 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10580 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10582 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10583 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10584 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10585 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10587 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10588 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10589 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10590 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10591 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10592 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10593 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10594 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10595 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10596 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10597 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10598 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10599 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10600 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10601 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10602 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10603 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10604 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10605 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10606 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10607 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10608 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10609 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10610 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10611 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10612 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10613 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10614 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10615 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10616 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10618 /* Place-holder. Leave as last unary SPE builtin. */
10619 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10621 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10622 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10623 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10624 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10625 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10629 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10632 tree arg0 = CALL_EXPR_ARG (exp, 0);
10633 rtx op0 = expand_normal (arg0);
10634 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10635 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10637 if (icode == CODE_FOR_nothing)
10638 /* Builtin not supported on this processor. */
10641 /* If we got invalid arguments bail out before generating bad rtl. */
10642 if (arg0 == error_mark_node)
10645 if (icode == CODE_FOR_altivec_vspltisb
10646 || icode == CODE_FOR_altivec_vspltish
10647 || icode == CODE_FOR_altivec_vspltisw
10648 || icode == CODE_FOR_spe_evsplatfi
10649 || icode == CODE_FOR_spe_evsplati)
10651 /* Only allow 5-bit *signed* literals. */
10652 if (GET_CODE (op0) != CONST_INT
10653 || INTVAL (op0) > 15
10654 || INTVAL (op0) < -16)
10656 error ("argument 1 must be a 5-bit signed literal");
10662 || GET_MODE (target) != tmode
10663 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10664 target = gen_reg_rtx (tmode);
10666 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10667 op0 = copy_to_mode_reg (mode0, op0);
10669 pat = GEN_FCN (icode) (target, op0);
10678 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10680 rtx pat, scratch1, scratch2;
10681 tree arg0 = CALL_EXPR_ARG (exp, 0);
10682 rtx op0 = expand_normal (arg0);
10683 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10684 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10686 /* If we have invalid arguments, bail out before generating bad rtl. */
10687 if (arg0 == error_mark_node)
10691 || GET_MODE (target) != tmode
10692 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10693 target = gen_reg_rtx (tmode);
10695 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10696 op0 = copy_to_mode_reg (mode0, op0);
10698 scratch1 = gen_reg_rtx (mode0);
10699 scratch2 = gen_reg_rtx (mode0);
10701 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10710 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10713 tree arg0 = CALL_EXPR_ARG (exp, 0);
10714 tree arg1 = CALL_EXPR_ARG (exp, 1);
10715 rtx op0 = expand_normal (arg0);
10716 rtx op1 = expand_normal (arg1);
10717 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10718 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10719 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10721 if (icode == CODE_FOR_nothing)
10722 /* Builtin not supported on this processor. */
10725 /* If we got invalid arguments bail out before generating bad rtl. */
10726 if (arg0 == error_mark_node || arg1 == error_mark_node)
10729 if (icode == CODE_FOR_altivec_vcfux
10730 || icode == CODE_FOR_altivec_vcfsx
10731 || icode == CODE_FOR_altivec_vctsxs
10732 || icode == CODE_FOR_altivec_vctuxs
10733 || icode == CODE_FOR_altivec_vspltb
10734 || icode == CODE_FOR_altivec_vsplth
10735 || icode == CODE_FOR_altivec_vspltw
10736 || icode == CODE_FOR_spe_evaddiw
10737 || icode == CODE_FOR_spe_evldd
10738 || icode == CODE_FOR_spe_evldh
10739 || icode == CODE_FOR_spe_evldw
10740 || icode == CODE_FOR_spe_evlhhesplat
10741 || icode == CODE_FOR_spe_evlhhossplat
10742 || icode == CODE_FOR_spe_evlhhousplat
10743 || icode == CODE_FOR_spe_evlwhe
10744 || icode == CODE_FOR_spe_evlwhos
10745 || icode == CODE_FOR_spe_evlwhou
10746 || icode == CODE_FOR_spe_evlwhsplat
10747 || icode == CODE_FOR_spe_evlwwsplat
10748 || icode == CODE_FOR_spe_evrlwi
10749 || icode == CODE_FOR_spe_evslwi
10750 || icode == CODE_FOR_spe_evsrwis
10751 || icode == CODE_FOR_spe_evsubifw
10752 || icode == CODE_FOR_spe_evsrwiu)
10754 /* Only allow 5-bit unsigned literals. */
10756 if (TREE_CODE (arg1) != INTEGER_CST
10757 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10759 error ("argument 2 must be a 5-bit unsigned literal");
10765 || GET_MODE (target) != tmode
10766 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10767 target = gen_reg_rtx (tmode);
10769 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10770 op0 = copy_to_mode_reg (mode0, op0);
10771 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10772 op1 = copy_to_mode_reg (mode1, op1);
10774 pat = GEN_FCN (icode) (target, op0, op1);
10783 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10786 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10787 tree arg0 = CALL_EXPR_ARG (exp, 1);
10788 tree arg1 = CALL_EXPR_ARG (exp, 2);
10789 rtx op0 = expand_normal (arg0);
10790 rtx op1 = expand_normal (arg1);
10791 enum machine_mode tmode = SImode;
10792 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10793 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10796 if (TREE_CODE (cr6_form) != INTEGER_CST)
10798 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10802 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10804 gcc_assert (mode0 == mode1);
10806 /* If we have invalid arguments, bail out before generating bad rtl. */
10807 if (arg0 == error_mark_node || arg1 == error_mark_node)
10811 || GET_MODE (target) != tmode
10812 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10813 target = gen_reg_rtx (tmode);
10815 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10816 op0 = copy_to_mode_reg (mode0, op0);
10817 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10818 op1 = copy_to_mode_reg (mode1, op1);
10820 scratch = gen_reg_rtx (mode0);
10822 pat = GEN_FCN (icode) (scratch, op0, op1);
10827 /* The vec_any* and vec_all* predicates use the same opcodes for two
10828 different operations, but the bits in CR6 will be different
10829 depending on what information we want. So we have to play tricks
10830 with CR6 to get the right bits out.
10832 If you think this is disgusting, look at the specs for the
10833 AltiVec predicates. */
10835 switch (cr6_form_int)
10838 emit_insn (gen_cr6_test_for_zero (target));
10841 emit_insn (gen_cr6_test_for_zero_reverse (target));
10844 emit_insn (gen_cr6_test_for_lt (target));
10847 emit_insn (gen_cr6_test_for_lt_reverse (target));
10850 error ("argument 1 of __builtin_altivec_predicate is out of range");
10858 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10861 tree arg0 = CALL_EXPR_ARG (exp, 0);
10862 tree arg1 = CALL_EXPR_ARG (exp, 1);
10863 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10864 enum machine_mode mode0 = Pmode;
10865 enum machine_mode mode1 = Pmode;
10866 rtx op0 = expand_normal (arg0);
10867 rtx op1 = expand_normal (arg1);
10869 if (icode == CODE_FOR_nothing)
10870 /* Builtin not supported on this processor. */
10873 /* If we got invalid arguments bail out before generating bad rtl. */
10874 if (arg0 == error_mark_node || arg1 == error_mark_node)
10878 || GET_MODE (target) != tmode
10879 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10880 target = gen_reg_rtx (tmode);
10882 op1 = copy_to_mode_reg (mode1, op1);
10884 if (op0 == const0_rtx)
10886 addr = gen_rtx_MEM (tmode, op1);
10890 op0 = copy_to_mode_reg (mode0, op0);
10891 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10894 pat = GEN_FCN (icode) (target, addr);
10904 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10907 tree arg0 = CALL_EXPR_ARG (exp, 0);
10908 tree arg1 = CALL_EXPR_ARG (exp, 1);
10909 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10910 enum machine_mode mode0 = Pmode;
10911 enum machine_mode mode1 = Pmode;
10912 rtx op0 = expand_normal (arg0);
10913 rtx op1 = expand_normal (arg1);
10915 if (icode == CODE_FOR_nothing)
10916 /* Builtin not supported on this processor. */
10919 /* If we got invalid arguments bail out before generating bad rtl. */
10920 if (arg0 == error_mark_node || arg1 == error_mark_node)
10924 || GET_MODE (target) != tmode
10925 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10926 target = gen_reg_rtx (tmode);
10928 op1 = copy_to_mode_reg (mode1, op1);
10930 if (op0 == const0_rtx)
10932 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10936 op0 = copy_to_mode_reg (mode0, op0);
10937 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10940 pat = GEN_FCN (icode) (target, addr);
10950 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10952 tree arg0 = CALL_EXPR_ARG (exp, 0);
10953 tree arg1 = CALL_EXPR_ARG (exp, 1);
10954 tree arg2 = CALL_EXPR_ARG (exp, 2);
10955 rtx op0 = expand_normal (arg0);
10956 rtx op1 = expand_normal (arg1);
10957 rtx op2 = expand_normal (arg2);
10959 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10960 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10961 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10963 /* Invalid arguments. Bail before doing anything stoopid! */
10964 if (arg0 == error_mark_node
10965 || arg1 == error_mark_node
10966 || arg2 == error_mark_node)
10969 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10970 op0 = copy_to_mode_reg (mode2, op0);
10971 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10972 op1 = copy_to_mode_reg (mode0, op1);
10973 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10974 op2 = copy_to_mode_reg (mode1, op2);
10976 pat = GEN_FCN (icode) (op1, op2, op0);
10983 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10985 tree arg0 = CALL_EXPR_ARG (exp, 0);
10986 tree arg1 = CALL_EXPR_ARG (exp, 1);
10987 tree arg2 = CALL_EXPR_ARG (exp, 2);
10988 rtx op0 = expand_normal (arg0);
10989 rtx op1 = expand_normal (arg1);
10990 rtx op2 = expand_normal (arg2);
10992 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10993 enum machine_mode mode1 = Pmode;
10994 enum machine_mode mode2 = Pmode;
10996 /* Invalid arguments. Bail before doing anything stoopid! */
10997 if (arg0 == error_mark_node
10998 || arg1 == error_mark_node
10999 || arg2 == error_mark_node)
11002 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11003 op0 = copy_to_mode_reg (tmode, op0);
11005 op2 = copy_to_mode_reg (mode2, op2);
11007 if (op1 == const0_rtx)
11009 addr = gen_rtx_MEM (tmode, op2);
11013 op1 = copy_to_mode_reg (mode1, op1);
11014 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11017 pat = GEN_FCN (icode) (addr, op0);
11024 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11026 tree arg0 = CALL_EXPR_ARG (exp, 0);
11027 tree arg1 = CALL_EXPR_ARG (exp, 1);
11028 tree arg2 = CALL_EXPR_ARG (exp, 2);
11029 rtx op0 = expand_normal (arg0);
11030 rtx op1 = expand_normal (arg1);
11031 rtx op2 = expand_normal (arg2);
11033 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11034 enum machine_mode smode = insn_data[icode].operand[1].mode;
11035 enum machine_mode mode1 = Pmode;
11036 enum machine_mode mode2 = Pmode;
11038 /* Invalid arguments. Bail before doing anything stoopid! */
11039 if (arg0 == error_mark_node
11040 || arg1 == error_mark_node
11041 || arg2 == error_mark_node)
11044 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11045 op0 = copy_to_mode_reg (smode, op0);
11047 op2 = copy_to_mode_reg (mode2, op2);
11049 if (op1 == const0_rtx)
11051 addr = gen_rtx_MEM (tmode, op2);
11055 op1 = copy_to_mode_reg (mode1, op1);
11056 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11059 pat = GEN_FCN (icode) (addr, op0);
11066 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11069 tree arg0 = CALL_EXPR_ARG (exp, 0);
11070 tree arg1 = CALL_EXPR_ARG (exp, 1);
11071 tree arg2 = CALL_EXPR_ARG (exp, 2);
11072 rtx op0 = expand_normal (arg0);
11073 rtx op1 = expand_normal (arg1);
11074 rtx op2 = expand_normal (arg2);
11075 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11076 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11077 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11078 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11080 if (icode == CODE_FOR_nothing)
11081 /* Builtin not supported on this processor. */
11084 /* If we got invalid arguments bail out before generating bad rtl. */
11085 if (arg0 == error_mark_node
11086 || arg1 == error_mark_node
11087 || arg2 == error_mark_node)
11090 /* Check and prepare argument depending on the instruction code.
11092 Note that a switch statement instead of the sequence of tests
11093 would be incorrect as many of the CODE_FOR values could be
11094 CODE_FOR_nothing and that would yield multiple alternatives
11095 with identical values. We'd never reach here at runtime in
11097 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11098 || icode == CODE_FOR_altivec_vsldoi_v4si
11099 || icode == CODE_FOR_altivec_vsldoi_v8hi
11100 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11102 /* Only allow 4-bit unsigned literals. */
11104 if (TREE_CODE (arg2) != INTEGER_CST
11105 || TREE_INT_CST_LOW (arg2) & ~0xf)
11107 error ("argument 3 must be a 4-bit unsigned literal");
11111 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11112 || icode == CODE_FOR_vsx_xxpermdi_v2di
11113 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11114 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11115 || icode == CODE_FOR_vsx_xxsldwi_v4si
11116 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11117 || icode == CODE_FOR_vsx_xxsldwi_v2di
11118 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11120 /* Only allow 2-bit unsigned literals. */
11122 if (TREE_CODE (arg2) != INTEGER_CST
11123 || TREE_INT_CST_LOW (arg2) & ~0x3)
11125 error ("argument 3 must be a 2-bit unsigned literal");
11129 else if (icode == CODE_FOR_vsx_set_v2df
11130 || icode == CODE_FOR_vsx_set_v2di)
11132 /* Only allow 1-bit unsigned literals. */
11134 if (TREE_CODE (arg2) != INTEGER_CST
11135 || TREE_INT_CST_LOW (arg2) & ~0x1)
11137 error ("argument 3 must be a 1-bit unsigned literal");
11143 || GET_MODE (target) != tmode
11144 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11145 target = gen_reg_rtx (tmode);
11147 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11148 op0 = copy_to_mode_reg (mode0, op0);
11149 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11150 op1 = copy_to_mode_reg (mode1, op1);
11151 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11152 op2 = copy_to_mode_reg (mode2, op2);
11154 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11155 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11157 pat = GEN_FCN (icode) (target, op0, op1, op2);
11165 /* Expand the lvx builtins. */
11167 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11169 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11170 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11172 enum machine_mode tmode, mode0;
11174 enum insn_code icode;
11178 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11179 icode = CODE_FOR_vector_altivec_load_v16qi;
11181 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11182 icode = CODE_FOR_vector_altivec_load_v8hi;
11184 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11185 icode = CODE_FOR_vector_altivec_load_v4si;
11187 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11188 icode = CODE_FOR_vector_altivec_load_v4sf;
11190 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11191 icode = CODE_FOR_vector_altivec_load_v2df;
11193 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11194 icode = CODE_FOR_vector_altivec_load_v2di;
11197 *expandedp = false;
11203 arg0 = CALL_EXPR_ARG (exp, 0);
11204 op0 = expand_normal (arg0);
11205 tmode = insn_data[icode].operand[0].mode;
11206 mode0 = insn_data[icode].operand[1].mode;
11209 || GET_MODE (target) != tmode
11210 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11211 target = gen_reg_rtx (tmode);
11213 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11214 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11216 pat = GEN_FCN (icode) (target, op0);
11223 /* Expand the stvx builtins. */
11225 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11228 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11229 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11231 enum machine_mode mode0, mode1;
11233 enum insn_code icode;
11237 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11238 icode = CODE_FOR_vector_altivec_store_v16qi;
11240 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11241 icode = CODE_FOR_vector_altivec_store_v8hi;
11243 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11244 icode = CODE_FOR_vector_altivec_store_v4si;
11246 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11247 icode = CODE_FOR_vector_altivec_store_v4sf;
11249 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11250 icode = CODE_FOR_vector_altivec_store_v2df;
11252 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11253 icode = CODE_FOR_vector_altivec_store_v2di;
11256 *expandedp = false;
11260 arg0 = CALL_EXPR_ARG (exp, 0);
11261 arg1 = CALL_EXPR_ARG (exp, 1);
11262 op0 = expand_normal (arg0);
11263 op1 = expand_normal (arg1);
11264 mode0 = insn_data[icode].operand[0].mode;
11265 mode1 = insn_data[icode].operand[1].mode;
11267 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11268 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11269 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11270 op1 = copy_to_mode_reg (mode1, op1);
11272 pat = GEN_FCN (icode) (op0, op1);
11280 /* Expand the dst builtins. */
11282 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11285 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11286 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11287 tree arg0, arg1, arg2;
11288 enum machine_mode mode0, mode1;
11289 rtx pat, op0, op1, op2;
11290 const struct builtin_description *d;
11293 *expandedp = false;
11295 /* Handle DST variants. */
11297 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11298 if (d->code == fcode)
11300 arg0 = CALL_EXPR_ARG (exp, 0);
11301 arg1 = CALL_EXPR_ARG (exp, 1);
11302 arg2 = CALL_EXPR_ARG (exp, 2);
11303 op0 = expand_normal (arg0);
11304 op1 = expand_normal (arg1);
11305 op2 = expand_normal (arg2);
11306 mode0 = insn_data[d->icode].operand[0].mode;
11307 mode1 = insn_data[d->icode].operand[1].mode;
11309 /* Invalid arguments, bail out before generating bad rtl. */
11310 if (arg0 == error_mark_node
11311 || arg1 == error_mark_node
11312 || arg2 == error_mark_node)
11317 if (TREE_CODE (arg2) != INTEGER_CST
11318 || TREE_INT_CST_LOW (arg2) & ~0x3)
11320 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11324 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11325 op0 = copy_to_mode_reg (Pmode, op0);
11326 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11327 op1 = copy_to_mode_reg (mode1, op1);
11329 pat = GEN_FCN (d->icode) (op0, op1, op2);
11339 /* Expand vec_init builtin. */
11341 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11343 enum machine_mode tmode = TYPE_MODE (type);
11344 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11345 int i, n_elt = GET_MODE_NUNITS (tmode);
11346 rtvec v = rtvec_alloc (n_elt);
11348 gcc_assert (VECTOR_MODE_P (tmode));
11349 gcc_assert (n_elt == call_expr_nargs (exp));
11351 for (i = 0; i < n_elt; ++i)
11353 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11354 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11357 if (!target || !register_operand (target, tmode))
11358 target = gen_reg_rtx (tmode);
11360 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11364 /* Return the integer constant in ARG. Constrain it to be in the range
11365 of the subparts of VEC_TYPE; issue an error if not. */
11368 get_element_number (tree vec_type, tree arg)
11370 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11372 if (!host_integerp (arg, 1)
11373 || (elt = tree_low_cst (arg, 1), elt > max))
11375 error ("selector must be an integer constant in the range 0..%wi", max);
11382 /* Expand vec_set builtin. */
11384 altivec_expand_vec_set_builtin (tree exp)
11386 enum machine_mode tmode, mode1;
11387 tree arg0, arg1, arg2;
11391 arg0 = CALL_EXPR_ARG (exp, 0);
11392 arg1 = CALL_EXPR_ARG (exp, 1);
11393 arg2 = CALL_EXPR_ARG (exp, 2);
11395 tmode = TYPE_MODE (TREE_TYPE (arg0));
11396 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11397 gcc_assert (VECTOR_MODE_P (tmode));
11399 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11400 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11401 elt = get_element_number (TREE_TYPE (arg0), arg2);
11403 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11404 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11406 op0 = force_reg (tmode, op0);
11407 op1 = force_reg (mode1, op1);
11409 rs6000_expand_vector_set (op0, op1, elt);
11414 /* Expand vec_ext builtin. */
11416 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11418 enum machine_mode tmode, mode0;
11423 arg0 = CALL_EXPR_ARG (exp, 0);
11424 arg1 = CALL_EXPR_ARG (exp, 1);
11426 op0 = expand_normal (arg0);
11427 elt = get_element_number (TREE_TYPE (arg0), arg1);
11429 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11430 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11431 gcc_assert (VECTOR_MODE_P (mode0));
11433 op0 = force_reg (mode0, op0);
11435 if (optimize || !target || !register_operand (target, tmode))
11436 target = gen_reg_rtx (tmode);
11438 rs6000_expand_vector_extract (target, op0, elt);
11443 /* Expand the builtin in EXP and store the result in TARGET. Store
11444 true in *EXPANDEDP if we found a builtin to expand. */
11446 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11448 const struct builtin_description *d;
11449 const struct builtin_description_predicates *dp;
11451 enum insn_code icode;
11452 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11455 enum machine_mode tmode, mode0;
11456 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11458 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11459 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11460 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11461 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11464 error ("unresolved overload for Altivec builtin %qF", fndecl);
11468 target = altivec_expand_ld_builtin (exp, target, expandedp);
11472 target = altivec_expand_st_builtin (exp, target, expandedp);
11476 target = altivec_expand_dst_builtin (exp, target, expandedp);
11484 case ALTIVEC_BUILTIN_STVX:
11485 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11486 case ALTIVEC_BUILTIN_STVEBX:
11487 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11488 case ALTIVEC_BUILTIN_STVEHX:
11489 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11490 case ALTIVEC_BUILTIN_STVEWX:
11491 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11492 case ALTIVEC_BUILTIN_STVXL:
11493 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11495 case ALTIVEC_BUILTIN_STVLX:
11496 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11497 case ALTIVEC_BUILTIN_STVLXL:
11498 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11499 case ALTIVEC_BUILTIN_STVRX:
11500 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11501 case ALTIVEC_BUILTIN_STVRXL:
11502 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11504 case VSX_BUILTIN_STXVD2X_V2DF:
11505 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11506 case VSX_BUILTIN_STXVD2X_V2DI:
11507 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11508 case VSX_BUILTIN_STXVW4X_V4SF:
11509 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11510 case VSX_BUILTIN_STXVW4X_V4SI:
11511 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11512 case VSX_BUILTIN_STXVW4X_V8HI:
11513 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11514 case VSX_BUILTIN_STXVW4X_V16QI:
11515 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11517 case ALTIVEC_BUILTIN_MFVSCR:
11518 icode = CODE_FOR_altivec_mfvscr;
11519 tmode = insn_data[icode].operand[0].mode;
11522 || GET_MODE (target) != tmode
11523 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11524 target = gen_reg_rtx (tmode);
11526 pat = GEN_FCN (icode) (target);
11532 case ALTIVEC_BUILTIN_MTVSCR:
11533 icode = CODE_FOR_altivec_mtvscr;
11534 arg0 = CALL_EXPR_ARG (exp, 0);
11535 op0 = expand_normal (arg0);
11536 mode0 = insn_data[icode].operand[0].mode;
11538 /* If we got invalid arguments bail out before generating bad rtl. */
11539 if (arg0 == error_mark_node)
11542 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11543 op0 = copy_to_mode_reg (mode0, op0);
11545 pat = GEN_FCN (icode) (op0);
11550 case ALTIVEC_BUILTIN_DSSALL:
11551 emit_insn (gen_altivec_dssall ());
11554 case ALTIVEC_BUILTIN_DSS:
11555 icode = CODE_FOR_altivec_dss;
11556 arg0 = CALL_EXPR_ARG (exp, 0);
11558 op0 = expand_normal (arg0);
11559 mode0 = insn_data[icode].operand[0].mode;
11561 /* If we got invalid arguments bail out before generating bad rtl. */
11562 if (arg0 == error_mark_node)
11565 if (TREE_CODE (arg0) != INTEGER_CST
11566 || TREE_INT_CST_LOW (arg0) & ~0x3)
11568 error ("argument to dss must be a 2-bit unsigned literal");
11572 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11573 op0 = copy_to_mode_reg (mode0, op0);
11575 emit_insn (gen_altivec_dss (op0));
11578 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11579 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11580 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11581 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11582 case VSX_BUILTIN_VEC_INIT_V2DF:
11583 case VSX_BUILTIN_VEC_INIT_V2DI:
11584 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11586 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11587 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11588 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11589 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11590 case VSX_BUILTIN_VEC_SET_V2DF:
11591 case VSX_BUILTIN_VEC_SET_V2DI:
11592 return altivec_expand_vec_set_builtin (exp);
11594 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11595 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11596 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11597 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11598 case VSX_BUILTIN_VEC_EXT_V2DF:
11599 case VSX_BUILTIN_VEC_EXT_V2DI:
11600 return altivec_expand_vec_ext_builtin (exp, target);
11604 /* Fall through. */
11607 /* Expand abs* operations. */
11609 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11610 if (d->code == fcode)
11611 return altivec_expand_abs_builtin (d->icode, exp, target);
11613 /* Expand the AltiVec predicates. */
11614 dp = bdesc_altivec_preds;
11615 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11616 if (dp->code == fcode)
11617 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11619 /* LV* are funky. We initialized them differently. */
11622 case ALTIVEC_BUILTIN_LVSL:
11623 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11624 exp, target, false);
11625 case ALTIVEC_BUILTIN_LVSR:
11626 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11627 exp, target, false);
11628 case ALTIVEC_BUILTIN_LVEBX:
11629 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11630 exp, target, false);
11631 case ALTIVEC_BUILTIN_LVEHX:
11632 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11633 exp, target, false);
11634 case ALTIVEC_BUILTIN_LVEWX:
11635 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11636 exp, target, false);
11637 case ALTIVEC_BUILTIN_LVXL:
11638 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11639 exp, target, false);
11640 case ALTIVEC_BUILTIN_LVX:
11641 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11642 exp, target, false);
11643 case ALTIVEC_BUILTIN_LVLX:
11644 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11645 exp, target, true);
11646 case ALTIVEC_BUILTIN_LVLXL:
11647 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11648 exp, target, true);
11649 case ALTIVEC_BUILTIN_LVRX:
11650 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11651 exp, target, true);
11652 case ALTIVEC_BUILTIN_LVRXL:
11653 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11654 exp, target, true);
11655 case VSX_BUILTIN_LXVD2X_V2DF:
11656 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11657 exp, target, false);
11658 case VSX_BUILTIN_LXVD2X_V2DI:
11659 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11660 exp, target, false);
11661 case VSX_BUILTIN_LXVW4X_V4SF:
11662 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11663 exp, target, false);
11664 case VSX_BUILTIN_LXVW4X_V4SI:
11665 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11666 exp, target, false);
11667 case VSX_BUILTIN_LXVW4X_V8HI:
11668 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11669 exp, target, false);
11670 case VSX_BUILTIN_LXVW4X_V16QI:
11671 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11672 exp, target, false);
11676 /* Fall through. */
11679 *expandedp = false;
11683 /* Expand the builtin in EXP and store the result in TARGET. Store
11684 true in *EXPANDEDP if we found a builtin to expand. */
11686 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11688 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11689 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11690 const struct builtin_description *d;
11697 case PAIRED_BUILTIN_STX:
11698 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11699 case PAIRED_BUILTIN_LX:
11700 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11703 /* Fall through. */
11706 /* Expand the paired predicates. */
11707 d = bdesc_paired_preds;
11708 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11709 if (d->code == fcode)
11710 return paired_expand_predicate_builtin (d->icode, exp, target);
11712 *expandedp = false;
11716 /* Binops that need to be initialized manually, but can be expanded
11717 automagically by rs6000_expand_binop_builtin. */
11718 static struct builtin_description bdesc_2arg_spe[] =
11720 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11721 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11722 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11723 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11724 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11725 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11726 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11727 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11728 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11729 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11730 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11731 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11732 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11733 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11734 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11735 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11736 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11737 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11738 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11739 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11740 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11741 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11744 /* Expand the builtin in EXP and store the result in TARGET. Store
11745 true in *EXPANDEDP if we found a builtin to expand.
11747 This expands the SPE builtins that are not simple unary and binary
11750 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11752 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11754 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11755 enum insn_code icode;
11756 enum machine_mode tmode, mode0;
11758 struct builtin_description *d;
11763 /* Syntax check for a 5-bit unsigned immediate. */
11766 case SPE_BUILTIN_EVSTDD:
11767 case SPE_BUILTIN_EVSTDH:
11768 case SPE_BUILTIN_EVSTDW:
11769 case SPE_BUILTIN_EVSTWHE:
11770 case SPE_BUILTIN_EVSTWHO:
11771 case SPE_BUILTIN_EVSTWWE:
11772 case SPE_BUILTIN_EVSTWWO:
11773 arg1 = CALL_EXPR_ARG (exp, 2);
11774 if (TREE_CODE (arg1) != INTEGER_CST
11775 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11777 error ("argument 2 must be a 5-bit unsigned literal");
11785 /* The evsplat*i instructions are not quite generic. */
11788 case SPE_BUILTIN_EVSPLATFI:
11789 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11791 case SPE_BUILTIN_EVSPLATI:
11792 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11798 d = (struct builtin_description *) bdesc_2arg_spe;
11799 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11800 if (d->code == fcode)
11801 return rs6000_expand_binop_builtin (d->icode, exp, target);
11803 d = (struct builtin_description *) bdesc_spe_predicates;
11804 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11805 if (d->code == fcode)
11806 return spe_expand_predicate_builtin (d->icode, exp, target);
11808 d = (struct builtin_description *) bdesc_spe_evsel;
11809 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11810 if (d->code == fcode)
11811 return spe_expand_evsel_builtin (d->icode, exp, target);
11815 case SPE_BUILTIN_EVSTDDX:
11816 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11817 case SPE_BUILTIN_EVSTDHX:
11818 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11819 case SPE_BUILTIN_EVSTDWX:
11820 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11821 case SPE_BUILTIN_EVSTWHEX:
11822 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11823 case SPE_BUILTIN_EVSTWHOX:
11824 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11825 case SPE_BUILTIN_EVSTWWEX:
11826 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11827 case SPE_BUILTIN_EVSTWWOX:
11828 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11829 case SPE_BUILTIN_EVSTDD:
11830 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11831 case SPE_BUILTIN_EVSTDH:
11832 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11833 case SPE_BUILTIN_EVSTDW:
11834 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11835 case SPE_BUILTIN_EVSTWHE:
11836 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11837 case SPE_BUILTIN_EVSTWHO:
11838 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11839 case SPE_BUILTIN_EVSTWWE:
11840 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11841 case SPE_BUILTIN_EVSTWWO:
11842 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11843 case SPE_BUILTIN_MFSPEFSCR:
11844 icode = CODE_FOR_spe_mfspefscr;
11845 tmode = insn_data[icode].operand[0].mode;
11848 || GET_MODE (target) != tmode
11849 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11850 target = gen_reg_rtx (tmode);
11852 pat = GEN_FCN (icode) (target);
11857 case SPE_BUILTIN_MTSPEFSCR:
11858 icode = CODE_FOR_spe_mtspefscr;
11859 arg0 = CALL_EXPR_ARG (exp, 0);
11860 op0 = expand_normal (arg0);
11861 mode0 = insn_data[icode].operand[0].mode;
11863 if (arg0 == error_mark_node)
11866 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11867 op0 = copy_to_mode_reg (mode0, op0);
11869 pat = GEN_FCN (icode) (op0);
11877 *expandedp = false;
11882 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11884 rtx pat, scratch, tmp;
11885 tree form = CALL_EXPR_ARG (exp, 0);
11886 tree arg0 = CALL_EXPR_ARG (exp, 1);
11887 tree arg1 = CALL_EXPR_ARG (exp, 2);
11888 rtx op0 = expand_normal (arg0);
11889 rtx op1 = expand_normal (arg1);
11890 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11891 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11893 enum rtx_code code;
11895 if (TREE_CODE (form) != INTEGER_CST)
11897 error ("argument 1 of __builtin_paired_predicate must be a constant");
11901 form_int = TREE_INT_CST_LOW (form);
11903 gcc_assert (mode0 == mode1);
11905 if (arg0 == error_mark_node || arg1 == error_mark_node)
11909 || GET_MODE (target) != SImode
11910 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11911 target = gen_reg_rtx (SImode);
11912 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11913 op0 = copy_to_mode_reg (mode0, op0);
11914 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11915 op1 = copy_to_mode_reg (mode1, op1);
11917 scratch = gen_reg_rtx (CCFPmode);
11919 pat = GEN_FCN (icode) (scratch, op0, op1);
11941 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11944 error ("argument 1 of __builtin_paired_predicate is out of range");
11948 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11949 emit_move_insn (target, tmp);
11954 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11956 rtx pat, scratch, tmp;
11957 tree form = CALL_EXPR_ARG (exp, 0);
11958 tree arg0 = CALL_EXPR_ARG (exp, 1);
11959 tree arg1 = CALL_EXPR_ARG (exp, 2);
11960 rtx op0 = expand_normal (arg0);
11961 rtx op1 = expand_normal (arg1);
11962 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11963 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11965 enum rtx_code code;
11967 if (TREE_CODE (form) != INTEGER_CST)
11969 error ("argument 1 of __builtin_spe_predicate must be a constant");
11973 form_int = TREE_INT_CST_LOW (form);
11975 gcc_assert (mode0 == mode1);
11977 if (arg0 == error_mark_node || arg1 == error_mark_node)
11981 || GET_MODE (target) != SImode
11982 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11983 target = gen_reg_rtx (SImode);
11985 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11986 op0 = copy_to_mode_reg (mode0, op0);
11987 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11988 op1 = copy_to_mode_reg (mode1, op1);
11990 scratch = gen_reg_rtx (CCmode);
11992 pat = GEN_FCN (icode) (scratch, op0, op1);
11997 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11998 _lower_. We use one compare, but look in different bits of the
11999 CR for each variant.
12001 There are 2 elements in each SPE simd type (upper/lower). The CR
12002 bits are set as follows:
12004 BIT0 | BIT 1 | BIT 2 | BIT 3
12005 U | L | (U | L) | (U & L)
12007 So, for an "all" relationship, BIT 3 would be set.
12008 For an "any" relationship, BIT 2 would be set. Etc.
12010 Following traditional nomenclature, these bits map to:
12012 BIT0 | BIT 1 | BIT 2 | BIT 3
12015 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12020 /* All variant. OV bit. */
12022 /* We need to get to the OV bit, which is the ORDERED bit. We
12023 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12024 that's ugly and will make validate_condition_mode die.
12025 So let's just use another pattern. */
12026 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12028 /* Any variant. EQ bit. */
12032 /* Upper variant. LT bit. */
12036 /* Lower variant. GT bit. */
12041 error ("argument 1 of __builtin_spe_predicate is out of range");
12045 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12046 emit_move_insn (target, tmp);
12051 /* The evsel builtins look like this:
12053 e = __builtin_spe_evsel_OP (a, b, c, d);
12055 and work like this:
12057 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12058 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12062 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12065 tree arg0 = CALL_EXPR_ARG (exp, 0);
12066 tree arg1 = CALL_EXPR_ARG (exp, 1);
12067 tree arg2 = CALL_EXPR_ARG (exp, 2);
12068 tree arg3 = CALL_EXPR_ARG (exp, 3);
12069 rtx op0 = expand_normal (arg0);
12070 rtx op1 = expand_normal (arg1);
12071 rtx op2 = expand_normal (arg2);
12072 rtx op3 = expand_normal (arg3);
12073 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12074 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12076 gcc_assert (mode0 == mode1);
12078 if (arg0 == error_mark_node || arg1 == error_mark_node
12079 || arg2 == error_mark_node || arg3 == error_mark_node)
12083 || GET_MODE (target) != mode0
12084 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12085 target = gen_reg_rtx (mode0);
12087 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12088 op0 = copy_to_mode_reg (mode0, op0);
12089 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12090 op1 = copy_to_mode_reg (mode0, op1);
12091 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12092 op2 = copy_to_mode_reg (mode0, op2);
12093 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12094 op3 = copy_to_mode_reg (mode0, op3);
12096 /* Generate the compare. */
12097 scratch = gen_reg_rtx (CCmode);
12098 pat = GEN_FCN (icode) (scratch, op0, op1);
12103 if (mode0 == V2SImode)
12104 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12106 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12111 /* Expand an expression EXP that calls a built-in function,
12112 with result going to TARGET if that's convenient
12113 (and in mode MODE if that's convenient).
12114 SUBTARGET may be used as the target for computing one of EXP's operands.
12115 IGNORE is nonzero if the value is to be ignored. */
12118 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12119 enum machine_mode mode ATTRIBUTE_UNUSED,
12120 int ignore ATTRIBUTE_UNUSED)
12122 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12123 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12124 const struct builtin_description *d;
12131 case RS6000_BUILTIN_RECIP:
12132 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12134 case RS6000_BUILTIN_RECIPF:
12135 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12137 case RS6000_BUILTIN_RSQRTF:
12138 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12140 case RS6000_BUILTIN_RSQRT:
12141 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12143 case RS6000_BUILTIN_BSWAP_HI:
12144 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12146 case POWER7_BUILTIN_BPERMD:
12147 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12148 ? CODE_FOR_bpermd_di
12149 : CODE_FOR_bpermd_si), exp, target);
12151 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12152 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12154 int icode = (int) CODE_FOR_altivec_lvsr;
12155 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12156 enum machine_mode mode = insn_data[icode].operand[1].mode;
12160 gcc_assert (TARGET_ALTIVEC);
12162 arg = CALL_EXPR_ARG (exp, 0);
12163 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12164 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12165 addr = memory_address (mode, op);
12166 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12170 /* For the load case need to negate the address. */
12171 op = gen_reg_rtx (GET_MODE (addr));
12172 emit_insn (gen_rtx_SET (VOIDmode, op,
12173 gen_rtx_NEG (GET_MODE (addr), addr)));
12175 op = gen_rtx_MEM (mode, op);
12178 || GET_MODE (target) != tmode
12179 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12180 target = gen_reg_rtx (tmode);
12182 /*pat = gen_altivec_lvsr (target, op);*/
12183 pat = GEN_FCN (icode) (target, op);
12191 case ALTIVEC_BUILTIN_VCFUX:
12192 case ALTIVEC_BUILTIN_VCFSX:
12193 case ALTIVEC_BUILTIN_VCTUXS:
12194 case ALTIVEC_BUILTIN_VCTSXS:
12195 /* FIXME: There's got to be a nicer way to handle this case than
12196 constructing a new CALL_EXPR. */
12197 if (call_expr_nargs (exp) == 1)
12199 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12200 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12208 if (TARGET_ALTIVEC)
12210 ret = altivec_expand_builtin (exp, target, &success);
12217 ret = spe_expand_builtin (exp, target, &success);
12222 if (TARGET_PAIRED_FLOAT)
12224 ret = paired_expand_builtin (exp, target, &success);
12230 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12232 /* Handle simple unary operations. */
12233 d = (struct builtin_description *) bdesc_1arg;
12234 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12235 if (d->code == fcode)
12236 return rs6000_expand_unop_builtin (d->icode, exp, target);
12238 /* Handle simple binary operations. */
12239 d = (struct builtin_description *) bdesc_2arg;
12240 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12241 if (d->code == fcode)
12242 return rs6000_expand_binop_builtin (d->icode, exp, target);
12244 /* Handle simple ternary operations. */
12246 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12247 if (d->code == fcode)
12248 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12250 gcc_unreachable ();
12254 rs6000_init_builtins (void)
12259 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12260 V2SF_type_node = build_vector_type (float_type_node, 2);
12261 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12262 V2DF_type_node = build_vector_type (double_type_node, 2);
12263 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12264 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12265 V4SF_type_node = build_vector_type (float_type_node, 4);
12266 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12267 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12269 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12270 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12271 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12272 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12274 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12275 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12276 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12277 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12279 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12280 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12281 'vector unsigned short'. */
12283 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12284 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12285 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12286 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12287 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12289 long_integer_type_internal_node = long_integer_type_node;
12290 long_unsigned_type_internal_node = long_unsigned_type_node;
12291 long_long_integer_type_internal_node = long_long_integer_type_node;
12292 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12293 intQI_type_internal_node = intQI_type_node;
12294 uintQI_type_internal_node = unsigned_intQI_type_node;
12295 intHI_type_internal_node = intHI_type_node;
12296 uintHI_type_internal_node = unsigned_intHI_type_node;
12297 intSI_type_internal_node = intSI_type_node;
12298 uintSI_type_internal_node = unsigned_intSI_type_node;
12299 intDI_type_internal_node = intDI_type_node;
12300 uintDI_type_internal_node = unsigned_intDI_type_node;
12301 float_type_internal_node = float_type_node;
12302 double_type_internal_node = double_type_node;
12303 void_type_internal_node = void_type_node;
12305 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12307 builtin_mode_to_type[QImode][0] = integer_type_node;
12308 builtin_mode_to_type[HImode][0] = integer_type_node;
12309 builtin_mode_to_type[SImode][0] = intSI_type_node;
12310 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12311 builtin_mode_to_type[DImode][0] = intDI_type_node;
12312 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12313 builtin_mode_to_type[SFmode][0] = float_type_node;
12314 builtin_mode_to_type[DFmode][0] = double_type_node;
12315 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12316 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12317 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12318 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12319 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12320 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12321 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12322 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12323 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12324 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12325 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12326 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12327 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12329 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12330 get_identifier ("__bool char"),
12331 bool_char_type_node);
12332 TYPE_NAME (bool_char_type_node) = tdecl;
12333 (*lang_hooks.decls.pushdecl) (tdecl);
12334 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12335 get_identifier ("__bool short"),
12336 bool_short_type_node);
12337 TYPE_NAME (bool_short_type_node) = tdecl;
12338 (*lang_hooks.decls.pushdecl) (tdecl);
12339 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12340 get_identifier ("__bool int"),
12341 bool_int_type_node);
12342 TYPE_NAME (bool_int_type_node) = tdecl;
12343 (*lang_hooks.decls.pushdecl) (tdecl);
12344 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12346 TYPE_NAME (pixel_type_node) = tdecl;
12347 (*lang_hooks.decls.pushdecl) (tdecl);
12349 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12350 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12351 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12352 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12353 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12355 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12356 get_identifier ("__vector unsigned char"),
12357 unsigned_V16QI_type_node);
12358 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12359 (*lang_hooks.decls.pushdecl) (tdecl);
12360 tdecl = build_decl (BUILTINS_LOCATION,
12361 TYPE_DECL, get_identifier ("__vector signed char"),
12363 TYPE_NAME (V16QI_type_node) = tdecl;
12364 (*lang_hooks.decls.pushdecl) (tdecl);
12365 tdecl = build_decl (BUILTINS_LOCATION,
12366 TYPE_DECL, get_identifier ("__vector __bool char"),
12367 bool_V16QI_type_node);
12368 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12369 (*lang_hooks.decls.pushdecl) (tdecl);
12371 tdecl = build_decl (BUILTINS_LOCATION,
12372 TYPE_DECL, get_identifier ("__vector unsigned short"),
12373 unsigned_V8HI_type_node);
12374 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12375 (*lang_hooks.decls.pushdecl) (tdecl);
12376 tdecl = build_decl (BUILTINS_LOCATION,
12377 TYPE_DECL, get_identifier ("__vector signed short"),
12379 TYPE_NAME (V8HI_type_node) = tdecl;
12380 (*lang_hooks.decls.pushdecl) (tdecl);
12381 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12382 get_identifier ("__vector __bool short"),
12383 bool_V8HI_type_node);
12384 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12385 (*lang_hooks.decls.pushdecl) (tdecl);
12387 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12388 get_identifier ("__vector unsigned int"),
12389 unsigned_V4SI_type_node);
12390 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12391 (*lang_hooks.decls.pushdecl) (tdecl);
12392 tdecl = build_decl (BUILTINS_LOCATION,
12393 TYPE_DECL, get_identifier ("__vector signed int"),
12395 TYPE_NAME (V4SI_type_node) = tdecl;
12396 (*lang_hooks.decls.pushdecl) (tdecl);
12397 tdecl = build_decl (BUILTINS_LOCATION,
12398 TYPE_DECL, get_identifier ("__vector __bool int"),
12399 bool_V4SI_type_node);
12400 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12401 (*lang_hooks.decls.pushdecl) (tdecl);
12403 tdecl = build_decl (BUILTINS_LOCATION,
12404 TYPE_DECL, get_identifier ("__vector float"),
12406 TYPE_NAME (V4SF_type_node) = tdecl;
12407 (*lang_hooks.decls.pushdecl) (tdecl);
12408 tdecl = build_decl (BUILTINS_LOCATION,
12409 TYPE_DECL, get_identifier ("__vector __pixel"),
12410 pixel_V8HI_type_node);
12411 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12412 (*lang_hooks.decls.pushdecl) (tdecl);
12416 tdecl = build_decl (BUILTINS_LOCATION,
12417 TYPE_DECL, get_identifier ("__vector double"),
12419 TYPE_NAME (V2DF_type_node) = tdecl;
12420 (*lang_hooks.decls.pushdecl) (tdecl);
12422 tdecl = build_decl (BUILTINS_LOCATION,
12423 TYPE_DECL, get_identifier ("__vector long"),
12425 TYPE_NAME (V2DI_type_node) = tdecl;
12426 (*lang_hooks.decls.pushdecl) (tdecl);
12428 tdecl = build_decl (BUILTINS_LOCATION,
12429 TYPE_DECL, get_identifier ("__vector unsigned long"),
12430 unsigned_V2DI_type_node);
12431 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12432 (*lang_hooks.decls.pushdecl) (tdecl);
12434 tdecl = build_decl (BUILTINS_LOCATION,
12435 TYPE_DECL, get_identifier ("__vector __bool long"),
12436 bool_V2DI_type_node);
12437 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12438 (*lang_hooks.decls.pushdecl) (tdecl);
12441 if (TARGET_PAIRED_FLOAT)
12442 paired_init_builtins ();
12444 spe_init_builtins ();
12445 if (TARGET_ALTIVEC)
12446 altivec_init_builtins ();
12447 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12448 rs6000_common_init_builtins ();
12451 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12452 RS6000_BUILTIN_RECIP,
12453 "__builtin_recipdiv");
12454 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12455 RS6000_BUILTIN_RECIP);
12459 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12460 RS6000_BUILTIN_RECIPF,
12461 "__builtin_recipdivf");
12462 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12463 RS6000_BUILTIN_RECIPF);
12465 if (TARGET_FRSQRTE)
12467 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12468 RS6000_BUILTIN_RSQRT,
12469 "__builtin_rsqrt");
12470 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12471 RS6000_BUILTIN_RSQRT);
12473 if (TARGET_FRSQRTES)
12475 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12476 RS6000_BUILTIN_RSQRTF,
12477 "__builtin_rsqrtf");
12478 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12479 RS6000_BUILTIN_RSQRTF);
12481 if (TARGET_POPCNTD)
12483 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12484 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12485 POWER7_BUILTIN_BPERMD,
12486 "__builtin_bpermd");
12487 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12488 POWER7_BUILTIN_BPERMD);
12490 if (TARGET_POWERPC)
12492 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12493 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12494 unsigned_intHI_type_node,
12496 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12497 RS6000_BUILTIN_BSWAP_HI);
12501 /* AIX libm provides clog as __clog. */
12502 if (built_in_decls [BUILT_IN_CLOG])
12503 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12506 #ifdef SUBTARGET_INIT_BUILTINS
12507 SUBTARGET_INIT_BUILTINS;
12511 /* Returns the rs6000 builtin decl for CODE. */
12514 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12516 if (code >= RS6000_BUILTIN_COUNT)
12517 return error_mark_node;
12519 return rs6000_builtin_decls[code];
12522 /* Search through a set of builtins and enable the mask bits.
12523 DESC is an array of builtins.
12524 SIZE is the total number of builtins.
12525 START is the builtin enum at which to start.
12526 END is the builtin enum at which to end. */
12528 enable_mask_for_builtins (struct builtin_description *desc, int size,
12529 enum rs6000_builtins start,
12530 enum rs6000_builtins end)
12534 for (i = 0; i < size; ++i)
12535 if (desc[i].code == start)
12541 for (; i < size; ++i)
12543 /* Flip all the bits on. */
12544 desc[i].mask = target_flags;
12545 if (desc[i].code == end)
12551 spe_init_builtins (void)
12553 tree puint_type_node = build_pointer_type (unsigned_type_node);
12554 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12555 struct builtin_description *d;
12558 tree v2si_ftype_4_v2si
12559 = build_function_type_list (opaque_V2SI_type_node,
12560 opaque_V2SI_type_node,
12561 opaque_V2SI_type_node,
12562 opaque_V2SI_type_node,
12563 opaque_V2SI_type_node,
12566 tree v2sf_ftype_4_v2sf
12567 = build_function_type_list (opaque_V2SF_type_node,
12568 opaque_V2SF_type_node,
12569 opaque_V2SF_type_node,
12570 opaque_V2SF_type_node,
12571 opaque_V2SF_type_node,
12574 tree int_ftype_int_v2si_v2si
12575 = build_function_type_list (integer_type_node,
12577 opaque_V2SI_type_node,
12578 opaque_V2SI_type_node,
12581 tree int_ftype_int_v2sf_v2sf
12582 = build_function_type_list (integer_type_node,
12584 opaque_V2SF_type_node,
12585 opaque_V2SF_type_node,
12588 tree void_ftype_v2si_puint_int
12589 = build_function_type_list (void_type_node,
12590 opaque_V2SI_type_node,
12595 tree void_ftype_v2si_puint_char
12596 = build_function_type_list (void_type_node,
12597 opaque_V2SI_type_node,
12602 tree void_ftype_v2si_pv2si_int
12603 = build_function_type_list (void_type_node,
12604 opaque_V2SI_type_node,
12605 opaque_p_V2SI_type_node,
12609 tree void_ftype_v2si_pv2si_char
12610 = build_function_type_list (void_type_node,
12611 opaque_V2SI_type_node,
12612 opaque_p_V2SI_type_node,
12616 tree void_ftype_int
12617 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12619 tree int_ftype_void
12620 = build_function_type_list (integer_type_node, NULL_TREE);
12622 tree v2si_ftype_pv2si_int
12623 = build_function_type_list (opaque_V2SI_type_node,
12624 opaque_p_V2SI_type_node,
12628 tree v2si_ftype_puint_int
12629 = build_function_type_list (opaque_V2SI_type_node,
12634 tree v2si_ftype_pushort_int
12635 = build_function_type_list (opaque_V2SI_type_node,
12640 tree v2si_ftype_signed_char
12641 = build_function_type_list (opaque_V2SI_type_node,
12642 signed_char_type_node,
12645 /* The initialization of the simple binary and unary builtins is
12646 done in rs6000_common_init_builtins, but we have to enable the
12647 mask bits here manually because we have run out of `target_flags'
12648 bits. We really need to redesign this mask business. */
12650 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12651 ARRAY_SIZE (bdesc_2arg),
12652 SPE_BUILTIN_EVADDW,
12653 SPE_BUILTIN_EVXOR);
12654 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12655 ARRAY_SIZE (bdesc_1arg),
12657 SPE_BUILTIN_EVSUBFUSIAAW);
12658 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12659 ARRAY_SIZE (bdesc_spe_predicates),
12660 SPE_BUILTIN_EVCMPEQ,
12661 SPE_BUILTIN_EVFSTSTLT);
12662 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12663 ARRAY_SIZE (bdesc_spe_evsel),
12664 SPE_BUILTIN_EVSEL_CMPGTS,
12665 SPE_BUILTIN_EVSEL_FSTSTEQ);
12667 (*lang_hooks.decls.pushdecl)
12668 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12669 get_identifier ("__ev64_opaque__"),
12670 opaque_V2SI_type_node));
12672 /* Initialize irregular SPE builtins. */
12674 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12675 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12676 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12677 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12678 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12679 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12680 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12681 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12682 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12683 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12684 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12685 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12686 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12687 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12688 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12689 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12690 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12691 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12694 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12695 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12696 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12697 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12698 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12699 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12700 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12701 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12702 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12703 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12704 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12705 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12706 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12707 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12708 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12709 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12710 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12711 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12712 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12713 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12714 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12715 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12718 d = (struct builtin_description *) bdesc_spe_predicates;
12719 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12723 switch (insn_data[d->icode].operand[1].mode)
12726 type = int_ftype_int_v2si_v2si;
12729 type = int_ftype_int_v2sf_v2sf;
12732 gcc_unreachable ();
12735 def_builtin (d->mask, d->name, type, d->code);
12738 /* Evsel predicates. */
12739 d = (struct builtin_description *) bdesc_spe_evsel;
12740 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12744 switch (insn_data[d->icode].operand[1].mode)
12747 type = v2si_ftype_4_v2si;
12750 type = v2sf_ftype_4_v2sf;
12753 gcc_unreachable ();
12756 def_builtin (d->mask, d->name, type, d->code);
12761 paired_init_builtins (void)
12763 const struct builtin_description *d;
12766 tree int_ftype_int_v2sf_v2sf
12767 = build_function_type_list (integer_type_node,
12772 tree pcfloat_type_node =
12773 build_pointer_type (build_qualified_type
12774 (float_type_node, TYPE_QUAL_CONST));
12776 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12777 long_integer_type_node,
12780 tree void_ftype_v2sf_long_pcfloat =
12781 build_function_type_list (void_type_node,
12783 long_integer_type_node,
12788 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12789 PAIRED_BUILTIN_LX);
12792 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12793 PAIRED_BUILTIN_STX);
12796 d = bdesc_paired_preds;
12797 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12801 switch (insn_data[d->icode].operand[1].mode)
12804 type = int_ftype_int_v2sf_v2sf;
12807 gcc_unreachable ();
12810 def_builtin (d->mask, d->name, type, d->code);
12815 altivec_init_builtins (void)
12817 const struct builtin_description *d;
12818 const struct builtin_description_predicates *dp;
12822 tree pvoid_type_node = build_pointer_type (void_type_node);
12824 tree pcvoid_type_node
12825 = build_pointer_type (build_qualified_type (void_type_node,
12828 tree int_ftype_opaque
12829 = build_function_type_list (integer_type_node,
12830 opaque_V4SI_type_node, NULL_TREE);
12831 tree opaque_ftype_opaque
12832 = build_function_type_list (integer_type_node, NULL_TREE);
12833 tree opaque_ftype_opaque_int
12834 = build_function_type_list (opaque_V4SI_type_node,
12835 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12836 tree opaque_ftype_opaque_opaque_int
12837 = build_function_type_list (opaque_V4SI_type_node,
12838 opaque_V4SI_type_node, opaque_V4SI_type_node,
12839 integer_type_node, NULL_TREE);
12840 tree int_ftype_int_opaque_opaque
12841 = build_function_type_list (integer_type_node,
12842 integer_type_node, opaque_V4SI_type_node,
12843 opaque_V4SI_type_node, NULL_TREE);
12844 tree int_ftype_int_v4si_v4si
12845 = build_function_type_list (integer_type_node,
12846 integer_type_node, V4SI_type_node,
12847 V4SI_type_node, NULL_TREE);
12848 tree void_ftype_v4si
12849 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12850 tree v8hi_ftype_void
12851 = build_function_type_list (V8HI_type_node, NULL_TREE);
12852 tree void_ftype_void
12853 = build_function_type_list (void_type_node, NULL_TREE);
12854 tree void_ftype_int
12855 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12857 tree opaque_ftype_long_pcvoid
12858 = build_function_type_list (opaque_V4SI_type_node,
12859 long_integer_type_node, pcvoid_type_node,
12861 tree v16qi_ftype_long_pcvoid
12862 = build_function_type_list (V16QI_type_node,
12863 long_integer_type_node, pcvoid_type_node,
12865 tree v8hi_ftype_long_pcvoid
12866 = build_function_type_list (V8HI_type_node,
12867 long_integer_type_node, pcvoid_type_node,
12869 tree v4si_ftype_long_pcvoid
12870 = build_function_type_list (V4SI_type_node,
12871 long_integer_type_node, pcvoid_type_node,
12873 tree v4sf_ftype_long_pcvoid
12874 = build_function_type_list (V4SF_type_node,
12875 long_integer_type_node, pcvoid_type_node,
12877 tree v2df_ftype_long_pcvoid
12878 = build_function_type_list (V2DF_type_node,
12879 long_integer_type_node, pcvoid_type_node,
12881 tree v2di_ftype_long_pcvoid
12882 = build_function_type_list (V2DI_type_node,
12883 long_integer_type_node, pcvoid_type_node,
12886 tree void_ftype_opaque_long_pvoid
12887 = build_function_type_list (void_type_node,
12888 opaque_V4SI_type_node, long_integer_type_node,
12889 pvoid_type_node, NULL_TREE);
12890 tree void_ftype_v4si_long_pvoid
12891 = build_function_type_list (void_type_node,
12892 V4SI_type_node, long_integer_type_node,
12893 pvoid_type_node, NULL_TREE);
12894 tree void_ftype_v16qi_long_pvoid
12895 = build_function_type_list (void_type_node,
12896 V16QI_type_node, long_integer_type_node,
12897 pvoid_type_node, NULL_TREE);
12898 tree void_ftype_v8hi_long_pvoid
12899 = build_function_type_list (void_type_node,
12900 V8HI_type_node, long_integer_type_node,
12901 pvoid_type_node, NULL_TREE);
12902 tree void_ftype_v4sf_long_pvoid
12903 = build_function_type_list (void_type_node,
12904 V4SF_type_node, long_integer_type_node,
12905 pvoid_type_node, NULL_TREE);
12906 tree void_ftype_v2df_long_pvoid
12907 = build_function_type_list (void_type_node,
12908 V2DF_type_node, long_integer_type_node,
12909 pvoid_type_node, NULL_TREE);
12910 tree void_ftype_v2di_long_pvoid
12911 = build_function_type_list (void_type_node,
12912 V2DI_type_node, long_integer_type_node,
12913 pvoid_type_node, NULL_TREE);
12914 tree int_ftype_int_v8hi_v8hi
12915 = build_function_type_list (integer_type_node,
12916 integer_type_node, V8HI_type_node,
12917 V8HI_type_node, NULL_TREE);
12918 tree int_ftype_int_v16qi_v16qi
12919 = build_function_type_list (integer_type_node,
12920 integer_type_node, V16QI_type_node,
12921 V16QI_type_node, NULL_TREE);
12922 tree int_ftype_int_v4sf_v4sf
12923 = build_function_type_list (integer_type_node,
12924 integer_type_node, V4SF_type_node,
12925 V4SF_type_node, NULL_TREE);
12926 tree int_ftype_int_v2df_v2df
12927 = build_function_type_list (integer_type_node,
12928 integer_type_node, V2DF_type_node,
12929 V2DF_type_node, NULL_TREE);
12930 tree v4si_ftype_v4si
12931 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12932 tree v8hi_ftype_v8hi
12933 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12934 tree v16qi_ftype_v16qi
12935 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12936 tree v4sf_ftype_v4sf
12937 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12938 tree v2df_ftype_v2df
12939 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12940 tree void_ftype_pcvoid_int_int
12941 = build_function_type_list (void_type_node,
12942 pcvoid_type_node, integer_type_node,
12943 integer_type_node, NULL_TREE);
12945 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12946 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12947 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12948 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12949 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12950 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12951 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12952 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12953 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12954 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12955 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12956 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12957 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12958 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12959 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12960 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12961 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12962 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12963 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12964 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12965 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12966 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12967 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12968 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12969 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12970 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12971 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12972 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12973 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12974 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12976 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
12977 VSX_BUILTIN_LXVD2X_V2DF);
12978 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
12979 VSX_BUILTIN_LXVD2X_V2DI);
12980 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
12981 VSX_BUILTIN_LXVW4X_V4SF);
12982 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
12983 VSX_BUILTIN_LXVW4X_V4SI);
12984 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
12985 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
12986 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
12987 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
12988 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
12989 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
12990 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
12991 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
12992 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
12993 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
12994 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
12995 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
12996 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
12997 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
12998 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
12999 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13000 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13001 VSX_BUILTIN_VEC_LD);
13002 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13003 VSX_BUILTIN_VEC_ST);
13005 if (rs6000_cpu == PROCESSOR_CELL)
13007 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13008 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13009 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13010 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13012 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13013 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13014 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13015 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13017 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13018 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13019 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13020 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13022 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13023 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13024 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13025 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13027 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13028 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13029 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13031 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13032 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13033 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13034 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13035 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13036 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13037 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13038 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13039 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13040 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13041 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13042 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13044 /* Add the DST variants. */
13046 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13047 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13049 /* Initialize the predicates. */
13050 dp = bdesc_altivec_preds;
13051 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13053 enum machine_mode mode1;
13055 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13056 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13057 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13058 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13063 mode1 = insn_data[dp->icode].operand[1].mode;
13068 type = int_ftype_int_opaque_opaque;
13071 type = int_ftype_int_v4si_v4si;
13074 type = int_ftype_int_v8hi_v8hi;
13077 type = int_ftype_int_v16qi_v16qi;
13080 type = int_ftype_int_v4sf_v4sf;
13083 type = int_ftype_int_v2df_v2df;
13086 gcc_unreachable ();
13089 def_builtin (dp->mask, dp->name, type, dp->code);
13092 /* Initialize the abs* operators. */
13094 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13096 enum machine_mode mode0;
13099 mode0 = insn_data[d->icode].operand[0].mode;
13104 type = v4si_ftype_v4si;
13107 type = v8hi_ftype_v8hi;
13110 type = v16qi_ftype_v16qi;
13113 type = v4sf_ftype_v4sf;
13116 type = v2df_ftype_v2df;
13119 gcc_unreachable ();
13122 def_builtin (d->mask, d->name, type, d->code);
13125 if (TARGET_ALTIVEC)
13129 /* Initialize target builtin that implements
13130 targetm.vectorize.builtin_mask_for_load. */
13132 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13133 v16qi_ftype_long_pcvoid,
13134 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13135 BUILT_IN_MD, NULL, NULL_TREE);
13136 TREE_READONLY (decl) = 1;
13137 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13138 altivec_builtin_mask_for_load = decl;
13141 /* Access to the vec_init patterns. */
13142 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13143 integer_type_node, integer_type_node,
13144 integer_type_node, NULL_TREE);
13145 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13146 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13148 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13149 short_integer_type_node,
13150 short_integer_type_node,
13151 short_integer_type_node,
13152 short_integer_type_node,
13153 short_integer_type_node,
13154 short_integer_type_node,
13155 short_integer_type_node, NULL_TREE);
13156 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13157 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13159 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13160 char_type_node, char_type_node,
13161 char_type_node, char_type_node,
13162 char_type_node, char_type_node,
13163 char_type_node, char_type_node,
13164 char_type_node, char_type_node,
13165 char_type_node, char_type_node,
13166 char_type_node, char_type_node,
13167 char_type_node, NULL_TREE);
13168 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13169 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13171 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13172 float_type_node, float_type_node,
13173 float_type_node, NULL_TREE);
13174 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13175 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13179 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13180 double_type_node, NULL_TREE);
13181 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13182 VSX_BUILTIN_VEC_INIT_V2DF);
13184 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13185 intDI_type_node, NULL_TREE);
13186 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13187 VSX_BUILTIN_VEC_INIT_V2DI);
13190 /* Access to the vec_set patterns. */
13191 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13193 integer_type_node, NULL_TREE);
13194 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13195 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13197 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13199 integer_type_node, NULL_TREE);
13200 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13201 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13203 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13205 integer_type_node, NULL_TREE);
13206 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13207 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13209 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13211 integer_type_node, NULL_TREE);
13212 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13213 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13217 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13219 integer_type_node, NULL_TREE);
13220 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13221 VSX_BUILTIN_VEC_SET_V2DF);
13223 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13225 integer_type_node, NULL_TREE);
13226 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13227 VSX_BUILTIN_VEC_SET_V2DI);
13230 /* Access to the vec_extract patterns. */
13231 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13232 integer_type_node, NULL_TREE);
13233 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13234 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13236 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13237 integer_type_node, NULL_TREE);
13238 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13239 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13241 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13242 integer_type_node, NULL_TREE);
13243 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13244 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13246 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13247 integer_type_node, NULL_TREE);
13248 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13249 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13253 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13254 integer_type_node, NULL_TREE);
13255 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13256 VSX_BUILTIN_VEC_EXT_V2DF);
13258 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13259 integer_type_node, NULL_TREE);
13260 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13261 VSX_BUILTIN_VEC_EXT_V2DI);
13265 /* Hash function for builtin functions with up to 3 arguments and a return
13268 builtin_hash_function (const void *hash_entry)
13272 const struct builtin_hash_struct *bh =
13273 (const struct builtin_hash_struct *) hash_entry;
13275 for (i = 0; i < 4; i++)
13277 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13278 ret = (ret * 2) + bh->uns_p[i];
13284 /* Compare builtin hash entries H1 and H2 for equivalence. */
13286 builtin_hash_eq (const void *h1, const void *h2)
13288 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13289 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13291 return ((p1->mode[0] == p2->mode[0])
13292 && (p1->mode[1] == p2->mode[1])
13293 && (p1->mode[2] == p2->mode[2])
13294 && (p1->mode[3] == p2->mode[3])
13295 && (p1->uns_p[0] == p2->uns_p[0])
13296 && (p1->uns_p[1] == p2->uns_p[1])
13297 && (p1->uns_p[2] == p2->uns_p[2])
13298 && (p1->uns_p[3] == p2->uns_p[3]));
13301 /* Map types for builtin functions with an explicit return type and up to 3
13302 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13303 of the argument. */
13305 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13306 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13307 enum rs6000_builtins builtin, const char *name)
13309 struct builtin_hash_struct h;
13310 struct builtin_hash_struct *h2;
13314 tree ret_type = NULL_TREE;
13315 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13317 /* Create builtin_hash_table. */
13318 if (builtin_hash_table == NULL)
13319 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13320 builtin_hash_eq, NULL);
13322 h.type = NULL_TREE;
13323 h.mode[0] = mode_ret;
13324 h.mode[1] = mode_arg0;
13325 h.mode[2] = mode_arg1;
13326 h.mode[3] = mode_arg2;
13332 /* If the builtin is a type that produces unsigned results or takes unsigned
13333 arguments, and it is returned as a decl for the vectorizer (such as
13334 widening multiplies, permute), make sure the arguments and return value
13335 are type correct. */
13338 /* unsigned 2 argument functions. */
13339 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13340 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13341 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13342 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13348 /* unsigned 3 argument functions. */
13349 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13350 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13351 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13352 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13353 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13354 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13355 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13356 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13357 case VSX_BUILTIN_VPERM_16QI_UNS:
13358 case VSX_BUILTIN_VPERM_8HI_UNS:
13359 case VSX_BUILTIN_VPERM_4SI_UNS:
13360 case VSX_BUILTIN_VPERM_2DI_UNS:
13361 case VSX_BUILTIN_XXSEL_16QI_UNS:
13362 case VSX_BUILTIN_XXSEL_8HI_UNS:
13363 case VSX_BUILTIN_XXSEL_4SI_UNS:
13364 case VSX_BUILTIN_XXSEL_2DI_UNS:
13371 /* signed permute functions with unsigned char mask. */
13372 case ALTIVEC_BUILTIN_VPERM_16QI:
13373 case ALTIVEC_BUILTIN_VPERM_8HI:
13374 case ALTIVEC_BUILTIN_VPERM_4SI:
13375 case ALTIVEC_BUILTIN_VPERM_4SF:
13376 case ALTIVEC_BUILTIN_VPERM_2DI:
13377 case ALTIVEC_BUILTIN_VPERM_2DF:
13378 case VSX_BUILTIN_VPERM_16QI:
13379 case VSX_BUILTIN_VPERM_8HI:
13380 case VSX_BUILTIN_VPERM_4SI:
13381 case VSX_BUILTIN_VPERM_4SF:
13382 case VSX_BUILTIN_VPERM_2DI:
13383 case VSX_BUILTIN_VPERM_2DF:
13387 /* unsigned args, signed return. */
13388 case VSX_BUILTIN_XVCVUXDDP_UNS:
13389 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13393 /* signed args, unsigned return. */
13394 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13395 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13403 /* Figure out how many args are present. */
13404 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13408 fatal_error ("internal error: builtin function %s had no type", name);
13410 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13411 if (!ret_type && h.uns_p[0])
13412 ret_type = builtin_mode_to_type[h.mode[0]][0];
13415 fatal_error ("internal error: builtin function %s had an unexpected "
13416 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13418 for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
13419 arg_type[i] = NULL_TREE;
13421 for (i = 0; i < num_args; i++)
13423 int m = (int) h.mode[i+1];
13424 int uns_p = h.uns_p[i+1];
13426 arg_type[i] = builtin_mode_to_type[m][uns_p];
13427 if (!arg_type[i] && uns_p)
13428 arg_type[i] = builtin_mode_to_type[m][0];
13431 fatal_error ("internal error: builtin function %s, argument %d "
13432 "had unexpected argument type %s", name, i,
13433 GET_MODE_NAME (m));
13436 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13437 if (*found == NULL)
13439 h2 = ggc_alloc_builtin_hash_struct ();
13441 *found = (void *)h2;
13443 h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
13444 arg_type[2], NULL_TREE);
13447 return ((struct builtin_hash_struct *)(*found))->type;
13451 rs6000_common_init_builtins (void)
13453 const struct builtin_description *d;
13456 tree opaque_ftype_opaque = NULL_TREE;
13457 tree opaque_ftype_opaque_opaque = NULL_TREE;
13458 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13459 tree v2si_ftype_qi = NULL_TREE;
13460 tree v2si_ftype_v2si_qi = NULL_TREE;
13461 tree v2si_ftype_int_qi = NULL_TREE;
13463 if (!TARGET_PAIRED_FLOAT)
13465 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13466 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13469 /* Add the ternary operators. */
13471 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13474 int mask = d->mask;
13476 if ((mask != 0 && (mask & target_flags) == 0)
13477 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13480 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13481 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13482 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13483 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13485 if (! (type = opaque_ftype_opaque_opaque_opaque))
13486 type = opaque_ftype_opaque_opaque_opaque
13487 = build_function_type_list (opaque_V4SI_type_node,
13488 opaque_V4SI_type_node,
13489 opaque_V4SI_type_node,
13490 opaque_V4SI_type_node,
13495 enum insn_code icode = d->icode;
13496 if (d->name == 0 || icode == CODE_FOR_nothing)
13499 type = builtin_function_type (insn_data[icode].operand[0].mode,
13500 insn_data[icode].operand[1].mode,
13501 insn_data[icode].operand[2].mode,
13502 insn_data[icode].operand[3].mode,
13506 def_builtin (d->mask, d->name, type, d->code);
13509 /* Add the binary operators. */
13511 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13513 enum machine_mode mode0, mode1, mode2;
13515 int mask = d->mask;
13517 if ((mask != 0 && (mask & target_flags) == 0)
13518 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13521 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13522 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13523 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13524 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13526 if (! (type = opaque_ftype_opaque_opaque))
13527 type = opaque_ftype_opaque_opaque
13528 = build_function_type_list (opaque_V4SI_type_node,
13529 opaque_V4SI_type_node,
13530 opaque_V4SI_type_node,
13535 enum insn_code icode = d->icode;
13536 if (d->name == 0 || icode == CODE_FOR_nothing)
13539 mode0 = insn_data[icode].operand[0].mode;
13540 mode1 = insn_data[icode].operand[1].mode;
13541 mode2 = insn_data[icode].operand[2].mode;
13543 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13545 if (! (type = v2si_ftype_v2si_qi))
13546 type = v2si_ftype_v2si_qi
13547 = build_function_type_list (opaque_V2SI_type_node,
13548 opaque_V2SI_type_node,
13553 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13554 && mode2 == QImode)
13556 if (! (type = v2si_ftype_int_qi))
13557 type = v2si_ftype_int_qi
13558 = build_function_type_list (opaque_V2SI_type_node,
13565 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13569 def_builtin (d->mask, d->name, type, d->code);
13572 /* Add the simple unary operators. */
13573 d = (struct builtin_description *) bdesc_1arg;
13574 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13576 enum machine_mode mode0, mode1;
13578 int mask = d->mask;
13580 if ((mask != 0 && (mask & target_flags) == 0)
13581 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13584 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13585 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13586 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13587 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13589 if (! (type = opaque_ftype_opaque))
13590 type = opaque_ftype_opaque
13591 = build_function_type_list (opaque_V4SI_type_node,
13592 opaque_V4SI_type_node,
13597 enum insn_code icode = d->icode;
13598 if (d->name == 0 || icode == CODE_FOR_nothing)
13601 mode0 = insn_data[icode].operand[0].mode;
13602 mode1 = insn_data[icode].operand[1].mode;
13604 if (mode0 == V2SImode && mode1 == QImode)
13606 if (! (type = v2si_ftype_qi))
13607 type = v2si_ftype_qi
13608 = build_function_type_list (opaque_V2SI_type_node,
13614 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13618 def_builtin (d->mask, d->name, type, d->code);
13623 rs6000_init_libfuncs (void)
13625 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13626 && !TARGET_POWER2 && !TARGET_POWERPC)
13628 /* AIX library routines for float->int conversion. */
13629 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13630 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13631 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13632 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13635 if (!TARGET_IEEEQUAD)
13636 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13637 if (!TARGET_XL_COMPAT)
13639 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13640 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13641 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13642 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13644 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13646 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13647 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13648 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13649 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13650 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13651 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13652 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13654 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13655 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13656 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13657 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13658 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13659 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13660 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13661 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13664 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13665 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13669 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13670 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13671 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13672 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13676 /* 32-bit SVR4 quad floating point routines. */
13678 set_optab_libfunc (add_optab, TFmode, "_q_add");
13679 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13680 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13681 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13682 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13683 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13684 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13686 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13687 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13688 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13689 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13690 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13691 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13693 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13694 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13695 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13696 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13697 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13698 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13699 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13700 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13705 /* Expand a block clear operation, and return 1 if successful. Return 0
13706 if we should let the compiler generate normal code.
13708 operands[0] is the destination
13709 operands[1] is the length
13710 operands[3] is the alignment */
13713 expand_block_clear (rtx operands[])
13715 rtx orig_dest = operands[0];
13716 rtx bytes_rtx = operands[1];
13717 rtx align_rtx = operands[3];
13718 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13719 HOST_WIDE_INT align;
13720 HOST_WIDE_INT bytes;
13725 /* If this is not a fixed size move, just call memcpy */
13729 /* This must be a fixed size alignment */
13730 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13731 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13733 /* Anything to clear? */
13734 bytes = INTVAL (bytes_rtx);
13738 /* Use the builtin memset after a point, to avoid huge code bloat.
13739 When optimize_size, avoid any significant code bloat; calling
13740 memset is about 4 instructions, so allow for one instruction to
13741 load zero and three to do clearing. */
13742 if (TARGET_ALTIVEC && align >= 128)
13744 else if (TARGET_POWERPC64 && align >= 32)
13746 else if (TARGET_SPE && align >= 64)
13751 if (optimize_size && bytes > 3 * clear_step)
13753 if (! optimize_size && bytes > 8 * clear_step)
13756 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13758 enum machine_mode mode = BLKmode;
13761 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13766 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13771 else if (bytes >= 8 && TARGET_POWERPC64
13772 /* 64-bit loads and stores require word-aligned
13774 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13779 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13780 { /* move 4 bytes */
13784 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13785 { /* move 2 bytes */
13789 else /* move 1 byte at a time */
13795 dest = adjust_address (orig_dest, mode, offset);
13797 emit_move_insn (dest, CONST0_RTX (mode));
13804 /* Expand a block move operation, and return 1 if successful. Return 0
13805 if we should let the compiler generate normal code.
13807 operands[0] is the destination
13808 operands[1] is the source
13809 operands[2] is the length
13810 operands[3] is the alignment */
13812 #define MAX_MOVE_REG 4
13815 expand_block_move (rtx operands[])
13817 rtx orig_dest = operands[0];
13818 rtx orig_src = operands[1];
13819 rtx bytes_rtx = operands[2];
13820 rtx align_rtx = operands[3];
13821 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13826 rtx stores[MAX_MOVE_REG];
13829 /* If this is not a fixed size move, just call memcpy */
13833 /* This must be a fixed size alignment */
13834 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13835 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13837 /* Anything to move? */
13838 bytes = INTVAL (bytes_rtx);
13842 if (bytes > rs6000_block_move_inline_limit)
13845 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13848 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13849 rtx (*mov) (rtx, rtx);
13851 enum machine_mode mode = BLKmode;
13854 /* Altivec first, since it will be faster than a string move
13855 when it applies, and usually not significantly larger. */
13856 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13860 gen_func.mov = gen_movv4si;
13862 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13866 gen_func.mov = gen_movv2si;
13868 else if (TARGET_STRING
13869 && bytes > 24 /* move up to 32 bytes at a time */
13875 && ! fixed_regs[10]
13876 && ! fixed_regs[11]
13877 && ! fixed_regs[12])
13879 move_bytes = (bytes > 32) ? 32 : bytes;
13880 gen_func.movmemsi = gen_movmemsi_8reg;
13882 else if (TARGET_STRING
13883 && bytes > 16 /* move up to 24 bytes at a time */
13889 && ! fixed_regs[10])
13891 move_bytes = (bytes > 24) ? 24 : bytes;
13892 gen_func.movmemsi = gen_movmemsi_6reg;
13894 else if (TARGET_STRING
13895 && bytes > 8 /* move up to 16 bytes at a time */
13899 && ! fixed_regs[8])
13901 move_bytes = (bytes > 16) ? 16 : bytes;
13902 gen_func.movmemsi = gen_movmemsi_4reg;
13904 else if (bytes >= 8 && TARGET_POWERPC64
13905 /* 64-bit loads and stores require word-aligned
13907 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13911 gen_func.mov = gen_movdi;
13913 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13914 { /* move up to 8 bytes at a time */
13915 move_bytes = (bytes > 8) ? 8 : bytes;
13916 gen_func.movmemsi = gen_movmemsi_2reg;
13918 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13919 { /* move 4 bytes */
13922 gen_func.mov = gen_movsi;
13924 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13925 { /* move 2 bytes */
13928 gen_func.mov = gen_movhi;
13930 else if (TARGET_STRING && bytes > 1)
13931 { /* move up to 4 bytes at a time */
13932 move_bytes = (bytes > 4) ? 4 : bytes;
13933 gen_func.movmemsi = gen_movmemsi_1reg;
13935 else /* move 1 byte at a time */
13939 gen_func.mov = gen_movqi;
13942 src = adjust_address (orig_src, mode, offset);
13943 dest = adjust_address (orig_dest, mode, offset);
13945 if (mode != BLKmode)
13947 rtx tmp_reg = gen_reg_rtx (mode);
13949 emit_insn ((*gen_func.mov) (tmp_reg, src));
13950 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13953 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13956 for (i = 0; i < num_reg; i++)
13957 emit_insn (stores[i]);
13961 if (mode == BLKmode)
13963 /* Move the address into scratch registers. The movmemsi
13964 patterns require zero offset. */
13965 if (!REG_P (XEXP (src, 0)))
13967 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13968 src = replace_equiv_address (src, src_reg);
13970 set_mem_size (src, GEN_INT (move_bytes));
13972 if (!REG_P (XEXP (dest, 0)))
13974 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13975 dest = replace_equiv_address (dest, dest_reg);
13977 set_mem_size (dest, GEN_INT (move_bytes));
13979 emit_insn ((*gen_func.movmemsi) (dest, src,
13980 GEN_INT (move_bytes & 31),
13989 /* Return a string to perform a load_multiple operation.
13990 operands[0] is the vector.
13991 operands[1] is the source address.
13992 operands[2] is the first destination register. */
13995 rs6000_output_load_multiple (rtx operands[3])
13997 /* We have to handle the case where the pseudo used to contain the address
13998 is assigned to one of the output registers. */
14000 int words = XVECLEN (operands[0], 0);
14003 if (XVECLEN (operands[0], 0) == 1)
14004 return "{l|lwz} %2,0(%1)";
14006 for (i = 0; i < words; i++)
14007 if (refers_to_regno_p (REGNO (operands[2]) + i,
14008 REGNO (operands[2]) + i + 1, operands[1], 0))
14012 xop[0] = GEN_INT (4 * (words-1));
14013 xop[1] = operands[1];
14014 xop[2] = operands[2];
14015 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14020 xop[0] = GEN_INT (4 * (words-1));
14021 xop[1] = operands[1];
14022 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14023 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);
14028 for (j = 0; j < words; j++)
14031 xop[0] = GEN_INT (j * 4);
14032 xop[1] = operands[1];
14033 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14034 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14036 xop[0] = GEN_INT (i * 4);
14037 xop[1] = operands[1];
14038 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14043 return "{lsi|lswi} %2,%1,%N0";
14047 /* A validation routine: say whether CODE, a condition code, and MODE
14048 match. The other alternatives either don't make sense or should
14049 never be generated. */
14052 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14054 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14055 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14056 && GET_MODE_CLASS (mode) == MODE_CC);
14058 /* These don't make sense. */
14059 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14060 || mode != CCUNSmode);
14062 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14063 || mode == CCUNSmode);
14065 gcc_assert (mode == CCFPmode
14066 || (code != ORDERED && code != UNORDERED
14067 && code != UNEQ && code != LTGT
14068 && code != UNGT && code != UNLT
14069 && code != UNGE && code != UNLE));
14071 /* These should never be generated except for
14072 flag_finite_math_only. */
14073 gcc_assert (mode != CCFPmode
14074 || flag_finite_math_only
14075 || (code != LE && code != GE
14076 && code != UNEQ && code != LTGT
14077 && code != UNGT && code != UNLT));
14079 /* These are invalid; the information is not there. */
14080 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14084 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14085 mask required to convert the result of a rotate insn into a shift
14086 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14089 includes_lshift_p (rtx shiftop, rtx andop)
14091 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14093 shift_mask <<= INTVAL (shiftop);
14095 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14098 /* Similar, but for right shift. */
14101 includes_rshift_p (rtx shiftop, rtx andop)
14103 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14105 shift_mask >>= INTVAL (shiftop);
14107 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14110 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14111 to perform a left shift. It must have exactly SHIFTOP least
14112 significant 0's, then one or more 1's, then zero or more 0's. */
14115 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14117 if (GET_CODE (andop) == CONST_INT)
14119 HOST_WIDE_INT c, lsb, shift_mask;
14121 c = INTVAL (andop);
14122 if (c == 0 || c == ~0)
14126 shift_mask <<= INTVAL (shiftop);
14128 /* Find the least significant one bit. */
14131 /* It must coincide with the LSB of the shift mask. */
14132 if (-lsb != shift_mask)
14135 /* Invert to look for the next transition (if any). */
14138 /* Remove the low group of ones (originally low group of zeros). */
14141 /* Again find the lsb, and check we have all 1's above. */
14145 else if (GET_CODE (andop) == CONST_DOUBLE
14146 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14148 HOST_WIDE_INT low, high, lsb;
14149 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14151 low = CONST_DOUBLE_LOW (andop);
14152 if (HOST_BITS_PER_WIDE_INT < 64)
14153 high = CONST_DOUBLE_HIGH (andop);
14155 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14156 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14159 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14161 shift_mask_high = ~0;
14162 if (INTVAL (shiftop) > 32)
14163 shift_mask_high <<= INTVAL (shiftop) - 32;
14165 lsb = high & -high;
14167 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14173 lsb = high & -high;
14174 return high == -lsb;
14177 shift_mask_low = ~0;
14178 shift_mask_low <<= INTVAL (shiftop);
14182 if (-lsb != shift_mask_low)
14185 if (HOST_BITS_PER_WIDE_INT < 64)
14190 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14192 lsb = high & -high;
14193 return high == -lsb;
14197 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14203 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14204 to perform a left shift. It must have SHIFTOP or more least
14205 significant 0's, with the remainder of the word 1's. */
14208 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14210 if (GET_CODE (andop) == CONST_INT)
14212 HOST_WIDE_INT c, lsb, shift_mask;
14215 shift_mask <<= INTVAL (shiftop);
14216 c = INTVAL (andop);
14218 /* Find the least significant one bit. */
14221 /* It must be covered by the shift mask.
14222 This test also rejects c == 0. */
14223 if ((lsb & shift_mask) == 0)
14226 /* Check we have all 1's above the transition, and reject all 1's. */
14227 return c == -lsb && lsb != 1;
14229 else if (GET_CODE (andop) == CONST_DOUBLE
14230 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14232 HOST_WIDE_INT low, lsb, shift_mask_low;
14234 low = CONST_DOUBLE_LOW (andop);
14236 if (HOST_BITS_PER_WIDE_INT < 64)
14238 HOST_WIDE_INT high, shift_mask_high;
14240 high = CONST_DOUBLE_HIGH (andop);
14244 shift_mask_high = ~0;
14245 if (INTVAL (shiftop) > 32)
14246 shift_mask_high <<= INTVAL (shiftop) - 32;
14248 lsb = high & -high;
14250 if ((lsb & shift_mask_high) == 0)
14253 return high == -lsb;
14259 shift_mask_low = ~0;
14260 shift_mask_low <<= INTVAL (shiftop);
14264 if ((lsb & shift_mask_low) == 0)
14267 return low == -lsb && lsb != 1;
14273 /* Return 1 if operands will generate a valid arguments to rlwimi
14274 instruction for insert with right shift in 64-bit mode. The mask may
14275 not start on the first bit or stop on the last bit because wrap-around
14276 effects of instruction do not correspond to semantics of RTL insn. */
14279 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14281 if (INTVAL (startop) > 32
14282 && INTVAL (startop) < 64
14283 && INTVAL (sizeop) > 1
14284 && INTVAL (sizeop) + INTVAL (startop) < 64
14285 && INTVAL (shiftop) > 0
14286 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14287 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14293 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14294 for lfq and stfq insns iff the registers are hard registers. */
14297 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14299 /* We might have been passed a SUBREG. */
14300 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14303 /* We might have been passed non floating point registers. */
14304 if (!FP_REGNO_P (REGNO (reg1))
14305 || !FP_REGNO_P (REGNO (reg2)))
14308 return (REGNO (reg1) == REGNO (reg2) - 1);
14311 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14312 addr1 and addr2 must be in consecutive memory locations
14313 (addr2 == addr1 + 8). */
14316 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14319 unsigned int reg1, reg2;
14320 int offset1, offset2;
14322 /* The mems cannot be volatile. */
14323 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14326 addr1 = XEXP (mem1, 0);
14327 addr2 = XEXP (mem2, 0);
14329 /* Extract an offset (if used) from the first addr. */
14330 if (GET_CODE (addr1) == PLUS)
14332 /* If not a REG, return zero. */
14333 if (GET_CODE (XEXP (addr1, 0)) != REG)
14337 reg1 = REGNO (XEXP (addr1, 0));
14338 /* The offset must be constant! */
14339 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14341 offset1 = INTVAL (XEXP (addr1, 1));
14344 else if (GET_CODE (addr1) != REG)
14348 reg1 = REGNO (addr1);
14349 /* This was a simple (mem (reg)) expression. Offset is 0. */
14353 /* And now for the second addr. */
14354 if (GET_CODE (addr2) == PLUS)
14356 /* If not a REG, return zero. */
14357 if (GET_CODE (XEXP (addr2, 0)) != REG)
14361 reg2 = REGNO (XEXP (addr2, 0));
14362 /* The offset must be constant. */
14363 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14365 offset2 = INTVAL (XEXP (addr2, 1));
14368 else if (GET_CODE (addr2) != REG)
14372 reg2 = REGNO (addr2);
14373 /* This was a simple (mem (reg)) expression. Offset is 0. */
14377 /* Both of these must have the same base register. */
14381 /* The offset for the second addr must be 8 more than the first addr. */
14382 if (offset2 != offset1 + 8)
14385 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14392 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14394 static bool eliminated = false;
14397 if (mode != SDmode)
14398 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14401 rtx mem = cfun->machine->sdmode_stack_slot;
14402 gcc_assert (mem != NULL_RTX);
14406 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14407 cfun->machine->sdmode_stack_slot = mem;
14413 if (TARGET_DEBUG_ADDR)
14415 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14416 GET_MODE_NAME (mode));
14418 fprintf (stderr, "\tNULL_RTX\n");
14427 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14429 /* Don't walk into types. */
14430 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14432 *walk_subtrees = 0;
14436 switch (TREE_CODE (*tp))
14445 case VIEW_CONVERT_EXPR:
14446 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14456 enum reload_reg_type {
14458 VECTOR_REGISTER_TYPE,
14459 OTHER_REGISTER_TYPE
14462 static enum reload_reg_type
14463 rs6000_reload_register_type (enum reg_class rclass)
14469 return GPR_REGISTER_TYPE;
14474 return VECTOR_REGISTER_TYPE;
14477 return OTHER_REGISTER_TYPE;
14481 /* Inform reload about cases where moving X with a mode MODE to a register in
14482 RCLASS requires an extra scratch or immediate register. Return the class
14483 needed for the immediate register.
14485 For VSX and Altivec, we may need a register to convert sp+offset into
14488 For misaligned 64-bit gpr loads and stores we need a register to
14489 convert an offset address to indirect. */
14492 rs6000_secondary_reload (bool in_p,
14494 reg_class_t rclass_i,
14495 enum machine_mode mode,
14496 secondary_reload_info *sri)
14498 enum reg_class rclass = (enum reg_class) rclass_i;
14499 reg_class_t ret = ALL_REGS;
14500 enum insn_code icode;
14501 bool default_p = false;
14503 sri->icode = CODE_FOR_nothing;
14505 /* Convert vector loads and stores into gprs to use an additional base
14507 icode = rs6000_vector_reload[mode][in_p != false];
14508 if (icode != CODE_FOR_nothing)
14511 sri->icode = CODE_FOR_nothing;
14512 sri->extra_cost = 0;
14514 if (GET_CODE (x) == MEM)
14516 rtx addr = XEXP (x, 0);
14518 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14519 an extra register in that case, but it would need an extra
14520 register if the addressing is reg+reg or (reg+reg)&(-16). */
14521 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14523 if (!legitimate_indirect_address_p (addr, false)
14524 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14526 sri->icode = icode;
14527 /* account for splitting the loads, and converting the
14528 address from reg+reg to reg. */
14529 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14530 + ((GET_CODE (addr) == AND) ? 1 : 0));
14533 /* Loads to and stores from vector registers can only do reg+reg
14534 addressing. Altivec registers can also do (reg+reg)&(-16). */
14535 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14536 || rclass == FLOAT_REGS || rclass == NO_REGS)
14538 if (!VECTOR_MEM_ALTIVEC_P (mode)
14539 && GET_CODE (addr) == AND
14540 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14541 && INTVAL (XEXP (addr, 1)) == -16
14542 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14543 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14545 sri->icode = icode;
14546 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14549 else if (!legitimate_indirect_address_p (addr, false)
14550 && (rclass == NO_REGS
14551 || !legitimate_indexed_address_p (addr, false)))
14553 sri->icode = icode;
14554 sri->extra_cost = 1;
14557 icode = CODE_FOR_nothing;
14559 /* Any other loads, including to pseudo registers which haven't been
14560 assigned to a register yet, default to require a scratch
14564 sri->icode = icode;
14565 sri->extra_cost = 2;
14568 else if (REG_P (x))
14570 int regno = true_regnum (x);
14572 icode = CODE_FOR_nothing;
14573 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14577 enum reg_class xclass = REGNO_REG_CLASS (regno);
14578 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14579 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14581 /* If memory is needed, use default_secondary_reload to create the
14583 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14592 else if (TARGET_POWERPC64
14593 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14595 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14597 rtx addr = XEXP (x, 0);
14599 if (GET_CODE (addr) == PRE_MODIFY)
14600 addr = XEXP (addr, 1);
14601 else if (GET_CODE (addr) == LO_SUM
14602 && GET_CODE (XEXP (addr, 0)) == REG
14603 && GET_CODE (XEXP (addr, 1)) == CONST)
14604 addr = XEXP (XEXP (addr, 1), 0);
14606 if (GET_CODE (addr) == PLUS
14607 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14608 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14611 sri->icode = CODE_FOR_reload_di_load;
14613 sri->icode = CODE_FOR_reload_di_store;
14614 sri->extra_cost = 2;
14624 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14626 gcc_assert (ret != ALL_REGS);
14628 if (TARGET_DEBUG_ADDR)
14631 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14633 reg_class_names[ret],
14634 in_p ? "true" : "false",
14635 reg_class_names[rclass],
14636 GET_MODE_NAME (mode));
14639 fprintf (stderr, ", default secondary reload");
14641 if (sri->icode != CODE_FOR_nothing)
14642 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14643 insn_data[sri->icode].name, sri->extra_cost);
14645 fprintf (stderr, "\n");
14653 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14654 to SP+reg addressing. */
14657 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14659 int regno = true_regnum (reg);
14660 enum machine_mode mode = GET_MODE (reg);
14661 enum reg_class rclass;
14663 rtx and_op2 = NULL_RTX;
14666 rtx scratch_or_premodify = scratch;
14670 if (TARGET_DEBUG_ADDR)
14672 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14673 store_p ? "store" : "load");
14674 fprintf (stderr, "reg:\n");
14676 fprintf (stderr, "mem:\n");
14678 fprintf (stderr, "scratch:\n");
14679 debug_rtx (scratch);
14682 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14683 gcc_assert (GET_CODE (mem) == MEM);
14684 rclass = REGNO_REG_CLASS (regno);
14685 addr = XEXP (mem, 0);
14689 /* GPRs can handle reg + small constant, all other addresses need to use
14690 the scratch register. */
14693 if (GET_CODE (addr) == AND)
14695 and_op2 = XEXP (addr, 1);
14696 addr = XEXP (addr, 0);
14699 if (GET_CODE (addr) == PRE_MODIFY)
14701 scratch_or_premodify = XEXP (addr, 0);
14702 gcc_assert (REG_P (scratch_or_premodify));
14703 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14704 addr = XEXP (addr, 1);
14707 if (GET_CODE (addr) == PLUS
14708 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14709 || and_op2 != NULL_RTX))
14711 addr_op1 = XEXP (addr, 0);
14712 addr_op2 = XEXP (addr, 1);
14713 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14715 if (!REG_P (addr_op2)
14716 && (GET_CODE (addr_op2) != CONST_INT
14717 || !satisfies_constraint_I (addr_op2)))
14719 if (TARGET_DEBUG_ADDR)
14722 "\nMove plus addr to register %s, mode = %s: ",
14723 rs6000_reg_names[REGNO (scratch)],
14724 GET_MODE_NAME (mode));
14725 debug_rtx (addr_op2);
14727 rs6000_emit_move (scratch, addr_op2, Pmode);
14728 addr_op2 = scratch;
14731 emit_insn (gen_rtx_SET (VOIDmode,
14732 scratch_or_premodify,
14733 gen_rtx_PLUS (Pmode,
14737 addr = scratch_or_premodify;
14738 scratch_or_premodify = scratch;
14740 else if (!legitimate_indirect_address_p (addr, false)
14741 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14743 if (TARGET_DEBUG_ADDR)
14745 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14746 rs6000_reg_names[REGNO (scratch_or_premodify)],
14747 GET_MODE_NAME (mode));
14750 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14751 addr = scratch_or_premodify;
14752 scratch_or_premodify = scratch;
14756 /* Float/Altivec registers can only handle reg+reg addressing. Move
14757 other addresses into a scratch register. */
14762 /* With float regs, we need to handle the AND ourselves, since we can't
14763 use the Altivec instruction with an implicit AND -16. Allow scalar
14764 loads to float registers to use reg+offset even if VSX. */
14765 if (GET_CODE (addr) == AND
14766 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14767 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14768 || INTVAL (XEXP (addr, 1)) != -16
14769 || !VECTOR_MEM_ALTIVEC_P (mode)))
14771 and_op2 = XEXP (addr, 1);
14772 addr = XEXP (addr, 0);
14775 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14776 as the address later. */
14777 if (GET_CODE (addr) == PRE_MODIFY
14778 && (!VECTOR_MEM_VSX_P (mode)
14779 || and_op2 != NULL_RTX
14780 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14782 scratch_or_premodify = XEXP (addr, 0);
14783 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14785 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14786 addr = XEXP (addr, 1);
14789 if (legitimate_indirect_address_p (addr, false) /* reg */
14790 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14791 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14792 || (GET_CODE (addr) == AND /* Altivec memory */
14793 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14794 && INTVAL (XEXP (addr, 1)) == -16
14795 && VECTOR_MEM_ALTIVEC_P (mode))
14796 || (rclass == FLOAT_REGS /* legacy float mem */
14797 && GET_MODE_SIZE (mode) == 8
14798 && and_op2 == NULL_RTX
14799 && scratch_or_premodify == scratch
14800 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14803 else if (GET_CODE (addr) == PLUS)
14805 addr_op1 = XEXP (addr, 0);
14806 addr_op2 = XEXP (addr, 1);
14807 gcc_assert (REG_P (addr_op1));
14809 if (TARGET_DEBUG_ADDR)
14811 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14812 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14813 debug_rtx (addr_op2);
14815 rs6000_emit_move (scratch, addr_op2, Pmode);
14816 emit_insn (gen_rtx_SET (VOIDmode,
14817 scratch_or_premodify,
14818 gen_rtx_PLUS (Pmode,
14821 addr = scratch_or_premodify;
14822 scratch_or_premodify = scratch;
14825 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14826 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14828 if (TARGET_DEBUG_ADDR)
14830 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14831 rs6000_reg_names[REGNO (scratch_or_premodify)],
14832 GET_MODE_NAME (mode));
14836 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14837 addr = scratch_or_premodify;
14838 scratch_or_premodify = scratch;
14842 gcc_unreachable ();
14847 gcc_unreachable ();
14850 /* If the original address involved a pre-modify that we couldn't use the VSX
14851 memory instruction with update, and we haven't taken care of already,
14852 store the address in the pre-modify register and use that as the
14854 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14856 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14857 addr = scratch_or_premodify;
14860 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14861 memory instruction, recreate the AND now, including the clobber which is
14862 generated by the general ANDSI3/ANDDI3 patterns for the
14863 andi. instruction. */
14864 if (and_op2 != NULL_RTX)
14866 if (! legitimate_indirect_address_p (addr, false))
14868 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14872 if (TARGET_DEBUG_ADDR)
14874 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14875 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14876 debug_rtx (and_op2);
14879 and_rtx = gen_rtx_SET (VOIDmode,
14881 gen_rtx_AND (Pmode,
14885 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14886 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14887 gen_rtvec (2, and_rtx, cc_clobber)));
14891 /* Adjust the address if it changed. */
14892 if (addr != XEXP (mem, 0))
14894 mem = change_address (mem, mode, addr);
14895 if (TARGET_DEBUG_ADDR)
14896 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14899 /* Now create the move. */
14901 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14903 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14908 /* Convert reloads involving 64-bit gprs and misaligned offset
14909 addressing to use indirect addressing. */
14912 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
14914 int regno = true_regnum (reg);
14915 enum reg_class rclass;
14917 rtx scratch_or_premodify = scratch;
14919 if (TARGET_DEBUG_ADDR)
14921 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14922 store_p ? "store" : "load");
14923 fprintf (stderr, "reg:\n");
14925 fprintf (stderr, "mem:\n");
14927 fprintf (stderr, "scratch:\n");
14928 debug_rtx (scratch);
14931 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14932 gcc_assert (GET_CODE (mem) == MEM);
14933 rclass = REGNO_REG_CLASS (regno);
14934 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
14935 addr = XEXP (mem, 0);
14937 if (GET_CODE (addr) == PRE_MODIFY)
14939 scratch_or_premodify = XEXP (addr, 0);
14940 gcc_assert (REG_P (scratch_or_premodify));
14941 addr = XEXP (addr, 1);
14943 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14945 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14947 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
14949 /* Now create the move. */
14951 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14953 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14958 /* Allocate a 64-bit stack slot to be used for copying SDmode
14959 values through if this function has any SDmode references. */
14962 rs6000_alloc_sdmode_stack_slot (void)
14966 gimple_stmt_iterator gsi;
14968 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14971 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14973 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14976 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14977 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14983 /* Check for any SDmode parameters of the function. */
14984 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14986 if (TREE_TYPE (t) == error_mark_node)
14989 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14990 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14992 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14993 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15001 rs6000_instantiate_decls (void)
15003 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15004 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15007 /* Given an rtx X being reloaded into a reg required to be
15008 in class CLASS, return the class of reg to actually use.
15009 In general this is just CLASS; but on some machines
15010 in some cases it is preferable to use a more restrictive class.
15012 On the RS/6000, we have to return NO_REGS when we want to reload a
15013 floating-point CONST_DOUBLE to force it to be copied to memory.
15015 We also don't want to reload integer values into floating-point
15016 registers if we can at all help it. In fact, this can
15017 cause reload to die, if it tries to generate a reload of CTR
15018 into a FP register and discovers it doesn't have the memory location
15021 ??? Would it be a good idea to have reload do the converse, that is
15022 try to reload floating modes into FP registers if possible?
15025 static enum reg_class
15026 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15028 enum machine_mode mode = GET_MODE (x);
15030 if (VECTOR_UNIT_VSX_P (mode)
15031 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15034 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15035 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15036 && easy_vector_constant (x, mode))
15037 return ALTIVEC_REGS;
15039 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15042 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15043 return GENERAL_REGS;
15045 /* For VSX, prefer the traditional registers for 64-bit values because we can
15046 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15047 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15048 prefer Altivec loads.. */
15049 if (rclass == VSX_REGS)
15051 if (GET_MODE_SIZE (mode) <= 8)
15054 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15055 return ALTIVEC_REGS;
15063 /* Debug version of rs6000_preferred_reload_class. */
15064 static enum reg_class
15065 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15067 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15070 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15072 reg_class_names[ret], reg_class_names[rclass],
15073 GET_MODE_NAME (GET_MODE (x)));
15079 /* If we are copying between FP or AltiVec registers and anything else, we need
15080 a memory location. The exception is when we are targeting ppc64 and the
15081 move to/from fpr to gpr instructions are available. Also, under VSX, you
15082 can copy vector registers from the FP register set to the Altivec register
15083 set and vice versa. */
15086 rs6000_secondary_memory_needed (enum reg_class class1,
15087 enum reg_class class2,
15088 enum machine_mode mode)
15090 if (class1 == class2)
15093 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15094 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15095 between these classes. But we need memory for other things that can go in
15096 FLOAT_REGS like SFmode. */
15098 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15099 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15100 || class1 == FLOAT_REGS))
15101 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15102 && class2 != FLOAT_REGS);
15104 if (class1 == VSX_REGS || class2 == VSX_REGS)
15107 if (class1 == FLOAT_REGS
15108 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15109 || ((mode != DFmode)
15110 && (mode != DDmode)
15111 && (mode != DImode))))
15114 if (class2 == FLOAT_REGS
15115 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15116 || ((mode != DFmode)
15117 && (mode != DDmode)
15118 && (mode != DImode))))
15121 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15127 /* Debug version of rs6000_secondary_memory_needed. */
15129 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15130 enum reg_class class2,
15131 enum machine_mode mode)
15133 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15136 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15137 "class2 = %s, mode = %s\n",
15138 ret ? "true" : "false", reg_class_names[class1],
15139 reg_class_names[class2], GET_MODE_NAME (mode));
15144 /* Return the register class of a scratch register needed to copy IN into
15145 or out of a register in RCLASS in MODE. If it can be done directly,
15146 NO_REGS is returned. */
15148 static enum reg_class
15149 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15154 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15156 && MACHOPIC_INDIRECT
15160 /* We cannot copy a symbolic operand directly into anything
15161 other than BASE_REGS for TARGET_ELF. So indicate that a
15162 register from BASE_REGS is needed as an intermediate
15165 On Darwin, pic addresses require a load from memory, which
15166 needs a base register. */
15167 if (rclass != BASE_REGS
15168 && (GET_CODE (in) == SYMBOL_REF
15169 || GET_CODE (in) == HIGH
15170 || GET_CODE (in) == LABEL_REF
15171 || GET_CODE (in) == CONST))
15175 if (GET_CODE (in) == REG)
15177 regno = REGNO (in);
15178 if (regno >= FIRST_PSEUDO_REGISTER)
15180 regno = true_regnum (in);
15181 if (regno >= FIRST_PSEUDO_REGISTER)
15185 else if (GET_CODE (in) == SUBREG)
15187 regno = true_regnum (in);
15188 if (regno >= FIRST_PSEUDO_REGISTER)
15194 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15196 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15197 || (regno >= 0 && INT_REGNO_P (regno)))
15200 /* Constants, memory, and FP registers can go into FP registers. */
15201 if ((regno == -1 || FP_REGNO_P (regno))
15202 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15203 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15205 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15208 && (regno == -1 || VSX_REGNO_P (regno))
15209 && VSX_REG_CLASS_P (rclass))
15212 /* Memory, and AltiVec registers can go into AltiVec registers. */
15213 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15214 && rclass == ALTIVEC_REGS)
15217 /* We can copy among the CR registers. */
15218 if ((rclass == CR_REGS || rclass == CR0_REGS)
15219 && regno >= 0 && CR_REGNO_P (regno))
15222 /* Otherwise, we need GENERAL_REGS. */
15223 return GENERAL_REGS;
15226 /* Debug version of rs6000_secondary_reload_class. */
15227 static enum reg_class
15228 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15229 enum machine_mode mode, rtx in)
15231 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15233 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15234 "mode = %s, input rtx:\n",
15235 reg_class_names[ret], reg_class_names[rclass],
15236 GET_MODE_NAME (mode));
15242 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15245 rs6000_cannot_change_mode_class (enum machine_mode from,
15246 enum machine_mode to,
15247 enum reg_class rclass)
15249 unsigned from_size = GET_MODE_SIZE (from);
15250 unsigned to_size = GET_MODE_SIZE (to);
15252 if (from_size != to_size)
15254 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15255 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15256 && reg_classes_intersect_p (xclass, rclass));
15259 if (TARGET_E500_DOUBLE
15260 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15261 || (((to) == TFmode) + ((from) == TFmode)) == 1
15262 || (((to) == DDmode) + ((from) == DDmode)) == 1
15263 || (((to) == TDmode) + ((from) == TDmode)) == 1
15264 || (((to) == DImode) + ((from) == DImode)) == 1))
15267 /* Since the VSX register set includes traditional floating point registers
15268 and altivec registers, just check for the size being different instead of
15269 trying to check whether the modes are vector modes. Otherwise it won't
15270 allow say DF and DI to change classes. */
15271 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15272 return (from_size != 8 && from_size != 16);
15274 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15275 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15278 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15279 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15285 /* Debug version of rs6000_cannot_change_mode_class. */
15287 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15288 enum machine_mode to,
15289 enum reg_class rclass)
15291 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15294 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15295 "to = %s, rclass = %s\n",
15296 ret ? "true" : "false",
15297 GET_MODE_NAME (from), GET_MODE_NAME (to),
15298 reg_class_names[rclass]);
15303 /* Given a comparison operation, return the bit number in CCR to test. We
15304 know this is a valid comparison.
15306 SCC_P is 1 if this is for an scc. That means that %D will have been
15307 used instead of %C, so the bits will be in different places.
15309 Return -1 if OP isn't a valid comparison for some reason. */
15312 ccr_bit (rtx op, int scc_p)
15314 enum rtx_code code = GET_CODE (op);
15315 enum machine_mode cc_mode;
15320 if (!COMPARISON_P (op))
15323 reg = XEXP (op, 0);
15325 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15327 cc_mode = GET_MODE (reg);
15328 cc_regnum = REGNO (reg);
15329 base_bit = 4 * (cc_regnum - CR0_REGNO);
15331 validate_condition_mode (code, cc_mode);
15333 /* When generating a sCOND operation, only positive conditions are
15336 || code == EQ || code == GT || code == LT || code == UNORDERED
15337 || code == GTU || code == LTU);
15342 return scc_p ? base_bit + 3 : base_bit + 2;
15344 return base_bit + 2;
15345 case GT: case GTU: case UNLE:
15346 return base_bit + 1;
15347 case LT: case LTU: case UNGE:
15349 case ORDERED: case UNORDERED:
15350 return base_bit + 3;
15353 /* If scc, we will have done a cror to put the bit in the
15354 unordered position. So test that bit. For integer, this is ! LT
15355 unless this is an scc insn. */
15356 return scc_p ? base_bit + 3 : base_bit;
15359 return scc_p ? base_bit + 3 : base_bit + 1;
15362 gcc_unreachable ();
15366 /* Return the GOT register. */
15369 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15371 /* The second flow pass currently (June 1999) can't update
15372 regs_ever_live without disturbing other parts of the compiler, so
15373 update it here to make the prolog/epilogue code happy. */
15374 if (!can_create_pseudo_p ()
15375 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15376 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15378 crtl->uses_pic_offset_table = 1;
15380 return pic_offset_table_rtx;
15383 static rs6000_stack_t stack_info;
15385 /* Function to init struct machine_function.
15386 This will be called, via a pointer variable,
15387 from push_function_context. */
15389 static struct machine_function *
15390 rs6000_init_machine_status (void)
15392 stack_info.reload_completed = 0;
15393 return ggc_alloc_cleared_machine_function ();
15396 /* These macros test for integers and extract the low-order bits. */
15398 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15399 && GET_MODE (X) == VOIDmode)
15401 #define INT_LOWPART(X) \
15402 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15405 extract_MB (rtx op)
15408 unsigned long val = INT_LOWPART (op);
15410 /* If the high bit is zero, the value is the first 1 bit we find
15412 if ((val & 0x80000000) == 0)
15414 gcc_assert (val & 0xffffffff);
15417 while (((val <<= 1) & 0x80000000) == 0)
15422 /* If the high bit is set and the low bit is not, or the mask is all
15423 1's, the value is zero. */
15424 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15427 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15430 while (((val >>= 1) & 1) != 0)
15437 extract_ME (rtx op)
15440 unsigned long val = INT_LOWPART (op);
15442 /* If the low bit is zero, the value is the first 1 bit we find from
15444 if ((val & 1) == 0)
15446 gcc_assert (val & 0xffffffff);
15449 while (((val >>= 1) & 1) == 0)
15455 /* If the low bit is set and the high bit is not, or the mask is all
15456 1's, the value is 31. */
15457 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15460 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15463 while (((val <<= 1) & 0x80000000) != 0)
15469 /* Locate some local-dynamic symbol still in use by this function
15470 so that we can print its name in some tls_ld pattern. */
15472 static const char *
15473 rs6000_get_some_local_dynamic_name (void)
15477 if (cfun->machine->some_ld_name)
15478 return cfun->machine->some_ld_name;
15480 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15482 && for_each_rtx (&PATTERN (insn),
15483 rs6000_get_some_local_dynamic_name_1, 0))
15484 return cfun->machine->some_ld_name;
15486 gcc_unreachable ();
15489 /* Helper function for rs6000_get_some_local_dynamic_name. */
15492 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15496 if (GET_CODE (x) == SYMBOL_REF)
15498 const char *str = XSTR (x, 0);
15499 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15501 cfun->machine->some_ld_name = str;
15509 /* Write out a function code label. */
15512 rs6000_output_function_entry (FILE *file, const char *fname)
15514 if (fname[0] != '.')
15516 switch (DEFAULT_ABI)
15519 gcc_unreachable ();
15525 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15534 RS6000_OUTPUT_BASENAME (file, fname);
15537 /* Print an operand. Recognize special options, documented below. */
15540 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15541 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15543 #define SMALL_DATA_RELOC "sda21"
15544 #define SMALL_DATA_REG 0
15548 print_operand (FILE *file, rtx x, int code)
15552 unsigned HOST_WIDE_INT uval;
15557 /* Write out an instruction after the call which may be replaced
15558 with glue code by the loader. This depends on the AIX version. */
15559 asm_fprintf (file, RS6000_CALL_GLUE);
15562 /* %a is output_address. */
15565 /* If X is a constant integer whose low-order 5 bits are zero,
15566 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15567 in the AIX assembler where "sri" with a zero shift count
15568 writes a trash instruction. */
15569 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15576 /* If constant, low-order 16 bits of constant, unsigned.
15577 Otherwise, write normally. */
15579 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15581 print_operand (file, x, 0);
15585 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15586 for 64-bit mask direction. */
15587 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15590 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15594 /* X is a CR register. Print the number of the GT bit of the CR. */
15595 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15596 output_operand_lossage ("invalid %%c value");
15598 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15602 /* Like 'J' but get to the GT bit only. */
15603 gcc_assert (GET_CODE (x) == REG);
15605 /* Bit 1 is GT bit. */
15606 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15608 /* Add one for shift count in rlinm for scc. */
15609 fprintf (file, "%d", i + 1);
15613 /* X is a CR register. Print the number of the EQ bit of the CR */
15614 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15615 output_operand_lossage ("invalid %%E value");
15617 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15621 /* X is a CR register. Print the shift count needed to move it
15622 to the high-order four bits. */
15623 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15624 output_operand_lossage ("invalid %%f value");
15626 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15630 /* Similar, but print the count for the rotate in the opposite
15632 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15633 output_operand_lossage ("invalid %%F value");
15635 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15639 /* X is a constant integer. If it is negative, print "m",
15640 otherwise print "z". This is to make an aze or ame insn. */
15641 if (GET_CODE (x) != CONST_INT)
15642 output_operand_lossage ("invalid %%G value");
15643 else if (INTVAL (x) >= 0)
15650 /* If constant, output low-order five bits. Otherwise, write
15653 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15655 print_operand (file, x, 0);
15659 /* If constant, output low-order six bits. Otherwise, write
15662 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15664 print_operand (file, x, 0);
15668 /* Print `i' if this is a constant, else nothing. */
15674 /* Write the bit number in CCR for jump. */
15675 i = ccr_bit (x, 0);
15677 output_operand_lossage ("invalid %%j code");
15679 fprintf (file, "%d", i);
15683 /* Similar, but add one for shift count in rlinm for scc and pass
15684 scc flag to `ccr_bit'. */
15685 i = ccr_bit (x, 1);
15687 output_operand_lossage ("invalid %%J code");
15689 /* If we want bit 31, write a shift count of zero, not 32. */
15690 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15694 /* X must be a constant. Write the 1's complement of the
15697 output_operand_lossage ("invalid %%k value");
15699 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15703 /* X must be a symbolic constant on ELF. Write an
15704 expression suitable for an 'addi' that adds in the low 16
15705 bits of the MEM. */
15706 if (GET_CODE (x) == CONST)
15708 if (GET_CODE (XEXP (x, 0)) != PLUS
15709 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15710 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15711 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15712 output_operand_lossage ("invalid %%K value");
15714 print_operand_address (file, x);
15715 fputs ("@l", file);
15718 /* %l is output_asm_label. */
15721 /* Write second word of DImode or DFmode reference. Works on register
15722 or non-indexed memory only. */
15723 if (GET_CODE (x) == REG)
15724 fputs (reg_names[REGNO (x) + 1], file);
15725 else if (GET_CODE (x) == MEM)
15727 /* Handle possible auto-increment. Since it is pre-increment and
15728 we have already done it, we can just use an offset of word. */
15729 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15730 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15731 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15733 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15734 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15737 output_address (XEXP (adjust_address_nv (x, SImode,
15741 if (small_data_operand (x, GET_MODE (x)))
15742 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15743 reg_names[SMALL_DATA_REG]);
15748 /* MB value for a mask operand. */
15749 if (! mask_operand (x, SImode))
15750 output_operand_lossage ("invalid %%m value");
15752 fprintf (file, "%d", extract_MB (x));
15756 /* ME value for a mask operand. */
15757 if (! mask_operand (x, SImode))
15758 output_operand_lossage ("invalid %%M value");
15760 fprintf (file, "%d", extract_ME (x));
15763 /* %n outputs the negative of its operand. */
15766 /* Write the number of elements in the vector times 4. */
15767 if (GET_CODE (x) != PARALLEL)
15768 output_operand_lossage ("invalid %%N value");
15770 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15774 /* Similar, but subtract 1 first. */
15775 if (GET_CODE (x) != PARALLEL)
15776 output_operand_lossage ("invalid %%O value");
15778 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15782 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15784 || INT_LOWPART (x) < 0
15785 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15786 output_operand_lossage ("invalid %%p value");
15788 fprintf (file, "%d", i);
15792 /* The operand must be an indirect memory reference. The result
15793 is the register name. */
15794 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15795 || REGNO (XEXP (x, 0)) >= 32)
15796 output_operand_lossage ("invalid %%P value");
15798 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15802 /* This outputs the logical code corresponding to a boolean
15803 expression. The expression may have one or both operands
15804 negated (if one, only the first one). For condition register
15805 logical operations, it will also treat the negated
15806 CR codes as NOTs, but not handle NOTs of them. */
15808 const char *const *t = 0;
15810 enum rtx_code code = GET_CODE (x);
15811 static const char * const tbl[3][3] = {
15812 { "and", "andc", "nor" },
15813 { "or", "orc", "nand" },
15814 { "xor", "eqv", "xor" } };
15818 else if (code == IOR)
15820 else if (code == XOR)
15823 output_operand_lossage ("invalid %%q value");
15825 if (GET_CODE (XEXP (x, 0)) != NOT)
15829 if (GET_CODE (XEXP (x, 1)) == NOT)
15847 /* X is a CR register. Print the mask for `mtcrf'. */
15848 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15849 output_operand_lossage ("invalid %%R value");
15851 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15855 /* Low 5 bits of 32 - value */
15857 output_operand_lossage ("invalid %%s value");
15859 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15863 /* PowerPC64 mask position. All 0's is excluded.
15864 CONST_INT 32-bit mask is considered sign-extended so any
15865 transition must occur within the CONST_INT, not on the boundary. */
15866 if (! mask64_operand (x, DImode))
15867 output_operand_lossage ("invalid %%S value");
15869 uval = INT_LOWPART (x);
15871 if (uval & 1) /* Clear Left */
15873 #if HOST_BITS_PER_WIDE_INT > 64
15874 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15878 else /* Clear Right */
15881 #if HOST_BITS_PER_WIDE_INT > 64
15882 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15888 gcc_assert (i >= 0);
15889 fprintf (file, "%d", i);
15893 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15894 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15896 /* Bit 3 is OV bit. */
15897 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15899 /* If we want bit 31, write a shift count of zero, not 32. */
15900 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15904 /* Print the symbolic name of a branch target register. */
15905 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15906 && REGNO (x) != CTR_REGNO))
15907 output_operand_lossage ("invalid %%T value");
15908 else if (REGNO (x) == LR_REGNO)
15909 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15911 fputs ("ctr", file);
15915 /* High-order 16 bits of constant for use in unsigned operand. */
15917 output_operand_lossage ("invalid %%u value");
15919 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15920 (INT_LOWPART (x) >> 16) & 0xffff);
15924 /* High-order 16 bits of constant for use in signed operand. */
15926 output_operand_lossage ("invalid %%v value");
15928 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15929 (INT_LOWPART (x) >> 16) & 0xffff);
15933 /* Print `u' if this has an auto-increment or auto-decrement. */
15934 if (GET_CODE (x) == MEM
15935 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15936 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15937 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15942 /* Print the trap code for this operand. */
15943 switch (GET_CODE (x))
15946 fputs ("eq", file); /* 4 */
15949 fputs ("ne", file); /* 24 */
15952 fputs ("lt", file); /* 16 */
15955 fputs ("le", file); /* 20 */
15958 fputs ("gt", file); /* 8 */
15961 fputs ("ge", file); /* 12 */
15964 fputs ("llt", file); /* 2 */
15967 fputs ("lle", file); /* 6 */
15970 fputs ("lgt", file); /* 1 */
15973 fputs ("lge", file); /* 5 */
15976 gcc_unreachable ();
15981 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15984 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15985 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15987 print_operand (file, x, 0);
15991 /* MB value for a PowerPC64 rldic operand. */
15992 val = (GET_CODE (x) == CONST_INT
15993 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15998 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15999 if ((val <<= 1) < 0)
16002 #if HOST_BITS_PER_WIDE_INT == 32
16003 if (GET_CODE (x) == CONST_INT && i >= 0)
16004 i += 32; /* zero-extend high-part was all 0's */
16005 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16007 val = CONST_DOUBLE_LOW (x);
16013 for ( ; i < 64; i++)
16014 if ((val <<= 1) < 0)
16019 fprintf (file, "%d", i + 1);
16023 /* X is a FPR or Altivec register used in a VSX context. */
16024 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16025 output_operand_lossage ("invalid %%x value");
16028 int reg = REGNO (x);
16029 int vsx_reg = (FP_REGNO_P (reg)
16031 : reg - FIRST_ALTIVEC_REGNO + 32);
16033 #ifdef TARGET_REGNAMES
16034 if (TARGET_REGNAMES)
16035 fprintf (file, "%%vs%d", vsx_reg);
16038 fprintf (file, "%d", vsx_reg);
16043 if (GET_CODE (x) == MEM
16044 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16045 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16046 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16051 /* Like 'L', for third word of TImode */
16052 if (GET_CODE (x) == REG)
16053 fputs (reg_names[REGNO (x) + 2], file);
16054 else if (GET_CODE (x) == MEM)
16056 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16057 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16058 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16059 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16060 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16062 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16063 if (small_data_operand (x, GET_MODE (x)))
16064 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16065 reg_names[SMALL_DATA_REG]);
16070 /* X is a SYMBOL_REF. Write out the name preceded by a
16071 period and without any trailing data in brackets. Used for function
16072 names. If we are configured for System V (or the embedded ABI) on
16073 the PowerPC, do not emit the period, since those systems do not use
16074 TOCs and the like. */
16075 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16077 /* Mark the decl as referenced so that cgraph will output the
16079 if (SYMBOL_REF_DECL (x))
16080 mark_decl_referenced (SYMBOL_REF_DECL (x));
16082 /* For macho, check to see if we need a stub. */
16085 const char *name = XSTR (x, 0);
16087 if (darwin_emit_branch_islands
16088 && MACHOPIC_INDIRECT
16089 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16090 name = machopic_indirection_name (x, /*stub_p=*/true);
16092 assemble_name (file, name);
16094 else if (!DOT_SYMBOLS)
16095 assemble_name (file, XSTR (x, 0));
16097 rs6000_output_function_entry (file, XSTR (x, 0));
16101 /* Like 'L', for last word of TImode. */
16102 if (GET_CODE (x) == REG)
16103 fputs (reg_names[REGNO (x) + 3], file);
16104 else if (GET_CODE (x) == MEM)
16106 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16107 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16108 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16109 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16110 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16112 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16113 if (small_data_operand (x, GET_MODE (x)))
16114 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16115 reg_names[SMALL_DATA_REG]);
16119 /* Print AltiVec or SPE memory operand. */
16124 gcc_assert (GET_CODE (x) == MEM);
16128 /* Ugly hack because %y is overloaded. */
16129 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16130 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16131 || GET_MODE (x) == TFmode
16132 || GET_MODE (x) == TImode))
16134 /* Handle [reg]. */
16135 if (GET_CODE (tmp) == REG)
16137 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16140 /* Handle [reg+UIMM]. */
16141 else if (GET_CODE (tmp) == PLUS &&
16142 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16146 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16148 x = INTVAL (XEXP (tmp, 1));
16149 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16153 /* Fall through. Must be [reg+reg]. */
16155 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16156 && GET_CODE (tmp) == AND
16157 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16158 && INTVAL (XEXP (tmp, 1)) == -16)
16159 tmp = XEXP (tmp, 0);
16160 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16161 && GET_CODE (tmp) == PRE_MODIFY)
16162 tmp = XEXP (tmp, 1);
16163 if (GET_CODE (tmp) == REG)
16164 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16167 if (!GET_CODE (tmp) == PLUS
16168 || !REG_P (XEXP (tmp, 0))
16169 || !REG_P (XEXP (tmp, 1)))
16171 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16175 if (REGNO (XEXP (tmp, 0)) == 0)
16176 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16177 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16179 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16180 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16186 if (GET_CODE (x) == REG)
16187 fprintf (file, "%s", reg_names[REGNO (x)]);
16188 else if (GET_CODE (x) == MEM)
16190 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16191 know the width from the mode. */
16192 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16193 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16194 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16195 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16196 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16197 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16198 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16199 output_address (XEXP (XEXP (x, 0), 1));
16201 output_address (XEXP (x, 0));
16205 if (toc_relative_expr_p (x))
16206 /* This hack along with a corresponding hack in
16207 rs6000_output_addr_const_extra arranges to output addends
16208 where the assembler expects to find them. eg.
16209 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16210 without this hack would be output as "x@toc+4". We
16212 output_addr_const (file, tocrel_base);
16214 output_addr_const (file, x);
16219 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16223 output_operand_lossage ("invalid %%xn code");
16227 /* Print the address of an operand. */
16230 print_operand_address (FILE *file, rtx x)
16232 if (GET_CODE (x) == REG)
16233 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16234 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16235 || GET_CODE (x) == LABEL_REF)
16237 output_addr_const (file, x);
16238 if (small_data_operand (x, GET_MODE (x)))
16239 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16240 reg_names[SMALL_DATA_REG]);
16242 gcc_assert (!TARGET_TOC);
16244 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16246 gcc_assert (REG_P (XEXP (x, 0)));
16247 if (REGNO (XEXP (x, 0)) == 0)
16248 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16249 reg_names[ REGNO (XEXP (x, 0)) ]);
16251 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16252 reg_names[ REGNO (XEXP (x, 1)) ]);
16254 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16255 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16256 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16258 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16259 && CONSTANT_P (XEXP (x, 1)))
16261 fprintf (file, "lo16(");
16262 output_addr_const (file, XEXP (x, 1));
16263 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16266 else if (legitimate_constant_pool_address_p (x, QImode, true))
16268 /* This hack along with a corresponding hack in
16269 rs6000_output_addr_const_extra arranges to output addends
16270 where the assembler expects to find them. eg.
16272 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16273 without this hack would be output as "x@toc+8@l(9)". We
16274 want "x+8@toc@l(9)". */
16275 output_addr_const (file, tocrel_base);
16276 if (GET_CODE (x) == LO_SUM)
16277 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16279 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16282 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16283 && CONSTANT_P (XEXP (x, 1)))
16285 output_addr_const (file, XEXP (x, 1));
16286 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16290 gcc_unreachable ();
16293 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16296 rs6000_output_addr_const_extra (FILE *file, rtx x)
16298 if (GET_CODE (x) == UNSPEC)
16299 switch (XINT (x, 1))
16301 case UNSPEC_TOCREL:
16302 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16303 output_addr_const (file, XVECEXP (x, 0, 0));
16304 if (x == tocrel_base && tocrel_offset != const0_rtx)
16306 if (INTVAL (tocrel_offset) >= 0)
16307 fprintf (file, "+");
16308 output_addr_const (file, tocrel_offset);
16310 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16313 assemble_name (file, toc_label_name);
16315 else if (TARGET_ELF)
16316 fputs ("@toc", file);
16320 case UNSPEC_MACHOPIC_OFFSET:
16321 output_addr_const (file, XVECEXP (x, 0, 0));
16323 machopic_output_function_base_name (file);
16330 /* Target hook for assembling integer objects. The PowerPC version has
16331 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16332 is defined. It also needs to handle DI-mode objects on 64-bit
16336 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16338 #ifdef RELOCATABLE_NEEDS_FIXUP
16339 /* Special handling for SI values. */
16340 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16342 static int recurse = 0;
16344 /* For -mrelocatable, we mark all addresses that need to be fixed up
16345 in the .fixup section. */
16346 if (TARGET_RELOCATABLE
16347 && in_section != toc_section
16348 && in_section != text_section
16349 && !unlikely_text_section_p (in_section)
16351 && GET_CODE (x) != CONST_INT
16352 && GET_CODE (x) != CONST_DOUBLE
16358 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16360 ASM_OUTPUT_LABEL (asm_out_file, buf);
16361 fprintf (asm_out_file, "\t.long\t(");
16362 output_addr_const (asm_out_file, x);
16363 fprintf (asm_out_file, ")@fixup\n");
16364 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16365 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16366 fprintf (asm_out_file, "\t.long\t");
16367 assemble_name (asm_out_file, buf);
16368 fprintf (asm_out_file, "\n\t.previous\n");
16372 /* Remove initial .'s to turn a -mcall-aixdesc function
16373 address into the address of the descriptor, not the function
16375 else if (GET_CODE (x) == SYMBOL_REF
16376 && XSTR (x, 0)[0] == '.'
16377 && DEFAULT_ABI == ABI_AIX)
16379 const char *name = XSTR (x, 0);
16380 while (*name == '.')
16383 fprintf (asm_out_file, "\t.long\t%s\n", name);
16387 #endif /* RELOCATABLE_NEEDS_FIXUP */
16388 return default_assemble_integer (x, size, aligned_p);
16391 #ifdef HAVE_GAS_HIDDEN
16392 /* Emit an assembler directive to set symbol visibility for DECL to
16393 VISIBILITY_TYPE. */
16396 rs6000_assemble_visibility (tree decl, int vis)
16398 /* Functions need to have their entry point symbol visibility set as
16399 well as their descriptor symbol visibility. */
16400 if (DEFAULT_ABI == ABI_AIX
16402 && TREE_CODE (decl) == FUNCTION_DECL)
16404 static const char * const visibility_types[] = {
16405 NULL, "internal", "hidden", "protected"
16408 const char *name, *type;
16410 name = ((* targetm.strip_name_encoding)
16411 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16412 type = visibility_types[vis];
16414 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16415 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16418 default_assemble_visibility (decl, vis);
16423 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16425 /* Reversal of FP compares takes care -- an ordered compare
16426 becomes an unordered compare and vice versa. */
16427 if (mode == CCFPmode
16428 && (!flag_finite_math_only
16429 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16430 || code == UNEQ || code == LTGT))
16431 return reverse_condition_maybe_unordered (code);
16433 return reverse_condition (code);
16436 /* Generate a compare for CODE. Return a brand-new rtx that
16437 represents the result of the compare. */
16440 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16442 enum machine_mode comp_mode;
16443 rtx compare_result;
16444 enum rtx_code code = GET_CODE (cmp);
16445 rtx op0 = XEXP (cmp, 0);
16446 rtx op1 = XEXP (cmp, 1);
16448 if (FLOAT_MODE_P (mode))
16449 comp_mode = CCFPmode;
16450 else if (code == GTU || code == LTU
16451 || code == GEU || code == LEU)
16452 comp_mode = CCUNSmode;
16453 else if ((code == EQ || code == NE)
16454 && GET_CODE (op0) == SUBREG
16455 && GET_CODE (op1) == SUBREG
16456 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16457 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16458 /* These are unsigned values, perhaps there will be a later
16459 ordering compare that can be shared with this one.
16460 Unfortunately we cannot detect the signedness of the operands
16461 for non-subregs. */
16462 comp_mode = CCUNSmode;
16464 comp_mode = CCmode;
16466 /* First, the compare. */
16467 compare_result = gen_reg_rtx (comp_mode);
16469 /* E500 FP compare instructions on the GPRs. Yuck! */
16470 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16471 && FLOAT_MODE_P (mode))
16473 rtx cmp, or_result, compare_result2;
16474 enum machine_mode op_mode = GET_MODE (op0);
16476 if (op_mode == VOIDmode)
16477 op_mode = GET_MODE (op1);
16479 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16480 This explains the following mess. */
16484 case EQ: case UNEQ: case NE: case LTGT:
16488 cmp = (flag_finite_math_only && !flag_trapping_math)
16489 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16490 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16494 cmp = (flag_finite_math_only && !flag_trapping_math)
16495 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16496 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16500 cmp = (flag_finite_math_only && !flag_trapping_math)
16501 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16502 : gen_cmptfeq_gpr (compare_result, op0, op1);
16506 gcc_unreachable ();
16510 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16514 cmp = (flag_finite_math_only && !flag_trapping_math)
16515 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16516 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16520 cmp = (flag_finite_math_only && !flag_trapping_math)
16521 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16522 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16526 cmp = (flag_finite_math_only && !flag_trapping_math)
16527 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16528 : gen_cmptfgt_gpr (compare_result, op0, op1);
16532 gcc_unreachable ();
16536 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16540 cmp = (flag_finite_math_only && !flag_trapping_math)
16541 ? gen_tstsflt_gpr (compare_result, op0, op1)
16542 : gen_cmpsflt_gpr (compare_result, op0, op1);
16546 cmp = (flag_finite_math_only && !flag_trapping_math)
16547 ? gen_tstdflt_gpr (compare_result, op0, op1)
16548 : gen_cmpdflt_gpr (compare_result, op0, op1);
16552 cmp = (flag_finite_math_only && !flag_trapping_math)
16553 ? gen_tsttflt_gpr (compare_result, op0, op1)
16554 : gen_cmptflt_gpr (compare_result, op0, op1);
16558 gcc_unreachable ();
16562 gcc_unreachable ();
16565 /* Synthesize LE and GE from LT/GT || EQ. */
16566 if (code == LE || code == GE || code == LEU || code == GEU)
16572 case LE: code = LT; break;
16573 case GE: code = GT; break;
16574 case LEU: code = LT; break;
16575 case GEU: code = GT; break;
16576 default: gcc_unreachable ();
16579 compare_result2 = gen_reg_rtx (CCFPmode);
16585 cmp = (flag_finite_math_only && !flag_trapping_math)
16586 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16587 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16591 cmp = (flag_finite_math_only && !flag_trapping_math)
16592 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16593 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16597 cmp = (flag_finite_math_only && !flag_trapping_math)
16598 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16599 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16603 gcc_unreachable ();
16607 /* OR them together. */
16608 or_result = gen_reg_rtx (CCFPmode);
16609 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16611 compare_result = or_result;
16616 if (code == NE || code == LTGT)
16626 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16627 CLOBBERs to match cmptf_internal2 pattern. */
16628 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16629 && GET_MODE (op0) == TFmode
16630 && !TARGET_IEEEQUAD
16631 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16632 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16634 gen_rtx_SET (VOIDmode,
16636 gen_rtx_COMPARE (comp_mode, op0, op1)),
16637 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16638 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16639 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16640 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16641 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16642 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16643 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16644 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16645 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16646 else if (GET_CODE (op1) == UNSPEC
16647 && XINT (op1, 1) == UNSPEC_SP_TEST)
16649 rtx op1b = XVECEXP (op1, 0, 0);
16650 comp_mode = CCEQmode;
16651 compare_result = gen_reg_rtx (CCEQmode);
16653 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16655 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16658 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16659 gen_rtx_COMPARE (comp_mode, op0, op1)));
16662 /* Some kinds of FP comparisons need an OR operation;
16663 under flag_finite_math_only we don't bother. */
16664 if (FLOAT_MODE_P (mode)
16665 && !flag_finite_math_only
16666 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16667 && (code == LE || code == GE
16668 || code == UNEQ || code == LTGT
16669 || code == UNGT || code == UNLT))
16671 enum rtx_code or1, or2;
16672 rtx or1_rtx, or2_rtx, compare2_rtx;
16673 rtx or_result = gen_reg_rtx (CCEQmode);
16677 case LE: or1 = LT; or2 = EQ; break;
16678 case GE: or1 = GT; or2 = EQ; break;
16679 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16680 case LTGT: or1 = LT; or2 = GT; break;
16681 case UNGT: or1 = UNORDERED; or2 = GT; break;
16682 case UNLT: or1 = UNORDERED; or2 = LT; break;
16683 default: gcc_unreachable ();
16685 validate_condition_mode (or1, comp_mode);
16686 validate_condition_mode (or2, comp_mode);
16687 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16688 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16689 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16690 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16692 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16694 compare_result = or_result;
16698 validate_condition_mode (code, GET_MODE (compare_result));
16700 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16704 /* Emit the RTL for an sISEL pattern. */
16707 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16709 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16713 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16716 enum machine_mode op_mode;
16717 enum rtx_code cond_code;
16718 rtx result = operands[0];
16720 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16722 rs6000_emit_sISEL (mode, operands);
16726 condition_rtx = rs6000_generate_compare (operands[1], mode);
16727 cond_code = GET_CODE (condition_rtx);
16729 if (FLOAT_MODE_P (mode)
16730 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16734 PUT_MODE (condition_rtx, SImode);
16735 t = XEXP (condition_rtx, 0);
16737 gcc_assert (cond_code == NE || cond_code == EQ);
16739 if (cond_code == NE)
16740 emit_insn (gen_e500_flip_gt_bit (t, t));
16742 emit_insn (gen_move_from_CR_gt_bit (result, t));
16746 if (cond_code == NE
16747 || cond_code == GE || cond_code == LE
16748 || cond_code == GEU || cond_code == LEU
16749 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16751 rtx not_result = gen_reg_rtx (CCEQmode);
16752 rtx not_op, rev_cond_rtx;
16753 enum machine_mode cc_mode;
16755 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16757 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16758 SImode, XEXP (condition_rtx, 0), const0_rtx);
16759 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16760 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16761 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16764 op_mode = GET_MODE (XEXP (operands[1], 0));
16765 if (op_mode == VOIDmode)
16766 op_mode = GET_MODE (XEXP (operands[1], 1));
16768 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16770 PUT_MODE (condition_rtx, DImode);
16771 convert_move (result, condition_rtx, 0);
16775 PUT_MODE (condition_rtx, SImode);
16776 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16780 /* Emit a branch of kind CODE to location LOC. */
16783 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16785 rtx condition_rtx, loc_ref;
16787 condition_rtx = rs6000_generate_compare (operands[0], mode);
16788 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16789 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16790 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16791 loc_ref, pc_rtx)));
16794 /* Return the string to output a conditional branch to LABEL, which is
16795 the operand number of the label, or -1 if the branch is really a
16796 conditional return.
16798 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16799 condition code register and its mode specifies what kind of
16800 comparison we made.
16802 REVERSED is nonzero if we should reverse the sense of the comparison.
16804 INSN is the insn. */
16807 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16809 static char string[64];
16810 enum rtx_code code = GET_CODE (op);
16811 rtx cc_reg = XEXP (op, 0);
16812 enum machine_mode mode = GET_MODE (cc_reg);
16813 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16814 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16815 int really_reversed = reversed ^ need_longbranch;
16821 validate_condition_mode (code, mode);
16823 /* Work out which way this really branches. We could use
16824 reverse_condition_maybe_unordered here always but this
16825 makes the resulting assembler clearer. */
16826 if (really_reversed)
16828 /* Reversal of FP compares takes care -- an ordered compare
16829 becomes an unordered compare and vice versa. */
16830 if (mode == CCFPmode)
16831 code = reverse_condition_maybe_unordered (code);
16833 code = reverse_condition (code);
16836 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16838 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16843 /* Opposite of GT. */
16852 gcc_unreachable ();
16858 /* Not all of these are actually distinct opcodes, but
16859 we distinguish them for clarity of the resulting assembler. */
16860 case NE: case LTGT:
16861 ccode = "ne"; break;
16862 case EQ: case UNEQ:
16863 ccode = "eq"; break;
16865 ccode = "ge"; break;
16866 case GT: case GTU: case UNGT:
16867 ccode = "gt"; break;
16869 ccode = "le"; break;
16870 case LT: case LTU: case UNLT:
16871 ccode = "lt"; break;
16872 case UNORDERED: ccode = "un"; break;
16873 case ORDERED: ccode = "nu"; break;
16874 case UNGE: ccode = "nl"; break;
16875 case UNLE: ccode = "ng"; break;
16877 gcc_unreachable ();
16880 /* Maybe we have a guess as to how likely the branch is.
16881 The old mnemonics don't have a way to specify this information. */
16883 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16884 if (note != NULL_RTX)
16886 /* PROB is the difference from 50%. */
16887 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16889 /* Only hint for highly probable/improbable branches on newer
16890 cpus as static prediction overrides processor dynamic
16891 prediction. For older cpus we may as well always hint, but
16892 assume not taken for branches that are very close to 50% as a
16893 mispredicted taken branch is more expensive than a
16894 mispredicted not-taken branch. */
16895 if (rs6000_always_hint
16896 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16897 && br_prob_note_reliable_p (note)))
16899 if (abs (prob) > REG_BR_PROB_BASE / 20
16900 && ((prob > 0) ^ need_longbranch))
16908 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16910 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16912 /* We need to escape any '%' characters in the reg_names string.
16913 Assume they'd only be the first character.... */
16914 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16916 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16920 /* If the branch distance was too far, we may have to use an
16921 unconditional branch to go the distance. */
16922 if (need_longbranch)
16923 s += sprintf (s, ",$+8\n\tb %s", label);
16925 s += sprintf (s, ",%s", label);
16931 /* Return the string to flip the GT bit on a CR. */
16933 output_e500_flip_gt_bit (rtx dst, rtx src)
16935 static char string[64];
16938 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16939 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16942 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16943 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16945 sprintf (string, "crnot %d,%d", a, b);
16949 /* Return insn for VSX or Altivec comparisons. */
16952 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16955 enum machine_mode mode = GET_MODE (op0);
16963 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16969 mask = gen_reg_rtx (mode);
16970 emit_insn (gen_rtx_SET (VOIDmode,
16972 gen_rtx_fmt_ee (code, mode, op0, op1)));
16979 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16980 DMODE is expected destination mode. This is a recursive function. */
16983 rs6000_emit_vector_compare (enum rtx_code rcode,
16985 enum machine_mode dmode)
16988 bool swap_operands = false;
16989 bool try_again = false;
16991 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16992 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16994 /* See if the comparison works as is. */
16995 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17003 swap_operands = true;
17008 swap_operands = true;
17016 /* Invert condition and try again.
17017 e.g., A != B becomes ~(A==B). */
17019 enum rtx_code rev_code;
17020 enum insn_code nor_code;
17023 rev_code = reverse_condition_maybe_unordered (rcode);
17024 if (rev_code == UNKNOWN)
17027 nor_code = optab_handler (one_cmpl_optab, dmode);
17028 if (nor_code == CODE_FOR_nothing)
17031 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17035 mask = gen_reg_rtx (dmode);
17036 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17044 /* Try GT/GTU/LT/LTU OR EQ */
17047 enum insn_code ior_code;
17048 enum rtx_code new_code;
17069 gcc_unreachable ();
17072 ior_code = optab_handler (ior_optab, dmode);
17073 if (ior_code == CODE_FOR_nothing)
17076 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17080 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17084 mask = gen_reg_rtx (dmode);
17085 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17103 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17108 /* You only get two chances. */
17112 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17113 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17114 operands for the relation operation COND. */
17117 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17118 rtx cond, rtx cc_op0, rtx cc_op1)
17120 enum machine_mode dest_mode = GET_MODE (dest);
17121 enum rtx_code rcode = GET_CODE (cond);
17122 enum machine_mode cc_mode = CCmode;
17126 bool invert_move = false;
17128 if (VECTOR_UNIT_NONE_P (dest_mode))
17133 /* Swap operands if we can, and fall back to doing the operation as
17134 specified, and doing a NOR to invert the test. */
17140 /* Invert condition and try again.
17141 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17142 invert_move = true;
17143 rcode = reverse_condition_maybe_unordered (rcode);
17144 if (rcode == UNKNOWN)
17148 /* Mark unsigned tests with CCUNSmode. */
17153 cc_mode = CCUNSmode;
17160 /* Get the vector mask for the given relational operations. */
17161 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17169 op_true = op_false;
17173 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17174 emit_insn (gen_rtx_SET (VOIDmode,
17176 gen_rtx_IF_THEN_ELSE (dest_mode,
17183 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17184 operands of the last comparison is nonzero/true, FALSE_COND if it
17185 is zero/false. Return 0 if the hardware has no such operation. */
17188 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17190 enum rtx_code code = GET_CODE (op);
17191 rtx op0 = XEXP (op, 0);
17192 rtx op1 = XEXP (op, 1);
17193 REAL_VALUE_TYPE c1;
17194 enum machine_mode compare_mode = GET_MODE (op0);
17195 enum machine_mode result_mode = GET_MODE (dest);
17197 bool is_against_zero;
17199 /* These modes should always match. */
17200 if (GET_MODE (op1) != compare_mode
17201 /* In the isel case however, we can use a compare immediate, so
17202 op1 may be a small constant. */
17203 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17205 if (GET_MODE (true_cond) != result_mode)
17207 if (GET_MODE (false_cond) != result_mode)
17210 /* First, work out if the hardware can do this at all, or
17211 if it's too slow.... */
17212 if (!FLOAT_MODE_P (compare_mode))
17215 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17218 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17219 && SCALAR_FLOAT_MODE_P (compare_mode))
17222 is_against_zero = op1 == CONST0_RTX (compare_mode);
17224 /* A floating-point subtract might overflow, underflow, or produce
17225 an inexact result, thus changing the floating-point flags, so it
17226 can't be generated if we care about that. It's safe if one side
17227 of the construct is zero, since then no subtract will be
17229 if (SCALAR_FLOAT_MODE_P (compare_mode)
17230 && flag_trapping_math && ! is_against_zero)
17233 /* Eliminate half of the comparisons by switching operands, this
17234 makes the remaining code simpler. */
17235 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17236 || code == LTGT || code == LT || code == UNLE)
17238 code = reverse_condition_maybe_unordered (code);
17240 true_cond = false_cond;
17244 /* UNEQ and LTGT take four instructions for a comparison with zero,
17245 it'll probably be faster to use a branch here too. */
17246 if (code == UNEQ && HONOR_NANS (compare_mode))
17249 if (GET_CODE (op1) == CONST_DOUBLE)
17250 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17252 /* We're going to try to implement comparisons by performing
17253 a subtract, then comparing against zero. Unfortunately,
17254 Inf - Inf is NaN which is not zero, and so if we don't
17255 know that the operand is finite and the comparison
17256 would treat EQ different to UNORDERED, we can't do it. */
17257 if (HONOR_INFINITIES (compare_mode)
17258 && code != GT && code != UNGE
17259 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17260 /* Constructs of the form (a OP b ? a : b) are safe. */
17261 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17262 || (! rtx_equal_p (op0, true_cond)
17263 && ! rtx_equal_p (op1, true_cond))))
17266 /* At this point we know we can use fsel. */
17268 /* Reduce the comparison to a comparison against zero. */
17269 if (! is_against_zero)
17271 temp = gen_reg_rtx (compare_mode);
17272 emit_insn (gen_rtx_SET (VOIDmode, temp,
17273 gen_rtx_MINUS (compare_mode, op0, op1)));
17275 op1 = CONST0_RTX (compare_mode);
17278 /* If we don't care about NaNs we can reduce some of the comparisons
17279 down to faster ones. */
17280 if (! HONOR_NANS (compare_mode))
17286 true_cond = false_cond;
17299 /* Now, reduce everything down to a GE. */
17306 temp = gen_reg_rtx (compare_mode);
17307 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17312 temp = gen_reg_rtx (compare_mode);
17313 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17318 temp = gen_reg_rtx (compare_mode);
17319 emit_insn (gen_rtx_SET (VOIDmode, temp,
17320 gen_rtx_NEG (compare_mode,
17321 gen_rtx_ABS (compare_mode, op0))));
17326 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17327 temp = gen_reg_rtx (result_mode);
17328 emit_insn (gen_rtx_SET (VOIDmode, temp,
17329 gen_rtx_IF_THEN_ELSE (result_mode,
17330 gen_rtx_GE (VOIDmode,
17332 true_cond, false_cond)));
17333 false_cond = true_cond;
17336 temp = gen_reg_rtx (compare_mode);
17337 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17342 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17343 temp = gen_reg_rtx (result_mode);
17344 emit_insn (gen_rtx_SET (VOIDmode, temp,
17345 gen_rtx_IF_THEN_ELSE (result_mode,
17346 gen_rtx_GE (VOIDmode,
17348 true_cond, false_cond)));
17349 true_cond = false_cond;
17352 temp = gen_reg_rtx (compare_mode);
17353 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17358 gcc_unreachable ();
17361 emit_insn (gen_rtx_SET (VOIDmode, dest,
17362 gen_rtx_IF_THEN_ELSE (result_mode,
17363 gen_rtx_GE (VOIDmode,
17365 true_cond, false_cond)));
17369 /* Same as above, but for ints (isel). */
17372 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17374 rtx condition_rtx, cr;
17375 enum machine_mode mode = GET_MODE (dest);
17376 enum rtx_code cond_code;
17377 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17380 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17383 /* We still have to do the compare, because isel doesn't do a
17384 compare, it just looks at the CRx bits set by a previous compare
17386 condition_rtx = rs6000_generate_compare (op, mode);
17387 cond_code = GET_CODE (condition_rtx);
17388 cr = XEXP (condition_rtx, 0);
17389 signedp = GET_MODE (cr) == CCmode;
17391 isel_func = (mode == SImode
17392 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17393 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17397 case LT: case GT: case LTU: case GTU: case EQ:
17398 /* isel handles these directly. */
17402 /* We need to swap the sense of the comparison. */
17405 true_cond = false_cond;
17407 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17412 false_cond = force_reg (mode, false_cond);
17413 if (true_cond != const0_rtx)
17414 true_cond = force_reg (mode, true_cond);
17416 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17422 output_isel (rtx *operands)
17424 enum rtx_code code;
17426 code = GET_CODE (operands[1]);
17428 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17430 gcc_assert (GET_CODE (operands[2]) == REG
17431 && GET_CODE (operands[3]) == REG);
17432 PUT_CODE (operands[1], reverse_condition (code));
17433 return "isel %0,%3,%2,%j1";
17436 return "isel %0,%2,%3,%j1";
17440 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17442 enum machine_mode mode = GET_MODE (op0);
17446 /* VSX/altivec have direct min/max insns. */
17447 if ((code == SMAX || code == SMIN)
17448 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17449 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17451 emit_insn (gen_rtx_SET (VOIDmode,
17453 gen_rtx_fmt_ee (code, mode, op0, op1)));
17457 if (code == SMAX || code == SMIN)
17462 if (code == SMAX || code == UMAX)
17463 target = emit_conditional_move (dest, c, op0, op1, mode,
17464 op0, op1, mode, 0);
17466 target = emit_conditional_move (dest, c, op0, op1, mode,
17467 op1, op0, mode, 0);
17468 gcc_assert (target);
17469 if (target != dest)
17470 emit_move_insn (dest, target);
17473 /* Emit instructions to perform a load-reserved/store-conditional operation.
17474 The operation performed is an atomic
17475 (set M (CODE:MODE M OP))
17476 If not NULL, BEFORE is atomically set to M before the operation, and
17477 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17478 If SYNC_P then a memory barrier is emitted before the operation.
17479 Either OP or M may be wrapped in a NOT operation. */
17482 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17483 rtx m, rtx op, rtx before_param, rtx after_param,
17486 enum machine_mode used_mode;
17487 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17490 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17491 rtx shift = NULL_RTX;
17494 emit_insn (gen_lwsync ());
17498 /* If this is smaller than SImode, we'll have to use SImode with
17500 if (mode == QImode || mode == HImode)
17504 if (MEM_ALIGN (used_m) >= 32)
17507 if (BYTES_BIG_ENDIAN)
17508 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17510 shift = GEN_INT (ishift);
17511 used_m = change_address (used_m, SImode, 0);
17515 rtx addrSI, aligned_addr;
17516 int shift_mask = mode == QImode ? 0x18 : 0x10;
17518 addrSI = gen_lowpart_common (SImode,
17519 force_reg (Pmode, XEXP (used_m, 0)));
17520 addrSI = force_reg (SImode, addrSI);
17521 shift = gen_reg_rtx (SImode);
17523 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17524 GEN_INT (shift_mask)));
17525 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17527 aligned_addr = expand_binop (Pmode, and_optab,
17529 GEN_INT (-4), NULL_RTX,
17530 1, OPTAB_LIB_WIDEN);
17531 used_m = change_address (used_m, SImode, aligned_addr);
17532 set_mem_align (used_m, 32);
17534 /* It's safe to keep the old alias set of USED_M, because
17535 the operation is atomic and only affects the original
17539 if (GET_CODE (op) == NOT)
17541 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17542 oldop = gen_rtx_NOT (SImode, oldop);
17545 oldop = lowpart_subreg (SImode, op, mode);
17551 newop = expand_binop (SImode, and_optab,
17552 oldop, GEN_INT (imask), NULL_RTX,
17553 1, OPTAB_LIB_WIDEN);
17554 emit_insn (gen_ashlsi3 (newop, newop, shift));
17557 case NOT: /* NAND */
17558 newop = expand_binop (SImode, ior_optab,
17559 oldop, GEN_INT (~imask), NULL_RTX,
17560 1, OPTAB_LIB_WIDEN);
17561 emit_insn (gen_rotlsi3 (newop, newop, shift));
17565 newop = expand_binop (SImode, ior_optab,
17566 oldop, GEN_INT (~imask), NULL_RTX,
17567 1, OPTAB_LIB_WIDEN);
17568 emit_insn (gen_rotlsi3 (newop, newop, shift));
17576 newop = expand_binop (SImode, and_optab,
17577 oldop, GEN_INT (imask), NULL_RTX,
17578 1, OPTAB_LIB_WIDEN);
17579 emit_insn (gen_ashlsi3 (newop, newop, shift));
17581 mask = gen_reg_rtx (SImode);
17582 emit_move_insn (mask, GEN_INT (imask));
17583 emit_insn (gen_ashlsi3 (mask, mask, shift));
17586 newop = gen_rtx_PLUS (SImode, m, newop);
17588 newop = gen_rtx_MINUS (SImode, m, newop);
17589 newop = gen_rtx_AND (SImode, newop, mask);
17590 newop = gen_rtx_IOR (SImode, newop,
17591 gen_rtx_AND (SImode,
17592 gen_rtx_NOT (SImode, mask),
17598 gcc_unreachable ();
17602 used_mode = SImode;
17603 before = gen_reg_rtx (used_mode);
17604 after = gen_reg_rtx (used_mode);
17609 before = before_param;
17610 after = after_param;
17612 if (before == NULL_RTX)
17613 before = gen_reg_rtx (used_mode);
17614 if (after == NULL_RTX)
17615 after = gen_reg_rtx (used_mode);
17618 if ((code == PLUS || code == MINUS)
17619 && used_mode != mode)
17620 the_op = op; /* Computed above. */
17621 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17622 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17623 else if (code == NOT)
17624 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17625 gen_rtx_NOT (used_mode, m),
17626 gen_rtx_NOT (used_mode, op));
17628 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17630 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17631 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17632 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17633 gen_rtx_UNSPEC (used_mode,
17634 gen_rtvec (1, the_op),
17636 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17638 if ((code == PLUS || code == MINUS) && used_mode != mode)
17639 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17640 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17642 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17643 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17645 /* Shift and mask the return values properly. */
17646 if (used_mode != mode && before_param)
17648 emit_insn (gen_lshrsi3 (before, before, shift));
17649 convert_move (before_param, before, 1);
17652 if (used_mode != mode && after_param)
17654 emit_insn (gen_lshrsi3 (after, after, shift));
17655 convert_move (after_param, after, 1);
17658 /* The previous sequence will end with a branch that's dependent on
17659 the conditional store, so placing an isync will ensure that no
17660 other instructions (especially, no load or store instructions)
17661 can start before the atomic operation completes. */
17663 emit_insn (gen_isync ());
17666 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17667 COND is true. Mark the jump as unlikely to be taken. */
17670 emit_unlikely_jump (rtx cond, rtx label)
17672 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17675 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17676 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17677 add_reg_note (x, REG_BR_PROB, very_unlikely);
17680 /* A subroutine of the atomic operation splitters. Emit a load-locked
17681 instruction in MODE. */
17684 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17686 rtx (*fn) (rtx, rtx) = NULL;
17687 if (mode == SImode)
17688 fn = gen_load_locked_si;
17689 else if (mode == DImode)
17690 fn = gen_load_locked_di;
17691 emit_insn (fn (reg, mem));
17694 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17695 instruction in MODE. */
17698 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17700 rtx (*fn) (rtx, rtx, rtx) = NULL;
17701 if (mode == SImode)
17702 fn = gen_store_conditional_si;
17703 else if (mode == DImode)
17704 fn = gen_store_conditional_di;
17706 /* Emit sync before stwcx. to address PPC405 Erratum. */
17707 if (PPC405_ERRATUM77)
17708 emit_insn (gen_memory_barrier ());
17710 emit_insn (fn (res, mem, val));
17713 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17714 to perform. MEM is the memory on which to operate. VAL is the second
17715 operand of the binary operator. BEFORE and AFTER are optional locations to
17716 return the value of MEM either before of after the operation. SCRATCH is
17717 a scratch register. */
17720 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17721 rtx before, rtx after, rtx scratch)
17723 enum machine_mode mode = GET_MODE (mem);
17724 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17726 emit_insn (gen_lwsync ());
17728 label = gen_label_rtx ();
17729 emit_label (label);
17730 label = gen_rtx_LABEL_REF (VOIDmode, label);
17732 if (before == NULL_RTX)
17734 emit_load_locked (mode, before, mem);
17737 x = gen_rtx_IOR (mode,
17738 gen_rtx_NOT (mode, before),
17739 gen_rtx_NOT (mode, val));
17740 else if (code == AND)
17741 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17743 x = gen_rtx_fmt_ee (code, mode, before, val);
17745 if (after != NULL_RTX)
17746 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17747 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17749 emit_store_conditional (mode, cond, mem, scratch);
17751 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17752 emit_unlikely_jump (x, label);
17754 emit_insn (gen_isync ());
17757 /* Expand an atomic compare and swap operation. MEM is the memory on which
17758 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17759 value to be stored. SCRATCH is a scratch GPR. */
17762 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17765 enum machine_mode mode = GET_MODE (mem);
17766 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17768 emit_insn (gen_lwsync ());
17770 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17771 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17772 emit_label (XEXP (label1, 0));
17774 emit_load_locked (mode, retval, mem);
17776 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17777 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17779 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17780 emit_unlikely_jump (x, label2);
17782 emit_move_insn (scratch, newval);
17783 emit_store_conditional (mode, cond, mem, scratch);
17785 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17786 emit_unlikely_jump (x, label1);
17788 emit_insn (gen_isync ());
17789 emit_label (XEXP (label2, 0));
17792 /* Expand an atomic test and set operation. MEM is the memory on which
17793 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17796 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17798 enum machine_mode mode = GET_MODE (mem);
17799 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17801 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17802 emit_label (XEXP (label, 0));
17804 emit_load_locked (mode, retval, mem);
17805 emit_move_insn (scratch, val);
17806 emit_store_conditional (mode, cond, mem, scratch);
17808 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17809 emit_unlikely_jump (x, label);
17811 emit_insn (gen_isync ());
17815 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17817 enum machine_mode mode = GET_MODE (mem);
17818 rtx addrSI, align, wdst, shift, mask;
17819 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17820 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17822 /* Shift amount for subword relative to aligned word. */
17823 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17824 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17825 shift = gen_reg_rtx (SImode);
17826 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17827 GEN_INT (shift_mask)));
17828 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17830 /* Shift and mask old value into position within word. */
17831 oldval = convert_modes (SImode, mode, oldval, 1);
17832 oldval = expand_binop (SImode, and_optab,
17833 oldval, GEN_INT (imask), NULL_RTX,
17834 1, OPTAB_LIB_WIDEN);
17835 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17837 /* Shift and mask new value into position within word. */
17838 newval = convert_modes (SImode, mode, newval, 1);
17839 newval = expand_binop (SImode, and_optab,
17840 newval, GEN_INT (imask), NULL_RTX,
17841 1, OPTAB_LIB_WIDEN);
17842 emit_insn (gen_ashlsi3 (newval, newval, shift));
17844 /* Mask for insertion. */
17845 mask = gen_reg_rtx (SImode);
17846 emit_move_insn (mask, GEN_INT (imask));
17847 emit_insn (gen_ashlsi3 (mask, mask, shift));
17849 /* Address of aligned word containing subword. */
17850 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17851 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17852 mem = change_address (mem, SImode, align);
17853 set_mem_align (mem, 32);
17854 MEM_VOLATILE_P (mem) = 1;
17856 wdst = gen_reg_rtx (SImode);
17857 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17858 oldval, newval, mem));
17860 /* Shift the result back. */
17861 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17863 emit_move_insn (dst, gen_lowpart (mode, wdst));
17867 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17868 rtx oldval, rtx newval, rtx mem,
17871 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17873 emit_insn (gen_lwsync ());
17874 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17875 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17876 emit_label (XEXP (label1, 0));
17878 emit_load_locked (SImode, scratch, mem);
17880 /* Mask subword within loaded value for comparison with oldval.
17881 Use UNSPEC_AND to avoid clobber.*/
17882 emit_insn (gen_rtx_SET (SImode, dest,
17883 gen_rtx_UNSPEC (SImode,
17884 gen_rtvec (2, scratch, mask),
17887 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17888 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17890 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17891 emit_unlikely_jump (x, label2);
17893 /* Clear subword within loaded value for insertion of new value. */
17894 emit_insn (gen_rtx_SET (SImode, scratch,
17895 gen_rtx_AND (SImode,
17896 gen_rtx_NOT (SImode, mask), scratch)));
17897 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17898 emit_store_conditional (SImode, cond, mem, scratch);
17900 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17901 emit_unlikely_jump (x, label1);
17903 emit_insn (gen_isync ());
17904 emit_label (XEXP (label2, 0));
17908 /* Emit instructions to move SRC to DST. Called by splitters for
17909 multi-register moves. It will emit at most one instruction for
17910 each register that is accessed; that is, it won't emit li/lis pairs
17911 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17915 rs6000_split_multireg_move (rtx dst, rtx src)
17917 /* The register number of the first register being moved. */
17919 /* The mode that is to be moved. */
17920 enum machine_mode mode;
17921 /* The mode that the move is being done in, and its size. */
17922 enum machine_mode reg_mode;
17924 /* The number of registers that will be moved. */
17927 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17928 mode = GET_MODE (dst);
17929 nregs = hard_regno_nregs[reg][mode];
17930 if (FP_REGNO_P (reg))
17931 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17932 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17933 else if (ALTIVEC_REGNO_P (reg))
17934 reg_mode = V16QImode;
17935 else if (TARGET_E500_DOUBLE && mode == TFmode)
17938 reg_mode = word_mode;
17939 reg_mode_size = GET_MODE_SIZE (reg_mode);
17941 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17943 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17945 /* Move register range backwards, if we might have destructive
17948 for (i = nregs - 1; i >= 0; i--)
17949 emit_insn (gen_rtx_SET (VOIDmode,
17950 simplify_gen_subreg (reg_mode, dst, mode,
17951 i * reg_mode_size),
17952 simplify_gen_subreg (reg_mode, src, mode,
17953 i * reg_mode_size)));
17959 bool used_update = false;
17960 rtx restore_basereg = NULL_RTX;
17962 if (MEM_P (src) && INT_REGNO_P (reg))
17966 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17967 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17970 breg = XEXP (XEXP (src, 0), 0);
17971 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17972 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17973 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17974 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17975 src = replace_equiv_address (src, breg);
17977 else if (! rs6000_offsettable_memref_p (src))
17979 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17981 rtx basereg = XEXP (XEXP (src, 0), 0);
17984 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17985 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17986 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17987 used_update = true;
17990 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17991 XEXP (XEXP (src, 0), 1)));
17992 src = replace_equiv_address (src, basereg);
17996 rtx basereg = gen_rtx_REG (Pmode, reg);
17997 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17998 src = replace_equiv_address (src, basereg);
18002 breg = XEXP (src, 0);
18003 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18004 breg = XEXP (breg, 0);
18006 /* If the base register we are using to address memory is
18007 also a destination reg, then change that register last. */
18009 && REGNO (breg) >= REGNO (dst)
18010 && REGNO (breg) < REGNO (dst) + nregs)
18011 j = REGNO (breg) - REGNO (dst);
18013 else if (MEM_P (dst) && INT_REGNO_P (reg))
18017 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18018 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18021 breg = XEXP (XEXP (dst, 0), 0);
18022 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18023 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18024 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18026 /* We have to update the breg before doing the store.
18027 Use store with update, if available. */
18031 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18032 emit_insn (TARGET_32BIT
18033 ? (TARGET_POWERPC64
18034 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18035 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18036 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18037 used_update = true;
18040 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18041 dst = replace_equiv_address (dst, breg);
18043 else if (!rs6000_offsettable_memref_p (dst)
18044 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18046 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18048 rtx basereg = XEXP (XEXP (dst, 0), 0);
18051 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18052 emit_insn (gen_rtx_SET (VOIDmode,
18053 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18054 used_update = true;
18057 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18058 XEXP (XEXP (dst, 0), 1)));
18059 dst = replace_equiv_address (dst, basereg);
18063 rtx basereg = XEXP (XEXP (dst, 0), 0);
18064 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18065 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18067 && REG_P (offsetreg)
18068 && REGNO (basereg) != REGNO (offsetreg));
18069 if (REGNO (basereg) == 0)
18071 rtx tmp = offsetreg;
18072 offsetreg = basereg;
18075 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18076 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18077 dst = replace_equiv_address (dst, basereg);
18080 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18081 gcc_assert (rs6000_offsettable_memref_p (dst));
18084 for (i = 0; i < nregs; i++)
18086 /* Calculate index to next subword. */
18091 /* If compiler already emitted move of first word by
18092 store with update, no need to do anything. */
18093 if (j == 0 && used_update)
18096 emit_insn (gen_rtx_SET (VOIDmode,
18097 simplify_gen_subreg (reg_mode, dst, mode,
18098 j * reg_mode_size),
18099 simplify_gen_subreg (reg_mode, src, mode,
18100 j * reg_mode_size)));
18102 if (restore_basereg != NULL_RTX)
18103 emit_insn (restore_basereg);
18108 /* This page contains routines that are used to determine what the
18109 function prologue and epilogue code will do and write them out. */
18111 /* Return the first fixed-point register that is required to be
18112 saved. 32 if none. */
18115 first_reg_to_save (void)
18119 /* Find lowest numbered live register. */
18120 for (first_reg = 13; first_reg <= 31; first_reg++)
18121 if (df_regs_ever_live_p (first_reg)
18122 && (! call_used_regs[first_reg]
18123 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18124 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18125 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18126 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18131 && crtl->uses_pic_offset_table
18132 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18133 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18139 /* Similar, for FP regs. */
18142 first_fp_reg_to_save (void)
18146 /* Find lowest numbered live register. */
18147 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18148 if (df_regs_ever_live_p (first_reg))
18154 /* Similar, for AltiVec regs. */
18157 first_altivec_reg_to_save (void)
18161 /* Stack frame remains as is unless we are in AltiVec ABI. */
18162 if (! TARGET_ALTIVEC_ABI)
18163 return LAST_ALTIVEC_REGNO + 1;
18165 /* On Darwin, the unwind routines are compiled without
18166 TARGET_ALTIVEC, and use save_world to save/restore the
18167 altivec registers when necessary. */
18168 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18169 && ! TARGET_ALTIVEC)
18170 return FIRST_ALTIVEC_REGNO + 20;
18172 /* Find lowest numbered live register. */
18173 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18174 if (df_regs_ever_live_p (i))
18180 /* Return a 32-bit mask of the AltiVec registers we need to set in
18181 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18182 the 32-bit word is 0. */
18184 static unsigned int
18185 compute_vrsave_mask (void)
18187 unsigned int i, mask = 0;
18189 /* On Darwin, the unwind routines are compiled without
18190 TARGET_ALTIVEC, and use save_world to save/restore the
18191 call-saved altivec registers when necessary. */
18192 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18193 && ! TARGET_ALTIVEC)
18196 /* First, find out if we use _any_ altivec registers. */
18197 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18198 if (df_regs_ever_live_p (i))
18199 mask |= ALTIVEC_REG_BIT (i);
18204 /* Next, remove the argument registers from the set. These must
18205 be in the VRSAVE mask set by the caller, so we don't need to add
18206 them in again. More importantly, the mask we compute here is
18207 used to generate CLOBBERs in the set_vrsave insn, and we do not
18208 wish the argument registers to die. */
18209 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18210 mask &= ~ALTIVEC_REG_BIT (i);
18212 /* Similarly, remove the return value from the set. */
18215 diddle_return_value (is_altivec_return_reg, &yes);
18217 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18223 /* For a very restricted set of circumstances, we can cut down the
18224 size of prologues/epilogues by calling our own save/restore-the-world
18228 compute_save_world_info (rs6000_stack_t *info_ptr)
18230 info_ptr->world_save_p = 1;
18231 info_ptr->world_save_p
18232 = (WORLD_SAVE_P (info_ptr)
18233 && DEFAULT_ABI == ABI_DARWIN
18234 && ! (cfun->calls_setjmp && flag_exceptions)
18235 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18236 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18237 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18238 && info_ptr->cr_save_p);
18240 /* This will not work in conjunction with sibcalls. Make sure there
18241 are none. (This check is expensive, but seldom executed.) */
18242 if (WORLD_SAVE_P (info_ptr))
18245 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18246 if ( GET_CODE (insn) == CALL_INSN
18247 && SIBLING_CALL_P (insn))
18249 info_ptr->world_save_p = 0;
18254 if (WORLD_SAVE_P (info_ptr))
18256 /* Even if we're not touching VRsave, make sure there's room on the
18257 stack for it, if it looks like we're calling SAVE_WORLD, which
18258 will attempt to save it. */
18259 info_ptr->vrsave_size = 4;
18261 /* If we are going to save the world, we need to save the link register too. */
18262 info_ptr->lr_save_p = 1;
18264 /* "Save" the VRsave register too if we're saving the world. */
18265 if (info_ptr->vrsave_mask == 0)
18266 info_ptr->vrsave_mask = compute_vrsave_mask ();
18268 /* Because the Darwin register save/restore routines only handle
18269 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18271 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18272 && (info_ptr->first_altivec_reg_save
18273 >= FIRST_SAVED_ALTIVEC_REGNO));
18280 is_altivec_return_reg (rtx reg, void *xyes)
18282 bool *yes = (bool *) xyes;
18283 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18288 /* Determine the strategy for savings/restoring registers. */
18291 SAVRES_MULTIPLE = 0x1,
18292 SAVE_INLINE_FPRS = 0x2,
18293 SAVE_INLINE_GPRS = 0x4,
18294 REST_INLINE_FPRS = 0x8,
18295 REST_INLINE_GPRS = 0x10,
18296 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18297 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18298 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18302 rs6000_savres_strategy (rs6000_stack_t *info,
18303 bool using_static_chain_p)
18307 if (TARGET_MULTIPLE
18308 && !TARGET_POWERPC64
18309 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18310 && info->first_gp_reg_save < 31
18311 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18312 strategy |= SAVRES_MULTIPLE;
18314 if (crtl->calls_eh_return
18315 || cfun->machine->ra_need_lr
18316 || info->total_size > 32767)
18317 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18318 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18320 if (info->first_fp_reg_save == 64
18321 || FP_SAVE_INLINE (info->first_fp_reg_save)
18322 /* The out-of-line FP routines use double-precision stores;
18323 we can't use those routines if we don't have such stores. */
18324 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18325 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18326 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18328 if (info->first_gp_reg_save == 32
18329 || GP_SAVE_INLINE (info->first_gp_reg_save)
18330 || !((strategy & SAVRES_MULTIPLE)
18331 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18332 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18334 /* Don't bother to try to save things out-of-line if r11 is occupied
18335 by the static chain. It would require too much fiddling and the
18336 static chain is rarely used anyway. */
18337 if (using_static_chain_p)
18338 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18340 /* If we are going to use store multiple, then don't even bother
18341 with the out-of-line routines, since the store-multiple
18342 instruction will always be smaller. */
18343 if ((strategy & SAVRES_MULTIPLE))
18344 strategy |= SAVE_INLINE_GPRS;
18346 /* The situation is more complicated with load multiple. We'd
18347 prefer to use the out-of-line routines for restores, since the
18348 "exit" out-of-line routines can handle the restore of LR and the
18349 frame teardown. However if doesn't make sense to use the
18350 out-of-line routine if that is the only reason we'd need to save
18351 LR, and we can't use the "exit" out-of-line gpr restore if we
18352 have saved some fprs; In those cases it is advantageous to use
18353 load multiple when available. */
18354 if ((strategy & SAVRES_MULTIPLE)
18355 && (!info->lr_save_p
18356 || info->first_fp_reg_save != 64))
18357 strategy |= REST_INLINE_GPRS;
18359 /* We can only use load multiple or the out-of-line routines to
18360 restore if we've used store multiple or out-of-line routines
18361 in the prologue, i.e. if we've saved all the registers from
18362 first_gp_reg_save. Otherwise, we risk loading garbage. */
18363 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18364 strategy |= REST_INLINE_GPRS;
18366 /* Saving CR interferes with the exit routines used on the SPE, so
18369 && info->spe_64bit_regs_used
18370 && info->cr_save_p)
18371 strategy |= REST_INLINE_GPRS;
18373 #ifdef POWERPC_LINUX
18376 if (!(strategy & SAVE_INLINE_FPRS))
18377 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18378 else if (!(strategy & SAVE_INLINE_GPRS)
18379 && info->first_fp_reg_save == 64)
18380 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18383 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18384 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18389 /* Calculate the stack information for the current function. This is
18390 complicated by having two separate calling sequences, the AIX calling
18391 sequence and the V.4 calling sequence.
18393 AIX (and Darwin/Mac OS X) stack frames look like:
18395 SP----> +---------------------------------------+
18396 | back chain to caller | 0 0
18397 +---------------------------------------+
18398 | saved CR | 4 8 (8-11)
18399 +---------------------------------------+
18401 +---------------------------------------+
18402 | reserved for compilers | 12 24
18403 +---------------------------------------+
18404 | reserved for binders | 16 32
18405 +---------------------------------------+
18406 | saved TOC pointer | 20 40
18407 +---------------------------------------+
18408 | Parameter save area (P) | 24 48
18409 +---------------------------------------+
18410 | Alloca space (A) | 24+P etc.
18411 +---------------------------------------+
18412 | Local variable space (L) | 24+P+A
18413 +---------------------------------------+
18414 | Float/int conversion temporary (X) | 24+P+A+L
18415 +---------------------------------------+
18416 | Save area for AltiVec registers (W) | 24+P+A+L+X
18417 +---------------------------------------+
18418 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18419 +---------------------------------------+
18420 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18421 +---------------------------------------+
18422 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18423 +---------------------------------------+
18424 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18425 +---------------------------------------+
18426 old SP->| back chain to caller's caller |
18427 +---------------------------------------+
18429 The required alignment for AIX configurations is two words (i.e., 8
18433 V.4 stack frames look like:
18435 SP----> +---------------------------------------+
18436 | back chain to caller | 0
18437 +---------------------------------------+
18438 | caller's saved LR | 4
18439 +---------------------------------------+
18440 | Parameter save area (P) | 8
18441 +---------------------------------------+
18442 | Alloca space (A) | 8+P
18443 +---------------------------------------+
18444 | Varargs save area (V) | 8+P+A
18445 +---------------------------------------+
18446 | Local variable space (L) | 8+P+A+V
18447 +---------------------------------------+
18448 | Float/int conversion temporary (X) | 8+P+A+V+L
18449 +---------------------------------------+
18450 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18451 +---------------------------------------+
18452 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18453 +---------------------------------------+
18454 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18455 +---------------------------------------+
18456 | SPE: area for 64-bit GP registers |
18457 +---------------------------------------+
18458 | SPE alignment padding |
18459 +---------------------------------------+
18460 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18461 +---------------------------------------+
18462 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18463 +---------------------------------------+
18464 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18465 +---------------------------------------+
18466 old SP->| back chain to caller's caller |
18467 +---------------------------------------+
18469 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18470 given. (But note below and in sysv4.h that we require only 8 and
18471 may round up the size of our stack frame anyways. The historical
18472 reason is early versions of powerpc-linux which didn't properly
18473 align the stack at program startup. A happy side-effect is that
18474 -mno-eabi libraries can be used with -meabi programs.)
18476 The EABI configuration defaults to the V.4 layout. However,
18477 the stack alignment requirements may differ. If -mno-eabi is not
18478 given, the required stack alignment is 8 bytes; if -mno-eabi is
18479 given, the required alignment is 16 bytes. (But see V.4 comment
18482 #ifndef ABI_STACK_BOUNDARY
18483 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18486 static rs6000_stack_t *
18487 rs6000_stack_info (void)
18489 rs6000_stack_t *info_ptr = &stack_info;
18490 int reg_size = TARGET_32BIT ? 4 : 8;
18494 HOST_WIDE_INT non_fixed_size;
18495 bool using_static_chain_p;
18497 if (reload_completed && info_ptr->reload_completed)
18500 memset (info_ptr, 0, sizeof (*info_ptr));
18501 info_ptr->reload_completed = reload_completed;
18505 /* Cache value so we don't rescan instruction chain over and over. */
18506 if (cfun->machine->insn_chain_scanned_p == 0)
18507 cfun->machine->insn_chain_scanned_p
18508 = spe_func_has_64bit_regs_p () + 1;
18509 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18512 /* Select which calling sequence. */
18513 info_ptr->abi = DEFAULT_ABI;
18515 /* Calculate which registers need to be saved & save area size. */
18516 info_ptr->first_gp_reg_save = first_reg_to_save ();
18517 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18518 even if it currently looks like we won't. Reload may need it to
18519 get at a constant; if so, it will have already created a constant
18520 pool entry for it. */
18521 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18522 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18523 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18524 && crtl->uses_const_pool
18525 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18526 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18528 first_gp = info_ptr->first_gp_reg_save;
18530 info_ptr->gp_size = reg_size * (32 - first_gp);
18532 /* For the SPE, we have an additional upper 32-bits on each GPR.
18533 Ideally we should save the entire 64-bits only when the upper
18534 half is used in SIMD instructions. Since we only record
18535 registers live (not the size they are used in), this proves
18536 difficult because we'd have to traverse the instruction chain at
18537 the right time, taking reload into account. This is a real pain,
18538 so we opt to save the GPRs in 64-bits always if but one register
18539 gets used in 64-bits. Otherwise, all the registers in the frame
18540 get saved in 32-bits.
18542 So... since when we save all GPRs (except the SP) in 64-bits, the
18543 traditional GP save area will be empty. */
18544 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18545 info_ptr->gp_size = 0;
18547 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18548 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18550 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18551 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18552 - info_ptr->first_altivec_reg_save);
18554 /* Does this function call anything? */
18555 info_ptr->calls_p = (! current_function_is_leaf
18556 || cfun->machine->ra_needs_full_frame);
18558 /* Determine if we need to save the condition code registers. */
18559 if (df_regs_ever_live_p (CR2_REGNO)
18560 || df_regs_ever_live_p (CR3_REGNO)
18561 || df_regs_ever_live_p (CR4_REGNO))
18563 info_ptr->cr_save_p = 1;
18564 if (DEFAULT_ABI == ABI_V4)
18565 info_ptr->cr_size = reg_size;
18568 /* If the current function calls __builtin_eh_return, then we need
18569 to allocate stack space for registers that will hold data for
18570 the exception handler. */
18571 if (crtl->calls_eh_return)
18574 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18577 /* SPE saves EH registers in 64-bits. */
18578 ehrd_size = i * (TARGET_SPE_ABI
18579 && info_ptr->spe_64bit_regs_used != 0
18580 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18585 /* Determine various sizes. */
18586 info_ptr->reg_size = reg_size;
18587 info_ptr->fixed_size = RS6000_SAVE_AREA;
18588 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18589 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18590 TARGET_ALTIVEC ? 16 : 8);
18591 if (FRAME_GROWS_DOWNWARD)
18592 info_ptr->vars_size
18593 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18594 + info_ptr->parm_size,
18595 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18596 - (info_ptr->fixed_size + info_ptr->vars_size
18597 + info_ptr->parm_size);
18599 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18600 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18602 info_ptr->spe_gp_size = 0;
18604 if (TARGET_ALTIVEC_ABI)
18605 info_ptr->vrsave_mask = compute_vrsave_mask ();
18607 info_ptr->vrsave_mask = 0;
18609 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18610 info_ptr->vrsave_size = 4;
18612 info_ptr->vrsave_size = 0;
18614 compute_save_world_info (info_ptr);
18616 /* Calculate the offsets. */
18617 switch (DEFAULT_ABI)
18621 gcc_unreachable ();
18625 info_ptr->fp_save_offset = - info_ptr->fp_size;
18626 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18628 if (TARGET_ALTIVEC_ABI)
18630 info_ptr->vrsave_save_offset
18631 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18633 /* Align stack so vector save area is on a quadword boundary.
18634 The padding goes above the vectors. */
18635 if (info_ptr->altivec_size != 0)
18636 info_ptr->altivec_padding_size
18637 = info_ptr->vrsave_save_offset & 0xF;
18639 info_ptr->altivec_padding_size = 0;
18641 info_ptr->altivec_save_offset
18642 = info_ptr->vrsave_save_offset
18643 - info_ptr->altivec_padding_size
18644 - info_ptr->altivec_size;
18645 gcc_assert (info_ptr->altivec_size == 0
18646 || info_ptr->altivec_save_offset % 16 == 0);
18648 /* Adjust for AltiVec case. */
18649 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18652 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18653 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18654 info_ptr->lr_save_offset = 2*reg_size;
18658 info_ptr->fp_save_offset = - info_ptr->fp_size;
18659 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18660 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18662 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18664 /* Align stack so SPE GPR save area is aligned on a
18665 double-word boundary. */
18666 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18667 info_ptr->spe_padding_size
18668 = 8 - (-info_ptr->cr_save_offset % 8);
18670 info_ptr->spe_padding_size = 0;
18672 info_ptr->spe_gp_save_offset
18673 = info_ptr->cr_save_offset
18674 - info_ptr->spe_padding_size
18675 - info_ptr->spe_gp_size;
18677 /* Adjust for SPE case. */
18678 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18680 else if (TARGET_ALTIVEC_ABI)
18682 info_ptr->vrsave_save_offset
18683 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18685 /* Align stack so vector save area is on a quadword boundary. */
18686 if (info_ptr->altivec_size != 0)
18687 info_ptr->altivec_padding_size
18688 = 16 - (-info_ptr->vrsave_save_offset % 16);
18690 info_ptr->altivec_padding_size = 0;
18692 info_ptr->altivec_save_offset
18693 = info_ptr->vrsave_save_offset
18694 - info_ptr->altivec_padding_size
18695 - info_ptr->altivec_size;
18697 /* Adjust for AltiVec case. */
18698 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18701 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18702 info_ptr->ehrd_offset -= ehrd_size;
18703 info_ptr->lr_save_offset = reg_size;
18707 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18708 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18709 + info_ptr->gp_size
18710 + info_ptr->altivec_size
18711 + info_ptr->altivec_padding_size
18712 + info_ptr->spe_gp_size
18713 + info_ptr->spe_padding_size
18715 + info_ptr->cr_size
18716 + info_ptr->vrsave_size,
18719 non_fixed_size = (info_ptr->vars_size
18720 + info_ptr->parm_size
18721 + info_ptr->save_size);
18723 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18724 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18726 /* Determine if we need to save the link register. */
18727 if (info_ptr->calls_p
18728 || (DEFAULT_ABI == ABI_AIX
18730 && !TARGET_PROFILE_KERNEL)
18731 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18732 #ifdef TARGET_RELOCATABLE
18733 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18735 || rs6000_ra_ever_killed ())
18736 info_ptr->lr_save_p = 1;
18738 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18739 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18740 && call_used_regs[STATIC_CHAIN_REGNUM]);
18741 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18742 using_static_chain_p);
18744 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18745 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18746 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18747 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18748 info_ptr->lr_save_p = 1;
18750 if (info_ptr->lr_save_p)
18751 df_set_regs_ever_live (LR_REGNO, true);
18753 /* Determine if we need to allocate any stack frame:
18755 For AIX we need to push the stack if a frame pointer is needed
18756 (because the stack might be dynamically adjusted), if we are
18757 debugging, if we make calls, or if the sum of fp_save, gp_save,
18758 and local variables are more than the space needed to save all
18759 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18760 + 18*8 = 288 (GPR13 reserved).
18762 For V.4 we don't have the stack cushion that AIX uses, but assume
18763 that the debugger can handle stackless frames. */
18765 if (info_ptr->calls_p)
18766 info_ptr->push_p = 1;
18768 else if (DEFAULT_ABI == ABI_V4)
18769 info_ptr->push_p = non_fixed_size != 0;
18771 else if (frame_pointer_needed)
18772 info_ptr->push_p = 1;
18774 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18775 info_ptr->push_p = 1;
18778 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18780 /* Zero offsets if we're not saving those registers. */
18781 if (info_ptr->fp_size == 0)
18782 info_ptr->fp_save_offset = 0;
18784 if (info_ptr->gp_size == 0)
18785 info_ptr->gp_save_offset = 0;
18787 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18788 info_ptr->altivec_save_offset = 0;
18790 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18791 info_ptr->vrsave_save_offset = 0;
18793 if (! TARGET_SPE_ABI
18794 || info_ptr->spe_64bit_regs_used == 0
18795 || info_ptr->spe_gp_size == 0)
18796 info_ptr->spe_gp_save_offset = 0;
18798 if (! info_ptr->lr_save_p)
18799 info_ptr->lr_save_offset = 0;
18801 if (! info_ptr->cr_save_p)
18802 info_ptr->cr_save_offset = 0;
18807 /* Return true if the current function uses any GPRs in 64-bit SIMD
18811 spe_func_has_64bit_regs_p (void)
18815 /* Functions that save and restore all the call-saved registers will
18816 need to save/restore the registers in 64-bits. */
18817 if (crtl->calls_eh_return
18818 || cfun->calls_setjmp
18819 || crtl->has_nonlocal_goto)
18822 insns = get_insns ();
18824 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18830 /* FIXME: This should be implemented with attributes...
18832 (set_attr "spe64" "true")....then,
18833 if (get_spe64(insn)) return true;
18835 It's the only reliable way to do the stuff below. */
18837 i = PATTERN (insn);
18838 if (GET_CODE (i) == SET)
18840 enum machine_mode mode = GET_MODE (SET_SRC (i));
18842 if (SPE_VECTOR_MODE (mode))
18844 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18854 debug_stack_info (rs6000_stack_t *info)
18856 const char *abi_string;
18859 info = rs6000_stack_info ();
18861 fprintf (stderr, "\nStack information for function %s:\n",
18862 ((current_function_decl && DECL_NAME (current_function_decl))
18863 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18868 default: abi_string = "Unknown"; break;
18869 case ABI_NONE: abi_string = "NONE"; break;
18870 case ABI_AIX: abi_string = "AIX"; break;
18871 case ABI_DARWIN: abi_string = "Darwin"; break;
18872 case ABI_V4: abi_string = "V.4"; break;
18875 fprintf (stderr, "\tABI = %5s\n", abi_string);
18877 if (TARGET_ALTIVEC_ABI)
18878 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18880 if (TARGET_SPE_ABI)
18881 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18883 if (info->first_gp_reg_save != 32)
18884 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18886 if (info->first_fp_reg_save != 64)
18887 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18889 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18890 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18891 info->first_altivec_reg_save);
18893 if (info->lr_save_p)
18894 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18896 if (info->cr_save_p)
18897 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18899 if (info->vrsave_mask)
18900 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18903 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18906 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18908 if (info->gp_save_offset)
18909 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18911 if (info->fp_save_offset)
18912 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18914 if (info->altivec_save_offset)
18915 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18916 info->altivec_save_offset);
18918 if (info->spe_gp_save_offset)
18919 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18920 info->spe_gp_save_offset);
18922 if (info->vrsave_save_offset)
18923 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18924 info->vrsave_save_offset);
18926 if (info->lr_save_offset)
18927 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18929 if (info->cr_save_offset)
18930 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18932 if (info->varargs_save_offset)
18933 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18935 if (info->total_size)
18936 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18939 if (info->vars_size)
18940 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18943 if (info->parm_size)
18944 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18946 if (info->fixed_size)
18947 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18950 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18952 if (info->spe_gp_size)
18953 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18956 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18958 if (info->altivec_size)
18959 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18961 if (info->vrsave_size)
18962 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18964 if (info->altivec_padding_size)
18965 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18966 info->altivec_padding_size);
18968 if (info->spe_padding_size)
18969 fprintf (stderr, "\tspe_padding_size = %5d\n",
18970 info->spe_padding_size);
18973 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18975 if (info->save_size)
18976 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18978 if (info->reg_size != 4)
18979 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18981 fprintf (stderr, "\n");
18985 rs6000_return_addr (int count, rtx frame)
18987 /* Currently we don't optimize very well between prolog and body
18988 code and for PIC code the code can be actually quite bad, so
18989 don't try to be too clever here. */
18990 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18992 cfun->machine->ra_needs_full_frame = 1;
18999 plus_constant (copy_to_reg
19000 (gen_rtx_MEM (Pmode,
19001 memory_address (Pmode, frame))),
19002 RETURN_ADDRESS_OFFSET)));
19005 cfun->machine->ra_need_lr = 1;
19006 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19009 /* Say whether a function is a candidate for sibcall handling or not. */
19012 rs6000_function_ok_for_sibcall (tree decl, tree exp)
19017 fntype = TREE_TYPE (decl);
19019 fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
19021 /* We can't do it if the called function has more vector parameters
19022 than the current function; there's nowhere to put the VRsave code. */
19023 if (TARGET_ALTIVEC_ABI
19024 && TARGET_ALTIVEC_VRSAVE
19025 && !(decl && decl == current_function_decl))
19027 function_args_iterator args_iter;
19031 /* Functions with vector parameters are required to have a
19032 prototype, so the argument type info must be available
19034 FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
19035 if (TREE_CODE (type) == VECTOR_TYPE
19036 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
19039 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
19040 if (TREE_CODE (type) == VECTOR_TYPE
19041 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type)))
19048 /* Under the AIX ABI we can't allow calls to non-local functions,
19049 because the callee may have a different TOC pointer to the
19050 caller and there's no way to ensure we restore the TOC when we
19051 return. With the secure-plt SYSV ABI we can't make non-local
19052 calls when -fpic/PIC because the plt call stubs use r30. */
19053 if (DEFAULT_ABI == ABI_DARWIN
19054 || (DEFAULT_ABI == ABI_AIX
19056 && !DECL_EXTERNAL (decl)
19057 && (*targetm.binds_local_p) (decl))
19058 || (DEFAULT_ABI == ABI_V4
19059 && (!TARGET_SECURE_PLT
19062 && (*targetm.binds_local_p) (decl)))))
19064 tree attr_list = TYPE_ATTRIBUTES (fntype);
19066 if (!lookup_attribute ("longcall", attr_list)
19067 || lookup_attribute ("shortcall", attr_list))
19074 /* NULL if INSN insn is valid within a low-overhead loop.
19075 Otherwise return why doloop cannot be applied.
19076 PowerPC uses the COUNT register for branch on table instructions. */
19078 static const char *
19079 rs6000_invalid_within_doloop (const_rtx insn)
19082 return "Function call in the loop.";
19085 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19086 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19087 return "Computed branch in the loop.";
19093 rs6000_ra_ever_killed (void)
19099 if (cfun->is_thunk)
19102 if (cfun->machine->lr_save_state)
19103 return cfun->machine->lr_save_state - 1;
19105 /* regs_ever_live has LR marked as used if any sibcalls are present,
19106 but this should not force saving and restoring in the
19107 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19108 clobbers LR, so that is inappropriate. */
19110 /* Also, the prologue can generate a store into LR that
19111 doesn't really count, like this:
19114 bcl to set PIC register
19118 When we're called from the epilogue, we need to avoid counting
19119 this as a store. */
19121 push_topmost_sequence ();
19122 top = get_insns ();
19123 pop_topmost_sequence ();
19124 reg = gen_rtx_REG (Pmode, LR_REGNO);
19126 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19132 if (!SIBLING_CALL_P (insn))
19135 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19137 else if (set_of (reg, insn) != NULL_RTX
19138 && !prologue_epilogue_contains (insn))
19145 /* Emit instructions needed to load the TOC register.
19146 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19147 a constant pool; or for SVR4 -fpic. */
19150 rs6000_emit_load_toc_table (int fromprolog)
19153 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19155 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19158 rtx lab, tmp1, tmp2, got;
19160 lab = gen_label_rtx ();
19161 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19162 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19164 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19166 got = rs6000_got_sym ();
19167 tmp1 = tmp2 = dest;
19170 tmp1 = gen_reg_rtx (Pmode);
19171 tmp2 = gen_reg_rtx (Pmode);
19173 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19174 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19175 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19176 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19178 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19180 emit_insn (gen_load_toc_v4_pic_si ());
19181 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19183 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19186 rtx temp0 = (fromprolog
19187 ? gen_rtx_REG (Pmode, 0)
19188 : gen_reg_rtx (Pmode));
19194 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19195 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19197 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19198 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19200 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19201 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19202 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19208 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19209 lab = gen_label_rtx ();
19210 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19211 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19212 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19214 emit_insn (gen_addsi3 (dest, temp0, dest));
19216 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19218 /* This is for AIX code running in non-PIC ELF32. */
19221 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19222 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19224 emit_insn (gen_elf_high (dest, realsym));
19225 emit_insn (gen_elf_low (dest, dest, realsym));
19229 gcc_assert (DEFAULT_ABI == ABI_AIX);
19232 emit_insn (gen_load_toc_aix_si (dest));
19234 emit_insn (gen_load_toc_aix_di (dest));
19238 /* Emit instructions to restore the link register after determining where
19239 its value has been stored. */
19242 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19244 rs6000_stack_t *info = rs6000_stack_info ();
19247 operands[0] = source;
19248 operands[1] = scratch;
19250 if (info->lr_save_p)
19252 rtx frame_rtx = stack_pointer_rtx;
19253 HOST_WIDE_INT sp_offset = 0;
19256 if (frame_pointer_needed
19257 || cfun->calls_alloca
19258 || info->total_size > 32767)
19260 tmp = gen_frame_mem (Pmode, frame_rtx);
19261 emit_move_insn (operands[1], tmp);
19262 frame_rtx = operands[1];
19264 else if (info->push_p)
19265 sp_offset = info->total_size;
19267 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19268 tmp = gen_frame_mem (Pmode, tmp);
19269 emit_move_insn (tmp, operands[0]);
19272 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19274 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19275 state of lr_save_p so any change from here on would be a bug. In
19276 particular, stop rs6000_ra_ever_killed from considering the SET
19277 of lr we may have added just above. */
19278 cfun->machine->lr_save_state = info->lr_save_p + 1;
19281 static GTY(()) alias_set_type set = -1;
19284 get_TOC_alias_set (void)
19287 set = new_alias_set ();
19291 /* This returns nonzero if the current function uses the TOC. This is
19292 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19293 is generated by the ABI_V4 load_toc_* patterns. */
19300 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19303 rtx pat = PATTERN (insn);
19306 if (GET_CODE (pat) == PARALLEL)
19307 for (i = 0; i < XVECLEN (pat, 0); i++)
19309 rtx sub = XVECEXP (pat, 0, i);
19310 if (GET_CODE (sub) == USE)
19312 sub = XEXP (sub, 0);
19313 if (GET_CODE (sub) == UNSPEC
19314 && XINT (sub, 1) == UNSPEC_TOC)
19324 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19326 rtx tocrel, tocreg;
19328 if (TARGET_DEBUG_ADDR)
19330 if (GET_CODE (symbol) == SYMBOL_REF)
19331 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19335 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19336 GET_RTX_NAME (GET_CODE (symbol)));
19337 debug_rtx (symbol);
19341 if (!can_create_pseudo_p ())
19342 df_set_regs_ever_live (TOC_REGISTER, true);
19344 tocrel = gen_rtx_CONST (Pmode,
19345 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19347 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19348 if (TARGET_CMODEL != CMODEL_SMALL)
19350 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19351 if (largetoc_reg != NULL)
19353 emit_move_insn (largetoc_reg, hi);
19356 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19359 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19362 /* Issue assembly directives that create a reference to the given DWARF
19363 FRAME_TABLE_LABEL from the current function section. */
19365 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19367 fprintf (asm_out_file, "\t.ref %s\n",
19368 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19371 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19372 and the change to the stack pointer. */
19375 rs6000_emit_stack_tie (void)
19377 rtx mem = gen_frame_mem (BLKmode,
19378 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19380 emit_insn (gen_stack_tie (mem));
19383 /* Emit the correct code for allocating stack space, as insns.
19384 If COPY_REG, make sure a copy of the old frame is left there.
19385 The generated code may use hard register 0 as a temporary. */
19388 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19391 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19392 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19393 rtx todec = gen_int_mode (-size, Pmode);
19396 if (INTVAL (todec) != -size)
19398 warning (0, "stack frame too large");
19399 emit_insn (gen_trap ());
19403 if (crtl->limit_stack)
19405 if (REG_P (stack_limit_rtx)
19406 && REGNO (stack_limit_rtx) > 1
19407 && REGNO (stack_limit_rtx) <= 31)
19409 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19410 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19413 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19415 && DEFAULT_ABI == ABI_V4)
19417 rtx toload = gen_rtx_CONST (VOIDmode,
19418 gen_rtx_PLUS (Pmode,
19422 emit_insn (gen_elf_high (tmp_reg, toload));
19423 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19424 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19428 warning (0, "stack limit expression is not supported");
19432 emit_move_insn (copy_reg, stack_reg);
19436 /* Need a note here so that try_split doesn't get confused. */
19437 if (get_last_insn () == NULL_RTX)
19438 emit_note (NOTE_INSN_DELETED);
19439 insn = emit_move_insn (tmp_reg, todec);
19440 try_split (PATTERN (insn), insn, 0);
19444 insn = emit_insn (TARGET_32BIT
19445 ? gen_movsi_update_stack (stack_reg, stack_reg,
19447 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19448 todec, stack_reg));
19449 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19450 it now and set the alias set/attributes. The above gen_*_update
19451 calls will generate a PARALLEL with the MEM set being the first
19453 par = PATTERN (insn);
19454 gcc_assert (GET_CODE (par) == PARALLEL);
19455 set = XVECEXP (par, 0, 0);
19456 gcc_assert (GET_CODE (set) == SET);
19457 mem = SET_DEST (set);
19458 gcc_assert (MEM_P (mem));
19459 MEM_NOTRAP_P (mem) = 1;
19460 set_mem_alias_set (mem, get_frame_alias_set ());
19462 RTX_FRAME_RELATED_P (insn) = 1;
19463 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19464 gen_rtx_SET (VOIDmode, stack_reg,
19465 gen_rtx_PLUS (Pmode, stack_reg,
19466 GEN_INT (-size))));
19469 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19471 #if PROBE_INTERVAL > 32768
19472 #error Cannot use indexed addressing mode for stack probing
19475 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19476 inclusive. These are offsets from the current stack pointer. */
19479 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19481 /* See if we have a constant small number of probes to generate. If so,
19482 that's the easy case. */
19483 if (first + size <= 32768)
19487 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19488 it exceeds SIZE. If only one probe is needed, this will not
19489 generate any code. Then probe at FIRST + SIZE. */
19490 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19491 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19493 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19496 /* Otherwise, do the same as above, but in a loop. Note that we must be
19497 extra careful with variables wrapping around because we might be at
19498 the very top (or the very bottom) of the address space and we have
19499 to be able to handle this case properly; in particular, we use an
19500 equality test for the loop condition. */
19503 HOST_WIDE_INT rounded_size;
19504 rtx r12 = gen_rtx_REG (Pmode, 12);
19505 rtx r0 = gen_rtx_REG (Pmode, 0);
19507 /* Sanity check for the addressing mode we're going to use. */
19508 gcc_assert (first <= 32768);
19510 /* Step 1: round SIZE to the previous multiple of the interval. */
19512 rounded_size = size & -PROBE_INTERVAL;
19515 /* Step 2: compute initial and final value of the loop counter. */
19517 /* TEST_ADDR = SP + FIRST. */
19518 emit_insn (gen_rtx_SET (VOIDmode, r12,
19519 plus_constant (stack_pointer_rtx, -first)));
19521 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19522 if (rounded_size > 32768)
19524 emit_move_insn (r0, GEN_INT (-rounded_size));
19525 emit_insn (gen_rtx_SET (VOIDmode, r0,
19526 gen_rtx_PLUS (Pmode, r12, r0)));
19529 emit_insn (gen_rtx_SET (VOIDmode, r0,
19530 plus_constant (r12, -rounded_size)));
19533 /* Step 3: the loop
19535 while (TEST_ADDR != LAST_ADDR)
19537 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19541 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19542 until it is equal to ROUNDED_SIZE. */
19545 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19547 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19550 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19551 that SIZE is equal to ROUNDED_SIZE. */
19553 if (size != rounded_size)
19554 emit_stack_probe (plus_constant (r12, rounded_size - size));
19558 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19559 absolute addresses. */
19562 output_probe_stack_range (rtx reg1, rtx reg2)
19564 static int labelno = 0;
19565 char loop_lab[32], end_lab[32];
19568 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19569 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19571 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19573 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19577 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19579 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19581 fputs ("\tbeq 0,", asm_out_file);
19582 assemble_name_raw (asm_out_file, end_lab);
19583 fputc ('\n', asm_out_file);
19585 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19586 xops[1] = GEN_INT (-PROBE_INTERVAL);
19587 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19589 /* Probe at TEST_ADDR and branch. */
19590 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19591 fprintf (asm_out_file, "\tb ");
19592 assemble_name_raw (asm_out_file, loop_lab);
19593 fputc ('\n', asm_out_file);
19595 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19600 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19601 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19602 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19603 deduce these equivalences by itself so it wasn't necessary to hold
19604 its hand so much. */
19607 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19608 rtx reg2, rtx rreg)
19612 /* copy_rtx will not make unique copies of registers, so we need to
19613 ensure we don't have unwanted sharing here. */
19615 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19618 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19620 real = copy_rtx (PATTERN (insn));
19622 if (reg2 != NULL_RTX)
19623 real = replace_rtx (real, reg2, rreg);
19625 real = replace_rtx (real, reg,
19626 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19627 STACK_POINTER_REGNUM),
19630 /* We expect that 'real' is either a SET or a PARALLEL containing
19631 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19632 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19634 if (GET_CODE (real) == SET)
19638 temp = simplify_rtx (SET_SRC (set));
19640 SET_SRC (set) = temp;
19641 temp = simplify_rtx (SET_DEST (set));
19643 SET_DEST (set) = temp;
19644 if (GET_CODE (SET_DEST (set)) == MEM)
19646 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19648 XEXP (SET_DEST (set), 0) = temp;
19655 gcc_assert (GET_CODE (real) == PARALLEL);
19656 for (i = 0; i < XVECLEN (real, 0); i++)
19657 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19659 rtx set = XVECEXP (real, 0, i);
19661 temp = simplify_rtx (SET_SRC (set));
19663 SET_SRC (set) = temp;
19664 temp = simplify_rtx (SET_DEST (set));
19666 SET_DEST (set) = temp;
19667 if (GET_CODE (SET_DEST (set)) == MEM)
19669 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19671 XEXP (SET_DEST (set), 0) = temp;
19673 RTX_FRAME_RELATED_P (set) = 1;
19677 RTX_FRAME_RELATED_P (insn) = 1;
19678 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19681 /* Returns an insn that has a vrsave set operation with the
19682 appropriate CLOBBERs. */
19685 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19688 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19689 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19692 = gen_rtx_SET (VOIDmode,
19694 gen_rtx_UNSPEC_VOLATILE (SImode,
19695 gen_rtvec (2, reg, vrsave),
19696 UNSPECV_SET_VRSAVE));
19700 /* We need to clobber the registers in the mask so the scheduler
19701 does not move sets to VRSAVE before sets of AltiVec registers.
19703 However, if the function receives nonlocal gotos, reload will set
19704 all call saved registers live. We will end up with:
19706 (set (reg 999) (mem))
19707 (parallel [ (set (reg vrsave) (unspec blah))
19708 (clobber (reg 999))])
19710 The clobber will cause the store into reg 999 to be dead, and
19711 flow will attempt to delete an epilogue insn. In this case, we
19712 need an unspec use/set of the register. */
19714 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19715 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19717 if (!epiloguep || call_used_regs [i])
19718 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19719 gen_rtx_REG (V4SImode, i));
19722 rtx reg = gen_rtx_REG (V4SImode, i);
19725 = gen_rtx_SET (VOIDmode,
19727 gen_rtx_UNSPEC (V4SImode,
19728 gen_rtvec (1, reg), 27));
19732 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19734 for (i = 0; i < nclobs; ++i)
19735 XVECEXP (insn, 0, i) = clobs[i];
19740 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19741 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19744 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19745 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19747 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19748 rtx replacea, replaceb;
19750 int_rtx = GEN_INT (offset);
19752 /* Some cases that need register indexed addressing. */
19753 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19754 || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
19755 || (TARGET_E500_DOUBLE && mode == DFmode)
19757 && SPE_VECTOR_MODE (mode)
19758 && !SPE_CONST_OFFSET_OK (offset)))
19760 /* Whomever calls us must make sure r11 is available in the
19761 flow path of instructions in the prologue. */
19762 offset_rtx = gen_rtx_REG (Pmode, 11);
19763 emit_move_insn (offset_rtx, int_rtx);
19765 replacea = offset_rtx;
19766 replaceb = int_rtx;
19770 offset_rtx = int_rtx;
19771 replacea = NULL_RTX;
19772 replaceb = NULL_RTX;
19775 reg = gen_rtx_REG (mode, regno);
19776 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19777 mem = gen_frame_mem (mode, addr);
19779 insn = emit_move_insn (mem, reg);
19781 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19784 /* Emit an offset memory reference suitable for a frame store, while
19785 converting to a valid addressing mode. */
19788 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19790 rtx int_rtx, offset_rtx;
19792 int_rtx = GEN_INT (offset);
19794 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19795 || (TARGET_E500_DOUBLE && mode == DFmode))
19797 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19798 emit_move_insn (offset_rtx, int_rtx);
19801 offset_rtx = int_rtx;
19803 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19806 /* Look for user-defined global regs. We should not save and restore these,
19807 and cannot use stmw/lmw if there are any in its range. */
19810 no_global_regs_above (int first, bool gpr)
19813 int last = gpr ? 32 : 64;
19814 for (i = first; i < last; i++)
19815 if (global_regs[i])
19820 #ifndef TARGET_FIX_AND_CONTINUE
19821 #define TARGET_FIX_AND_CONTINUE 0
19824 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19825 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19826 #define LAST_SAVRES_REGISTER 31
19827 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19829 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19831 /* Temporary holding space for an out-of-line register save/restore
19833 static char savres_routine_name[30];
19835 /* Return the name for an out-of-line register save/restore routine.
19836 We are saving/restoring GPRs if GPR is true. */
19839 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19840 bool savep, bool gpr, bool lr)
19842 const char *prefix = "";
19843 const char *suffix = "";
19845 /* Different targets are supposed to define
19846 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19847 routine name could be defined with:
19849 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19851 This is a nice idea in practice, but in reality, things are
19852 complicated in several ways:
19854 - ELF targets have save/restore routines for GPRs.
19856 - SPE targets use different prefixes for 32/64-bit registers, and
19857 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19859 - PPC64 ELF targets have routines for save/restore of GPRs that
19860 differ in what they do with the link register, so having a set
19861 prefix doesn't work. (We only use one of the save routines at
19862 the moment, though.)
19864 - PPC32 elf targets have "exit" versions of the restore routines
19865 that restore the link register and can save some extra space.
19866 These require an extra suffix. (There are also "tail" versions
19867 of the restore routines and "GOT" versions of the save routines,
19868 but we don't generate those at present. Same problems apply,
19871 We deal with all this by synthesizing our own prefix/suffix and
19872 using that for the simple sprintf call shown above. */
19875 /* No floating point saves on the SPE. */
19879 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19881 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19886 else if (DEFAULT_ABI == ABI_V4)
19892 prefix = savep ? "_savegpr_" : "_restgpr_";
19894 prefix = savep ? "_savefpr_" : "_restfpr_";
19899 else if (DEFAULT_ABI == ABI_AIX)
19901 #ifndef POWERPC_LINUX
19902 /* No out-of-line save/restore routines for GPRs on AIX. */
19903 gcc_assert (!TARGET_AIX || !gpr);
19909 ? (lr ? "_savegpr0_" : "_savegpr1_")
19910 : (lr ? "_restgpr0_" : "_restgpr1_"));
19911 #ifdef POWERPC_LINUX
19913 prefix = (savep ? "_savefpr_" : "_restfpr_");
19917 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19918 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19921 else if (DEFAULT_ABI == ABI_DARWIN)
19922 sorry ("out-of-line save/restore routines not supported on Darwin");
19924 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19926 return savres_routine_name;
19929 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19930 We are saving/restoring GPRs if GPR is true. */
19933 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19936 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19938 int select = ((savep ? 1 : 0) << 2
19940 /* On the SPE, we never have any FPRs, but we do have
19941 32/64-bit versions of the routines. */
19942 ? (info->spe_64bit_regs_used ? 1 : 0)
19943 : (gpr ? 1 : 0)) << 1)
19946 /* Don't generate bogus routine names. */
19947 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19948 && regno <= LAST_SAVRES_REGISTER);
19950 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19956 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19958 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19959 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19960 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19966 /* Emit a sequence of insns, including a stack tie if needed, for
19967 resetting the stack pointer. If SAVRES is true, then don't reset the
19968 stack pointer, but move the base of the frame into r11 for use by
19969 out-of-line register restore routines. */
19972 rs6000_emit_stack_reset (rs6000_stack_t *info,
19973 rtx sp_reg_rtx, rtx frame_reg_rtx,
19974 int sp_offset, bool savres)
19976 /* This blockage is needed so that sched doesn't decide to move
19977 the sp change before the register restores. */
19978 if (frame_reg_rtx != sp_reg_rtx
19980 && info->spe_64bit_regs_used != 0
19981 && info->first_gp_reg_save != 32))
19982 rs6000_emit_stack_tie ();
19984 if (frame_reg_rtx != sp_reg_rtx)
19986 if (sp_offset != 0)
19988 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19989 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19990 GEN_INT (sp_offset)));
19993 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19995 else if (sp_offset != 0)
19997 /* If we are restoring registers out-of-line, we will be using the
19998 "exit" variants of the restore routines, which will reset the
19999 stack for us. But we do need to point r11 into the right place
20000 for those routines. */
20001 rtx dest_reg = (savres
20002 ? gen_rtx_REG (Pmode, 11)
20005 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20006 GEN_INT (sp_offset)));
20013 /* Construct a parallel rtx describing the effect of a call to an
20014 out-of-line register save/restore routine. */
20017 rs6000_make_savres_rtx (rs6000_stack_t *info,
20018 rtx frame_reg_rtx, int save_area_offset,
20019 enum machine_mode reg_mode,
20020 bool savep, bool gpr, bool lr)
20023 int offset, start_reg, end_reg, n_regs;
20024 int reg_size = GET_MODE_SIZE (reg_mode);
20030 ? info->first_gp_reg_save
20031 : info->first_fp_reg_save);
20032 end_reg = gpr ? 32 : 64;
20033 n_regs = end_reg - start_reg;
20034 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20037 RTVEC_ELT (p, offset++) = ret_rtx;
20039 RTVEC_ELT (p, offset++)
20040 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20042 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20043 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20044 RTVEC_ELT (p, offset++)
20045 = gen_rtx_USE (VOIDmode,
20046 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20050 for (i = 0; i < end_reg - start_reg; i++)
20052 rtx addr, reg, mem;
20053 reg = gen_rtx_REG (reg_mode, start_reg + i);
20054 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20055 GEN_INT (save_area_offset + reg_size*i));
20056 mem = gen_frame_mem (reg_mode, addr);
20058 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20060 savep ? reg : mem);
20065 rtx addr, reg, mem;
20066 reg = gen_rtx_REG (Pmode, 0);
20067 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20068 GEN_INT (info->lr_save_offset));
20069 mem = gen_frame_mem (Pmode, addr);
20070 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20073 return gen_rtx_PARALLEL (VOIDmode, p);
20076 /* Determine whether the gp REG is really used. */
20079 rs6000_reg_live_or_pic_offset_p (int reg)
20081 /* If the function calls eh_return, claim used all the registers that would
20082 be checked for liveness otherwise. This is required for the PIC offset
20083 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20084 register allocation purposes in this case. */
20086 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20087 && (!call_used_regs[reg]
20088 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20089 && !TARGET_SINGLE_PIC_BASE
20090 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20091 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20092 && !TARGET_SINGLE_PIC_BASE
20093 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20094 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20097 /* Emit function prologue as insns. */
20100 rs6000_emit_prologue (void)
20102 rs6000_stack_t *info = rs6000_stack_info ();
20103 enum machine_mode reg_mode = Pmode;
20104 int reg_size = TARGET_32BIT ? 4 : 8;
20105 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20106 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20107 rtx frame_reg_rtx = sp_reg_rtx;
20108 rtx cr_save_rtx = NULL_RTX;
20111 int saving_FPRs_inline;
20112 int saving_GPRs_inline;
20113 int using_store_multiple;
20114 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20115 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20116 && call_used_regs[STATIC_CHAIN_REGNUM]);
20117 HOST_WIDE_INT sp_offset = 0;
20119 if (flag_stack_usage)
20120 current_function_static_stack_size = info->total_size;
20122 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20123 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20125 if (TARGET_FIX_AND_CONTINUE)
20127 /* gdb on darwin arranges to forward a function from the old
20128 address by modifying the first 5 instructions of the function
20129 to branch to the overriding function. This is necessary to
20130 permit function pointers that point to the old function to
20131 actually forward to the new function. */
20132 emit_insn (gen_nop ());
20133 emit_insn (gen_nop ());
20134 emit_insn (gen_nop ());
20135 emit_insn (gen_nop ());
20136 emit_insn (gen_nop ());
20139 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20141 reg_mode = V2SImode;
20145 strategy = info->savres_strategy;
20146 using_store_multiple = strategy & SAVRES_MULTIPLE;
20147 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20148 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20150 /* For V.4, update stack before we do any saving and set back pointer. */
20151 if (! WORLD_SAVE_P (info)
20153 && (DEFAULT_ABI == ABI_V4
20154 || crtl->calls_eh_return))
20156 bool need_r11 = (TARGET_SPE
20157 ? (!saving_GPRs_inline
20158 && info->spe_64bit_regs_used == 0)
20159 : (!saving_FPRs_inline || !saving_GPRs_inline));
20160 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20162 if (info->total_size < 32767)
20163 sp_offset = info->total_size;
20165 frame_reg_rtx = copy_reg;
20166 else if (info->cr_save_p
20168 || info->first_fp_reg_save < 64
20169 || info->first_gp_reg_save < 32
20170 || info->altivec_size != 0
20171 || info->vrsave_mask != 0
20172 || crtl->calls_eh_return)
20174 copy_reg = frame_ptr_rtx;
20175 frame_reg_rtx = copy_reg;
20179 /* The prologue won't be saving any regs so there is no need
20180 to set up a frame register to access any frame save area.
20181 We also won't be using sp_offset anywhere below, but set
20182 the correct value anyway to protect against future
20183 changes to this function. */
20184 sp_offset = info->total_size;
20186 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20187 if (frame_reg_rtx != sp_reg_rtx)
20188 rs6000_emit_stack_tie ();
20191 /* Handle world saves specially here. */
20192 if (WORLD_SAVE_P (info))
20199 /* save_world expects lr in r0. */
20200 reg0 = gen_rtx_REG (Pmode, 0);
20201 if (info->lr_save_p)
20203 insn = emit_move_insn (reg0,
20204 gen_rtx_REG (Pmode, LR_REGNO));
20205 RTX_FRAME_RELATED_P (insn) = 1;
20208 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20209 assumptions about the offsets of various bits of the stack
20211 gcc_assert (info->gp_save_offset == -220
20212 && info->fp_save_offset == -144
20213 && info->lr_save_offset == 8
20214 && info->cr_save_offset == 4
20217 && (!crtl->calls_eh_return
20218 || info->ehrd_offset == -432)
20219 && info->vrsave_save_offset == -224
20220 && info->altivec_save_offset == -416);
20222 treg = gen_rtx_REG (SImode, 11);
20223 emit_move_insn (treg, GEN_INT (-info->total_size));
20225 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20226 in R11. It also clobbers R12, so beware! */
20228 /* Preserve CR2 for save_world prologues */
20230 sz += 32 - info->first_gp_reg_save;
20231 sz += 64 - info->first_fp_reg_save;
20232 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20233 p = rtvec_alloc (sz);
20235 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20236 gen_rtx_REG (SImode,
20238 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20239 gen_rtx_SYMBOL_REF (Pmode,
20241 /* We do floats first so that the instruction pattern matches
20243 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20245 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20246 ? DFmode : SFmode),
20247 info->first_fp_reg_save + i);
20248 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20249 GEN_INT (info->fp_save_offset
20250 + sp_offset + 8 * i));
20251 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20252 ? DFmode : SFmode), addr);
20254 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20256 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20258 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20259 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20260 GEN_INT (info->altivec_save_offset
20261 + sp_offset + 16 * i));
20262 rtx mem = gen_frame_mem (V4SImode, addr);
20264 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20266 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20268 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20269 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20270 GEN_INT (info->gp_save_offset
20271 + sp_offset + reg_size * i));
20272 rtx mem = gen_frame_mem (reg_mode, addr);
20274 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20278 /* CR register traditionally saved as CR2. */
20279 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20280 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20281 GEN_INT (info->cr_save_offset
20283 rtx mem = gen_frame_mem (reg_mode, addr);
20285 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20287 /* Explain about use of R0. */
20288 if (info->lr_save_p)
20290 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20291 GEN_INT (info->lr_save_offset
20293 rtx mem = gen_frame_mem (reg_mode, addr);
20295 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20297 /* Explain what happens to the stack pointer. */
20299 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20300 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20303 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20304 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20305 treg, GEN_INT (-info->total_size));
20306 sp_offset = info->total_size;
20309 /* If we use the link register, get it into r0. */
20310 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20312 rtx addr, reg, mem;
20314 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20315 gen_rtx_REG (Pmode, LR_REGNO));
20316 RTX_FRAME_RELATED_P (insn) = 1;
20318 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20319 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20321 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20322 GEN_INT (info->lr_save_offset + sp_offset));
20323 reg = gen_rtx_REG (Pmode, 0);
20324 mem = gen_rtx_MEM (Pmode, addr);
20325 /* This should not be of rs6000_sr_alias_set, because of
20326 __builtin_return_address. */
20328 insn = emit_move_insn (mem, reg);
20329 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20330 NULL_RTX, NULL_RTX);
20334 /* If we need to save CR, put it into r12 or r11. */
20335 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20340 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20342 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20343 RTX_FRAME_RELATED_P (insn) = 1;
20344 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20345 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20346 But that's OK. All we have to do is specify that _one_ condition
20347 code register is saved in this stack slot. The thrower's epilogue
20348 will then restore all the call-saved registers.
20349 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20350 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20351 gen_rtx_REG (SImode, CR2_REGNO));
20352 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20355 /* Do any required saving of fpr's. If only one or two to save, do
20356 it ourselves. Otherwise, call function. */
20357 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20360 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20361 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20362 && ! call_used_regs[info->first_fp_reg_save+i]))
20363 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20364 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20366 info->first_fp_reg_save + i,
20367 info->fp_save_offset + sp_offset + 8 * i,
20370 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20374 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20375 info->fp_save_offset + sp_offset,
20377 /*savep=*/true, /*gpr=*/false,
20379 & SAVE_NOINLINE_FPRS_SAVES_LR)
20381 insn = emit_insn (par);
20382 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20383 NULL_RTX, NULL_RTX);
20386 /* Save GPRs. This is done as a PARALLEL if we are using
20387 the store-multiple instructions. */
20388 if (!WORLD_SAVE_P (info)
20390 && info->spe_64bit_regs_used != 0
20391 && info->first_gp_reg_save != 32)
20394 rtx spe_save_area_ptr;
20396 /* Determine whether we can address all of the registers that need
20397 to be saved with an offset from the stack pointer that fits in
20398 the small const field for SPE memory instructions. */
20399 int spe_regs_addressable_via_sp
20400 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20401 + (32 - info->first_gp_reg_save - 1) * reg_size)
20402 && saving_GPRs_inline);
20405 if (spe_regs_addressable_via_sp)
20407 spe_save_area_ptr = frame_reg_rtx;
20408 spe_offset = info->spe_gp_save_offset + sp_offset;
20412 /* Make r11 point to the start of the SPE save area. We need
20413 to be careful here if r11 is holding the static chain. If
20414 it is, then temporarily save it in r0. We would use r0 as
20415 our base register here, but using r0 as a base register in
20416 loads and stores means something different from what we
20418 int ool_adjust = (saving_GPRs_inline
20420 : (info->first_gp_reg_save
20421 - (FIRST_SAVRES_REGISTER+1))*8);
20422 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20423 + sp_offset - ool_adjust);
20425 if (using_static_chain_p)
20427 rtx r0 = gen_rtx_REG (Pmode, 0);
20428 gcc_assert (info->first_gp_reg_save > 11);
20430 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20433 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20434 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20436 GEN_INT (offset)));
20437 /* We need to make sure the move to r11 gets noted for
20438 properly outputting unwind information. */
20439 if (!saving_GPRs_inline)
20440 rs6000_frame_related (insn, frame_reg_rtx, offset,
20441 NULL_RTX, NULL_RTX);
20445 if (saving_GPRs_inline)
20447 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20448 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20450 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20451 rtx offset, addr, mem;
20453 /* We're doing all this to ensure that the offset fits into
20454 the immediate offset of 'evstdd'. */
20455 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20457 offset = GEN_INT (reg_size * i + spe_offset);
20458 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20459 mem = gen_rtx_MEM (V2SImode, addr);
20461 insn = emit_move_insn (mem, reg);
20463 rs6000_frame_related (insn, spe_save_area_ptr,
20464 info->spe_gp_save_offset
20465 + sp_offset + reg_size * i,
20466 offset, const0_rtx);
20473 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20475 /*savep=*/true, /*gpr=*/true,
20477 insn = emit_insn (par);
20478 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20479 NULL_RTX, NULL_RTX);
20483 /* Move the static chain pointer back. */
20484 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20485 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20487 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20491 /* Need to adjust r11 (r12) if we saved any FPRs. */
20492 if (info->first_fp_reg_save != 64)
20494 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20496 rtx offset = GEN_INT (sp_offset
20497 + (-8 * (64-info->first_fp_reg_save)));
20498 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20501 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20502 info->gp_save_offset + sp_offset,
20504 /*savep=*/true, /*gpr=*/true,
20506 & SAVE_NOINLINE_GPRS_SAVES_LR)
20508 insn = emit_insn (par);
20509 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20510 NULL_RTX, NULL_RTX);
20512 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20516 p = rtvec_alloc (32 - info->first_gp_reg_save);
20517 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20519 rtx addr, reg, mem;
20520 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20521 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20522 GEN_INT (info->gp_save_offset
20525 mem = gen_frame_mem (reg_mode, addr);
20527 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20529 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20530 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20531 NULL_RTX, NULL_RTX);
20533 else if (!WORLD_SAVE_P (info))
20536 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20537 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20539 rtx addr, reg, mem;
20540 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20542 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20543 GEN_INT (info->gp_save_offset
20546 mem = gen_frame_mem (reg_mode, addr);
20548 insn = emit_move_insn (mem, reg);
20549 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20550 NULL_RTX, NULL_RTX);
20554 /* ??? There's no need to emit actual instructions here, but it's the
20555 easiest way to get the frame unwind information emitted. */
20556 if (crtl->calls_eh_return)
20558 unsigned int i, regno;
20562 regno = EH_RETURN_DATA_REGNO (i);
20563 if (regno == INVALID_REGNUM)
20566 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20567 info->ehrd_offset + sp_offset
20568 + reg_size * (int) i,
20573 /* In AIX ABI we need to make sure r2 is really saved. */
20574 if (TARGET_AIX && crtl->calls_eh_return)
20576 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20577 long toc_restore_insn;
20579 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20580 || frame_reg_rtx == sp_reg_rtx);
20581 tmp_reg = gen_rtx_REG (Pmode, 11);
20582 tmp_reg_si = gen_rtx_REG (SImode, 11);
20583 if (using_static_chain_p)
20584 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20585 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20586 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20587 /* Peek at instruction to which this function returns. If it's
20588 restoring r2, then we know we've already saved r2. We can't
20589 unconditionally save r2 because the value we have will already
20590 be updated if we arrived at this function via a plt call or
20591 toc adjusting stub. */
20592 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20593 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20594 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20595 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20596 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20597 validate_condition_mode (EQ, CCUNSmode);
20598 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20599 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20600 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20601 toc_save_done = gen_label_rtx ();
20602 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20603 gen_rtx_EQ (VOIDmode, compare_result,
20605 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20607 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20608 JUMP_LABEL (jump) = toc_save_done;
20609 LABEL_NUSES (toc_save_done) += 1;
20611 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20612 sp_offset + 5 * reg_size, info->total_size);
20613 emit_label (toc_save_done);
20614 if (using_static_chain_p)
20615 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20618 /* Save CR if we use any that must be preserved. */
20619 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20621 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20622 GEN_INT (info->cr_save_offset + sp_offset));
20623 rtx mem = gen_frame_mem (SImode, addr);
20624 /* See the large comment above about why CR2_REGNO is used. */
20625 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20627 /* If r12 was used to hold the original sp, copy cr into r0 now
20629 if (REGNO (frame_reg_rtx) == 12)
20633 cr_save_rtx = gen_rtx_REG (SImode, 0);
20634 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20635 RTX_FRAME_RELATED_P (insn) = 1;
20636 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20637 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20639 insn = emit_move_insn (mem, cr_save_rtx);
20641 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20642 NULL_RTX, NULL_RTX);
20645 /* Update stack and set back pointer unless this is V.4,
20646 for which it was done previously. */
20647 if (!WORLD_SAVE_P (info) && info->push_p
20648 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20650 rtx copy_reg = NULL;
20652 if (info->total_size < 32767)
20653 sp_offset = info->total_size;
20654 else if (info->altivec_size != 0
20655 || info->vrsave_mask != 0)
20657 copy_reg = frame_ptr_rtx;
20658 frame_reg_rtx = copy_reg;
20661 sp_offset = info->total_size;
20662 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20663 if (frame_reg_rtx != sp_reg_rtx)
20664 rs6000_emit_stack_tie ();
20667 /* Set frame pointer, if needed. */
20668 if (frame_pointer_needed)
20670 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20672 RTX_FRAME_RELATED_P (insn) = 1;
20675 /* Save AltiVec registers if needed. Save here because the red zone does
20676 not include AltiVec registers. */
20677 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20681 /* There should be a non inline version of this, for when we
20682 are saving lots of vector registers. */
20683 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20684 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20686 rtx areg, savereg, mem;
20689 offset = info->altivec_save_offset + sp_offset
20690 + 16 * (i - info->first_altivec_reg_save);
20692 savereg = gen_rtx_REG (V4SImode, i);
20694 areg = gen_rtx_REG (Pmode, 0);
20695 emit_move_insn (areg, GEN_INT (offset));
20697 /* AltiVec addressing mode is [reg+reg]. */
20698 mem = gen_frame_mem (V4SImode,
20699 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20701 insn = emit_move_insn (mem, savereg);
20703 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20704 areg, GEN_INT (offset));
20708 /* VRSAVE is a bit vector representing which AltiVec registers
20709 are used. The OS uses this to determine which vector
20710 registers to save on a context switch. We need to save
20711 VRSAVE on the stack frame, add whatever AltiVec registers we
20712 used in this function, and do the corresponding magic in the
20715 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20716 && info->vrsave_mask != 0)
20718 rtx reg, mem, vrsave;
20721 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20722 as frame_reg_rtx and r11 as the static chain pointer for
20723 nested functions. */
20724 reg = gen_rtx_REG (SImode, 0);
20725 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20727 emit_insn (gen_get_vrsave_internal (reg));
20729 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20731 if (!WORLD_SAVE_P (info))
20734 offset = info->vrsave_save_offset + sp_offset;
20735 mem = gen_frame_mem (SImode,
20736 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20737 GEN_INT (offset)));
20738 insn = emit_move_insn (mem, reg);
20741 /* Include the registers in the mask. */
20742 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20744 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20747 if (TARGET_SINGLE_PIC_BASE)
20748 return; /* Do not set PIC register */
20750 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20751 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20752 || (DEFAULT_ABI == ABI_V4
20753 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20754 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20756 /* If emit_load_toc_table will use the link register, we need to save
20757 it. We use R12 for this purpose because emit_load_toc_table
20758 can use register 0. This allows us to use a plain 'blr' to return
20759 from the procedure more often. */
20760 int save_LR_around_toc_setup = (TARGET_ELF
20761 && DEFAULT_ABI != ABI_AIX
20763 && ! info->lr_save_p
20764 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20765 if (save_LR_around_toc_setup)
20767 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20769 insn = emit_move_insn (frame_ptr_rtx, lr);
20770 RTX_FRAME_RELATED_P (insn) = 1;
20772 rs6000_emit_load_toc_table (TRUE);
20774 insn = emit_move_insn (lr, frame_ptr_rtx);
20775 RTX_FRAME_RELATED_P (insn) = 1;
20778 rs6000_emit_load_toc_table (TRUE);
20782 if (DEFAULT_ABI == ABI_DARWIN
20783 && flag_pic && crtl->uses_pic_offset_table)
20785 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20786 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20788 /* Save and restore LR locally around this call (in R0). */
20789 if (!info->lr_save_p)
20790 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20792 emit_insn (gen_load_macho_picbase (src));
20794 emit_move_insn (gen_rtx_REG (Pmode,
20795 RS6000_PIC_OFFSET_TABLE_REGNUM),
20798 if (!info->lr_save_p)
20799 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20804 /* Write function prologue. */
20807 rs6000_output_function_prologue (FILE *file,
20808 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20810 rs6000_stack_t *info = rs6000_stack_info ();
20812 if (TARGET_DEBUG_STACK)
20813 debug_stack_info (info);
20815 /* Write .extern for any function we will call to save and restore
20817 if (info->first_fp_reg_save < 64)
20820 int regno = info->first_fp_reg_save - 32;
20822 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20824 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20825 /*gpr=*/false, /*lr=*/false);
20826 fprintf (file, "\t.extern %s\n", name);
20828 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20830 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20831 /*gpr=*/false, /*lr=*/true);
20832 fprintf (file, "\t.extern %s\n", name);
20836 /* Write .extern for AIX common mode routines, if needed. */
20837 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20839 fputs ("\t.extern __mulh\n", file);
20840 fputs ("\t.extern __mull\n", file);
20841 fputs ("\t.extern __divss\n", file);
20842 fputs ("\t.extern __divus\n", file);
20843 fputs ("\t.extern __quoss\n", file);
20844 fputs ("\t.extern __quous\n", file);
20845 common_mode_defined = 1;
20848 if (! HAVE_prologue)
20854 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20855 the "toplevel" insn chain. */
20856 emit_note (NOTE_INSN_DELETED);
20857 rs6000_emit_prologue ();
20858 emit_note (NOTE_INSN_DELETED);
20860 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20864 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20866 INSN_ADDRESSES_NEW (insn, addr);
20871 prologue = get_insns ();
20874 if (TARGET_DEBUG_STACK)
20875 debug_rtx_list (prologue, 100);
20877 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20881 rs6000_pic_labelno++;
20884 /* Non-zero if vmx regs are restored before the frame pop, zero if
20885 we restore after the pop when possible. */
20886 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20888 /* Reload CR from REG. */
20891 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20896 if (using_mfcr_multiple)
20898 for (i = 0; i < 8; i++)
20899 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20901 gcc_assert (count);
20904 if (using_mfcr_multiple && count > 1)
20909 p = rtvec_alloc (count);
20912 for (i = 0; i < 8; i++)
20913 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20915 rtvec r = rtvec_alloc (2);
20916 RTVEC_ELT (r, 0) = reg;
20917 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20918 RTVEC_ELT (p, ndx) =
20919 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20920 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20923 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20924 gcc_assert (ndx == count);
20927 for (i = 0; i < 8; i++)
20928 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20930 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20936 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20937 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20938 below stack pointer not cloberred by signals. */
20941 offset_below_red_zone_p (HOST_WIDE_INT offset)
20943 return offset < (DEFAULT_ABI == ABI_V4
20945 : TARGET_32BIT ? -220 : -288);
20948 /* Emit function epilogue as insns. */
20951 rs6000_emit_epilogue (int sibcall)
20953 rs6000_stack_t *info;
20954 int restoring_GPRs_inline;
20955 int restoring_FPRs_inline;
20956 int using_load_multiple;
20957 int using_mtcr_multiple;
20958 int use_backchain_to_restore_sp;
20962 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20963 rtx frame_reg_rtx = sp_reg_rtx;
20964 rtx cfa_restores = NULL_RTX;
20966 rtx cr_save_reg = NULL_RTX;
20967 enum machine_mode reg_mode = Pmode;
20968 int reg_size = TARGET_32BIT ? 4 : 8;
20971 info = rs6000_stack_info ();
20973 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20975 reg_mode = V2SImode;
20979 strategy = info->savres_strategy;
20980 using_load_multiple = strategy & SAVRES_MULTIPLE;
20981 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20982 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20983 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20984 || rs6000_cpu == PROCESSOR_PPC603
20985 || rs6000_cpu == PROCESSOR_PPC750
20987 /* Restore via the backchain when we have a large frame, since this
20988 is more efficient than an addis, addi pair. The second condition
20989 here will not trigger at the moment; We don't actually need a
20990 frame pointer for alloca, but the generic parts of the compiler
20991 give us one anyway. */
20992 use_backchain_to_restore_sp = (info->total_size > 32767
20993 || info->total_size
20994 + (info->lr_save_p ? info->lr_save_offset : 0)
20996 || (cfun->calls_alloca
20997 && !frame_pointer_needed));
20998 restore_lr = (info->lr_save_p
20999 && (restoring_FPRs_inline
21000 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21001 && (restoring_GPRs_inline
21002 || info->first_fp_reg_save < 64));
21004 if (WORLD_SAVE_P (info))
21008 const char *alloc_rname;
21011 /* eh_rest_world_r10 will return to the location saved in the LR
21012 stack slot (which is not likely to be our caller.)
21013 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21014 rest_world is similar, except any R10 parameter is ignored.
21015 The exception-handling stuff that was here in 2.95 is no
21016 longer necessary. */
21020 + 32 - info->first_gp_reg_save
21021 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21022 + 63 + 1 - info->first_fp_reg_save);
21024 strcpy (rname, ((crtl->calls_eh_return) ?
21025 "*eh_rest_world_r10" : "*rest_world"));
21026 alloc_rname = ggc_strdup (rname);
21029 RTVEC_ELT (p, j++) = ret_rtx;
21030 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21031 gen_rtx_REG (Pmode,
21034 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21035 /* The instruction pattern requires a clobber here;
21036 it is shared with the restVEC helper. */
21038 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21041 /* CR register traditionally saved as CR2. */
21042 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21043 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21044 GEN_INT (info->cr_save_offset));
21045 rtx mem = gen_frame_mem (reg_mode, addr);
21047 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21050 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21052 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21053 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21054 GEN_INT (info->gp_save_offset
21056 rtx mem = gen_frame_mem (reg_mode, addr);
21058 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21060 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21062 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21063 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21064 GEN_INT (info->altivec_save_offset
21066 rtx mem = gen_frame_mem (V4SImode, addr);
21068 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21070 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21072 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21073 ? DFmode : SFmode),
21074 info->first_fp_reg_save + i);
21075 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21076 GEN_INT (info->fp_save_offset
21078 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21079 ? DFmode : SFmode), addr);
21081 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21084 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21086 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21088 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21090 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21092 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21093 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21098 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21100 sp_offset = info->total_size;
21102 /* Restore AltiVec registers if we must do so before adjusting the
21104 if (TARGET_ALTIVEC_ABI
21105 && info->altivec_size != 0
21106 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21107 || (DEFAULT_ABI != ABI_V4
21108 && offset_below_red_zone_p (info->altivec_save_offset))))
21112 if (use_backchain_to_restore_sp)
21114 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21115 emit_move_insn (frame_reg_rtx,
21116 gen_rtx_MEM (Pmode, sp_reg_rtx));
21119 else if (frame_pointer_needed)
21120 frame_reg_rtx = hard_frame_pointer_rtx;
21122 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21123 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21125 rtx addr, areg, mem, reg;
21127 areg = gen_rtx_REG (Pmode, 0);
21129 (areg, GEN_INT (info->altivec_save_offset
21131 + 16 * (i - info->first_altivec_reg_save)));
21133 /* AltiVec addressing mode is [reg+reg]. */
21134 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21135 mem = gen_frame_mem (V4SImode, addr);
21137 reg = gen_rtx_REG (V4SImode, i);
21138 emit_move_insn (reg, mem);
21139 if (offset_below_red_zone_p (info->altivec_save_offset
21140 + (i - info->first_altivec_reg_save)
21142 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21147 /* Restore VRSAVE if we must do so before adjusting the stack. */
21149 && TARGET_ALTIVEC_VRSAVE
21150 && info->vrsave_mask != 0
21151 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21152 || (DEFAULT_ABI != ABI_V4
21153 && offset_below_red_zone_p (info->vrsave_save_offset))))
21155 rtx addr, mem, reg;
21157 if (frame_reg_rtx == sp_reg_rtx)
21159 if (use_backchain_to_restore_sp)
21161 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21162 emit_move_insn (frame_reg_rtx,
21163 gen_rtx_MEM (Pmode, sp_reg_rtx));
21166 else if (frame_pointer_needed)
21167 frame_reg_rtx = hard_frame_pointer_rtx;
21170 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21171 GEN_INT (info->vrsave_save_offset + sp_offset));
21172 mem = gen_frame_mem (SImode, addr);
21173 reg = gen_rtx_REG (SImode, 12);
21174 emit_move_insn (reg, mem);
21176 emit_insn (generate_set_vrsave (reg, info, 1));
21180 /* If we have a large stack frame, restore the old stack pointer
21181 using the backchain. */
21182 if (use_backchain_to_restore_sp)
21184 if (frame_reg_rtx == sp_reg_rtx)
21186 /* Under V.4, don't reset the stack pointer until after we're done
21187 loading the saved registers. */
21188 if (DEFAULT_ABI == ABI_V4)
21189 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21191 insn = emit_move_insn (frame_reg_rtx,
21192 gen_rtx_MEM (Pmode, sp_reg_rtx));
21195 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21196 && DEFAULT_ABI == ABI_V4)
21197 /* frame_reg_rtx has been set up by the altivec restore. */
21201 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21202 frame_reg_rtx = sp_reg_rtx;
21205 /* If we have a frame pointer, we can restore the old stack pointer
21207 else if (frame_pointer_needed)
21209 frame_reg_rtx = sp_reg_rtx;
21210 if (DEFAULT_ABI == ABI_V4)
21211 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21212 /* Prevent reordering memory accesses against stack pointer restore. */
21213 else if (cfun->calls_alloca
21214 || offset_below_red_zone_p (-info->total_size))
21216 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21217 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21218 MEM_NOTRAP_P (mem1) = 1;
21219 MEM_NOTRAP_P (mem2) = 1;
21220 emit_insn (gen_frame_tie (mem1, mem2));
21223 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21224 GEN_INT (info->total_size)));
21227 else if (info->push_p
21228 && DEFAULT_ABI != ABI_V4
21229 && !crtl->calls_eh_return)
21231 /* Prevent reordering memory accesses against stack pointer restore. */
21232 if (cfun->calls_alloca
21233 || offset_below_red_zone_p (-info->total_size))
21235 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21236 MEM_NOTRAP_P (mem) = 1;
21237 emit_insn (gen_stack_tie (mem));
21239 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21240 GEN_INT (info->total_size)));
21243 if (insn && frame_reg_rtx == sp_reg_rtx)
21247 REG_NOTES (insn) = cfa_restores;
21248 cfa_restores = NULL_RTX;
21250 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21251 RTX_FRAME_RELATED_P (insn) = 1;
21254 /* Restore AltiVec registers if we have not done so already. */
21255 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21256 && TARGET_ALTIVEC_ABI
21257 && info->altivec_size != 0
21258 && (DEFAULT_ABI == ABI_V4
21259 || !offset_below_red_zone_p (info->altivec_save_offset)))
21263 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21264 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21266 rtx addr, areg, mem, reg;
21268 areg = gen_rtx_REG (Pmode, 0);
21270 (areg, GEN_INT (info->altivec_save_offset
21272 + 16 * (i - info->first_altivec_reg_save)));
21274 /* AltiVec addressing mode is [reg+reg]. */
21275 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21276 mem = gen_frame_mem (V4SImode, addr);
21278 reg = gen_rtx_REG (V4SImode, i);
21279 emit_move_insn (reg, mem);
21280 if (DEFAULT_ABI == ABI_V4)
21281 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21286 /* Restore VRSAVE if we have not done so already. */
21287 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21289 && TARGET_ALTIVEC_VRSAVE
21290 && info->vrsave_mask != 0
21291 && (DEFAULT_ABI == ABI_V4
21292 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21294 rtx addr, mem, reg;
21296 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21297 GEN_INT (info->vrsave_save_offset + sp_offset));
21298 mem = gen_frame_mem (SImode, addr);
21299 reg = gen_rtx_REG (SImode, 12);
21300 emit_move_insn (reg, mem);
21302 emit_insn (generate_set_vrsave (reg, info, 1));
21305 /* Get the old lr if we saved it. If we are restoring registers
21306 out-of-line, then the out-of-line routines can do this for us. */
21307 if (restore_lr && restoring_GPRs_inline)
21309 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21310 info->lr_save_offset + sp_offset);
21312 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21315 /* Get the old cr if we saved it. */
21316 if (info->cr_save_p)
21318 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21319 GEN_INT (info->cr_save_offset + sp_offset));
21320 rtx mem = gen_frame_mem (SImode, addr);
21322 cr_save_reg = gen_rtx_REG (SImode,
21323 DEFAULT_ABI == ABI_AIX
21324 && !restoring_GPRs_inline
21325 && info->first_fp_reg_save < 64
21327 emit_move_insn (cr_save_reg, mem);
21330 /* Set LR here to try to overlap restores below. LR is always saved
21331 above incoming stack, so it never needs REG_CFA_RESTORE. */
21332 if (restore_lr && restoring_GPRs_inline)
21333 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21334 gen_rtx_REG (Pmode, 0));
21336 /* Load exception handler data registers, if needed. */
21337 if (crtl->calls_eh_return)
21339 unsigned int i, regno;
21343 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21344 GEN_INT (sp_offset + 5 * reg_size));
21345 rtx mem = gen_frame_mem (reg_mode, addr);
21347 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21354 regno = EH_RETURN_DATA_REGNO (i);
21355 if (regno == INVALID_REGNUM)
21358 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21359 info->ehrd_offset + sp_offset
21360 + reg_size * (int) i);
21362 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21366 /* Restore GPRs. This is done as a PARALLEL if we are using
21367 the load-multiple instructions. */
21369 && info->spe_64bit_regs_used != 0
21370 && info->first_gp_reg_save != 32)
21372 /* Determine whether we can address all of the registers that need
21373 to be saved with an offset from the stack pointer that fits in
21374 the small const field for SPE memory instructions. */
21375 int spe_regs_addressable_via_sp
21376 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21377 + (32 - info->first_gp_reg_save - 1) * reg_size)
21378 && restoring_GPRs_inline);
21381 if (spe_regs_addressable_via_sp)
21382 spe_offset = info->spe_gp_save_offset + sp_offset;
21385 rtx old_frame_reg_rtx = frame_reg_rtx;
21386 /* Make r11 point to the start of the SPE save area. We worried about
21387 not clobbering it when we were saving registers in the prologue.
21388 There's no need to worry here because the static chain is passed
21389 anew to every function. */
21390 int ool_adjust = (restoring_GPRs_inline
21392 : (info->first_gp_reg_save
21393 - (FIRST_SAVRES_REGISTER+1))*8);
21395 if (frame_reg_rtx == sp_reg_rtx)
21396 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21397 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21398 GEN_INT (info->spe_gp_save_offset
21401 /* Keep the invariant that frame_reg_rtx + sp_offset points
21402 at the top of the stack frame. */
21403 sp_offset = -info->spe_gp_save_offset;
21408 if (restoring_GPRs_inline)
21410 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21411 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21413 rtx offset, addr, mem, reg;
21415 /* We're doing all this to ensure that the immediate offset
21416 fits into the immediate field of 'evldd'. */
21417 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21419 offset = GEN_INT (spe_offset + reg_size * i);
21420 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21421 mem = gen_rtx_MEM (V2SImode, addr);
21422 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21424 insn = emit_move_insn (reg, mem);
21425 if (DEFAULT_ABI == ABI_V4)
21427 if (frame_pointer_needed
21428 && info->first_gp_reg_save + i
21429 == HARD_FRAME_POINTER_REGNUM)
21431 add_reg_note (insn, REG_CFA_DEF_CFA,
21432 plus_constant (frame_reg_rtx,
21434 RTX_FRAME_RELATED_P (insn) = 1;
21437 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21446 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21448 /*savep=*/false, /*gpr=*/true,
21450 emit_jump_insn (par);
21451 /* We don't want anybody else emitting things after we jumped
21456 else if (!restoring_GPRs_inline)
21458 /* We are jumping to an out-of-line function. */
21459 bool can_use_exit = info->first_fp_reg_save == 64;
21462 /* Emit stack reset code if we need it. */
21464 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21465 sp_offset, can_use_exit);
21468 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21471 GEN_INT (sp_offset - info->fp_size)));
21472 if (REGNO (frame_reg_rtx) == 11)
21473 sp_offset += info->fp_size;
21476 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21477 info->gp_save_offset, reg_mode,
21478 /*savep=*/false, /*gpr=*/true,
21479 /*lr=*/can_use_exit);
21483 if (info->cr_save_p)
21485 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21486 if (DEFAULT_ABI == ABI_V4)
21488 = alloc_reg_note (REG_CFA_RESTORE,
21489 gen_rtx_REG (SImode, CR2_REGNO),
21493 emit_jump_insn (par);
21495 /* We don't want anybody else emitting things after we jumped
21500 insn = emit_insn (par);
21501 if (DEFAULT_ABI == ABI_V4)
21503 if (frame_pointer_needed)
21505 add_reg_note (insn, REG_CFA_DEF_CFA,
21506 plus_constant (frame_reg_rtx, sp_offset));
21507 RTX_FRAME_RELATED_P (insn) = 1;
21510 for (i = info->first_gp_reg_save; i < 32; i++)
21512 = alloc_reg_note (REG_CFA_RESTORE,
21513 gen_rtx_REG (reg_mode, i), cfa_restores);
21516 else if (using_load_multiple)
21519 p = rtvec_alloc (32 - info->first_gp_reg_save);
21520 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21522 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21523 GEN_INT (info->gp_save_offset
21526 rtx mem = gen_frame_mem (reg_mode, addr);
21527 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21529 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21530 if (DEFAULT_ABI == ABI_V4)
21531 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21534 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21535 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21537 add_reg_note (insn, REG_CFA_DEF_CFA,
21538 plus_constant (frame_reg_rtx, sp_offset));
21539 RTX_FRAME_RELATED_P (insn) = 1;
21544 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21545 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21547 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21548 GEN_INT (info->gp_save_offset
21551 rtx mem = gen_frame_mem (reg_mode, addr);
21552 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21554 insn = emit_move_insn (reg, mem);
21555 if (DEFAULT_ABI == ABI_V4)
21557 if (frame_pointer_needed
21558 && info->first_gp_reg_save + i
21559 == HARD_FRAME_POINTER_REGNUM)
21561 add_reg_note (insn, REG_CFA_DEF_CFA,
21562 plus_constant (frame_reg_rtx, sp_offset));
21563 RTX_FRAME_RELATED_P (insn) = 1;
21566 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21572 if (restore_lr && !restoring_GPRs_inline)
21574 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21575 info->lr_save_offset + sp_offset);
21577 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21578 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21579 gen_rtx_REG (Pmode, 0));
21582 /* Restore fpr's if we need to do it without calling a function. */
21583 if (restoring_FPRs_inline)
21584 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21585 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21586 && ! call_used_regs[info->first_fp_reg_save+i]))
21588 rtx addr, mem, reg;
21589 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21590 GEN_INT (info->fp_save_offset
21593 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21594 ? DFmode : SFmode), addr);
21595 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21596 ? DFmode : SFmode),
21597 info->first_fp_reg_save + i);
21599 emit_move_insn (reg, mem);
21600 if (DEFAULT_ABI == ABI_V4)
21601 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21605 /* If we saved cr, restore it here. Just those that were used. */
21606 if (info->cr_save_p)
21608 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21609 if (DEFAULT_ABI == ABI_V4)
21611 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21615 /* If this is V.4, unwind the stack pointer after all of the loads
21617 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21618 sp_offset, !restoring_FPRs_inline);
21623 REG_NOTES (insn) = cfa_restores;
21624 cfa_restores = NULL_RTX;
21626 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21627 RTX_FRAME_RELATED_P (insn) = 1;
21630 if (crtl->calls_eh_return)
21632 rtx sa = EH_RETURN_STACKADJ_RTX;
21633 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21639 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21640 if (! restoring_FPRs_inline)
21641 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21643 p = rtvec_alloc (2);
21645 RTVEC_ELT (p, 0) = ret_rtx;
21646 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21647 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21648 : gen_rtx_CLOBBER (VOIDmode,
21649 gen_rtx_REG (Pmode, 65)));
21651 /* If we have to restore more than two FP registers, branch to the
21652 restore function. It will return to our caller. */
21653 if (! restoring_FPRs_inline)
21658 sym = rs6000_savres_routine_sym (info,
21662 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21663 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21664 gen_rtx_REG (Pmode,
21665 DEFAULT_ABI == ABI_AIX
21667 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21670 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21671 GEN_INT (info->fp_save_offset + 8*i));
21672 mem = gen_frame_mem (DFmode, addr);
21674 RTVEC_ELT (p, i+4) =
21675 gen_rtx_SET (VOIDmode,
21676 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21681 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21685 /* Write function epilogue. */
21688 rs6000_output_function_epilogue (FILE *file,
21689 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21691 if (! HAVE_epilogue)
21693 rtx insn = get_last_insn ();
21694 /* If the last insn was a BARRIER, we don't have to write anything except
21695 the trace table. */
21696 if (GET_CODE (insn) == NOTE)
21697 insn = prev_nonnote_insn (insn);
21698 if (insn == 0 || GET_CODE (insn) != BARRIER)
21700 /* This is slightly ugly, but at least we don't have two
21701 copies of the epilogue-emitting code. */
21704 /* A NOTE_INSN_DELETED is supposed to be at the start
21705 and end of the "toplevel" insn chain. */
21706 emit_note (NOTE_INSN_DELETED);
21707 rs6000_emit_epilogue (FALSE);
21708 emit_note (NOTE_INSN_DELETED);
21710 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21714 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21716 INSN_ADDRESSES_NEW (insn, addr);
21721 if (TARGET_DEBUG_STACK)
21722 debug_rtx_list (get_insns (), 100);
21723 final (get_insns (), file, FALSE);
21729 macho_branch_islands ();
21730 /* Mach-O doesn't support labels at the end of objects, so if
21731 it looks like we might want one, insert a NOP. */
21733 rtx insn = get_last_insn ();
21736 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21737 insn = PREV_INSN (insn);
21741 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21742 fputs ("\tnop\n", file);
21746 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21749 We don't output a traceback table if -finhibit-size-directive was
21750 used. The documentation for -finhibit-size-directive reads
21751 ``don't output a @code{.size} assembler directive, or anything
21752 else that would cause trouble if the function is split in the
21753 middle, and the two halves are placed at locations far apart in
21754 memory.'' The traceback table has this property, since it
21755 includes the offset from the start of the function to the
21756 traceback table itself.
21758 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21759 different traceback table. */
21760 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21761 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21763 const char *fname = NULL;
21764 const char *language_string = lang_hooks.name;
21765 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21767 int optional_tbtab;
21768 rs6000_stack_t *info = rs6000_stack_info ();
21770 if (rs6000_traceback == traceback_full)
21771 optional_tbtab = 1;
21772 else if (rs6000_traceback == traceback_part)
21773 optional_tbtab = 0;
21775 optional_tbtab = !optimize_size && !TARGET_ELF;
21777 if (optional_tbtab)
21779 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21780 while (*fname == '.') /* V.4 encodes . in the name */
21783 /* Need label immediately before tbtab, so we can compute
21784 its offset from the function start. */
21785 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21786 ASM_OUTPUT_LABEL (file, fname);
21789 /* The .tbtab pseudo-op can only be used for the first eight
21790 expressions, since it can't handle the possibly variable
21791 length fields that follow. However, if you omit the optional
21792 fields, the assembler outputs zeros for all optional fields
21793 anyways, giving each variable length field is minimum length
21794 (as defined in sys/debug.h). Thus we can not use the .tbtab
21795 pseudo-op at all. */
21797 /* An all-zero word flags the start of the tbtab, for debuggers
21798 that have to find it by searching forward from the entry
21799 point or from the current pc. */
21800 fputs ("\t.long 0\n", file);
21802 /* Tbtab format type. Use format type 0. */
21803 fputs ("\t.byte 0,", file);
21805 /* Language type. Unfortunately, there does not seem to be any
21806 official way to discover the language being compiled, so we
21807 use language_string.
21808 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21809 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21810 a number, so for now use 9. LTO and Go aren't assigned numbers
21811 either, so for now use 0. */
21812 if (! strcmp (language_string, "GNU C")
21813 || ! strcmp (language_string, "GNU GIMPLE")
21814 || ! strcmp (language_string, "GNU Go"))
21816 else if (! strcmp (language_string, "GNU F77")
21817 || ! strcmp (language_string, "GNU Fortran"))
21819 else if (! strcmp (language_string, "GNU Pascal"))
21821 else if (! strcmp (language_string, "GNU Ada"))
21823 else if (! strcmp (language_string, "GNU C++")
21824 || ! strcmp (language_string, "GNU Objective-C++"))
21826 else if (! strcmp (language_string, "GNU Java"))
21828 else if (! strcmp (language_string, "GNU Objective-C"))
21831 gcc_unreachable ();
21832 fprintf (file, "%d,", i);
21834 /* 8 single bit fields: global linkage (not set for C extern linkage,
21835 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21836 from start of procedure stored in tbtab, internal function, function
21837 has controlled storage, function has no toc, function uses fp,
21838 function logs/aborts fp operations. */
21839 /* Assume that fp operations are used if any fp reg must be saved. */
21840 fprintf (file, "%d,",
21841 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21843 /* 6 bitfields: function is interrupt handler, name present in
21844 proc table, function calls alloca, on condition directives
21845 (controls stack walks, 3 bits), saves condition reg, saves
21847 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21848 set up as a frame pointer, even when there is no alloca call. */
21849 fprintf (file, "%d,",
21850 ((optional_tbtab << 6)
21851 | ((optional_tbtab & frame_pointer_needed) << 5)
21852 | (info->cr_save_p << 1)
21853 | (info->lr_save_p)));
21855 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21857 fprintf (file, "%d,",
21858 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21860 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21861 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21863 if (optional_tbtab)
21865 /* Compute the parameter info from the function decl argument
21868 int next_parm_info_bit = 31;
21870 for (decl = DECL_ARGUMENTS (current_function_decl);
21871 decl; decl = DECL_CHAIN (decl))
21873 rtx parameter = DECL_INCOMING_RTL (decl);
21874 enum machine_mode mode = GET_MODE (parameter);
21876 if (GET_CODE (parameter) == REG)
21878 if (SCALAR_FLOAT_MODE_P (mode))
21899 gcc_unreachable ();
21902 /* If only one bit will fit, don't or in this entry. */
21903 if (next_parm_info_bit > 0)
21904 parm_info |= (bits << (next_parm_info_bit - 1));
21905 next_parm_info_bit -= 2;
21909 fixed_parms += ((GET_MODE_SIZE (mode)
21910 + (UNITS_PER_WORD - 1))
21912 next_parm_info_bit -= 1;
21918 /* Number of fixed point parameters. */
21919 /* This is actually the number of words of fixed point parameters; thus
21920 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21921 fprintf (file, "%d,", fixed_parms);
21923 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21925 /* This is actually the number of fp registers that hold parameters;
21926 and thus the maximum value is 13. */
21927 /* Set parameters on stack bit if parameters are not in their original
21928 registers, regardless of whether they are on the stack? Xlc
21929 seems to set the bit when not optimizing. */
21930 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21932 if (! optional_tbtab)
21935 /* Optional fields follow. Some are variable length. */
21937 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21938 11 double float. */
21939 /* There is an entry for each parameter in a register, in the order that
21940 they occur in the parameter list. Any intervening arguments on the
21941 stack are ignored. If the list overflows a long (max possible length
21942 34 bits) then completely leave off all elements that don't fit. */
21943 /* Only emit this long if there was at least one parameter. */
21944 if (fixed_parms || float_parms)
21945 fprintf (file, "\t.long %d\n", parm_info);
21947 /* Offset from start of code to tb table. */
21948 fputs ("\t.long ", file);
21949 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21950 RS6000_OUTPUT_BASENAME (file, fname);
21952 rs6000_output_function_entry (file, fname);
21955 /* Interrupt handler mask. */
21956 /* Omit this long, since we never set the interrupt handler bit
21959 /* Number of CTL (controlled storage) anchors. */
21960 /* Omit this long, since the has_ctl bit is never set above. */
21962 /* Displacement into stack of each CTL anchor. */
21963 /* Omit this list of longs, because there are no CTL anchors. */
21965 /* Length of function name. */
21968 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21970 /* Function name. */
21971 assemble_string (fname, strlen (fname));
21973 /* Register for alloca automatic storage; this is always reg 31.
21974 Only emit this if the alloca bit was set above. */
21975 if (frame_pointer_needed)
21976 fputs ("\t.byte 31\n", file);
21978 fputs ("\t.align 2\n", file);
21982 /* A C compound statement that outputs the assembler code for a thunk
21983 function, used to implement C++ virtual function calls with
21984 multiple inheritance. The thunk acts as a wrapper around a virtual
21985 function, adjusting the implicit object parameter before handing
21986 control off to the real function.
21988 First, emit code to add the integer DELTA to the location that
21989 contains the incoming first argument. Assume that this argument
21990 contains a pointer, and is the one used to pass the `this' pointer
21991 in C++. This is the incoming argument *before* the function
21992 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21993 values of all other incoming arguments.
21995 After the addition, emit code to jump to FUNCTION, which is a
21996 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21997 not touch the return address. Hence returning from FUNCTION will
21998 return to whoever called the current `thunk'.
22000 The effect must be as if FUNCTION had been called directly with the
22001 adjusted first argument. This macro is responsible for emitting
22002 all of the code for a thunk function; output_function_prologue()
22003 and output_function_epilogue() are not invoked.
22005 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22006 been extracted from it.) It might possibly be useful on some
22007 targets, but probably not.
22009 If you do not define this macro, the target-independent code in the
22010 C++ frontend will generate a less efficient heavyweight thunk that
22011 calls FUNCTION instead of jumping to it. The generic approach does
22012 not support varargs. */
22015 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22016 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22019 rtx this_rtx, insn, funexp;
22021 reload_completed = 1;
22022 epilogue_completed = 1;
22024 /* Mark the end of the (empty) prologue. */
22025 emit_note (NOTE_INSN_PROLOGUE_END);
22027 /* Find the "this" pointer. If the function returns a structure,
22028 the structure return pointer is in r3. */
22029 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22030 this_rtx = gen_rtx_REG (Pmode, 4);
22032 this_rtx = gen_rtx_REG (Pmode, 3);
22034 /* Apply the constant offset, if required. */
22036 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22038 /* Apply the offset from the vtable, if required. */
22041 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22042 rtx tmp = gen_rtx_REG (Pmode, 12);
22044 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22045 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22047 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22048 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22052 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22054 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22056 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22059 /* Generate a tail call to the target function. */
22060 if (!TREE_USED (function))
22062 assemble_external (function);
22063 TREE_USED (function) = 1;
22065 funexp = XEXP (DECL_RTL (function), 0);
22066 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22069 if (MACHOPIC_INDIRECT)
22070 funexp = machopic_indirect_call_target (funexp);
22073 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22074 generate sibcall RTL explicitly. */
22075 insn = emit_call_insn (
22076 gen_rtx_PARALLEL (VOIDmode,
22078 gen_rtx_CALL (VOIDmode,
22079 funexp, const0_rtx),
22080 gen_rtx_USE (VOIDmode, const0_rtx),
22081 gen_rtx_USE (VOIDmode,
22082 gen_rtx_REG (SImode,
22085 SIBLING_CALL_P (insn) = 1;
22088 /* Run just enough of rest_of_compilation to get the insns emitted.
22089 There's not really enough bulk here to make other passes such as
22090 instruction scheduling worth while. Note that use_thunk calls
22091 assemble_start_function and assemble_end_function. */
22092 insn = get_insns ();
22093 insn_locators_alloc ();
22094 shorten_branches (insn);
22095 final_start_function (insn, file, 1);
22096 final (insn, file, 1);
22097 final_end_function ();
22099 reload_completed = 0;
22100 epilogue_completed = 0;
22103 /* A quick summary of the various types of 'constant-pool tables'
22106 Target Flags Name One table per
22107 AIX (none) AIX TOC object file
22108 AIX -mfull-toc AIX TOC object file
22109 AIX -mminimal-toc AIX minimal TOC translation unit
22110 SVR4/EABI (none) SVR4 SDATA object file
22111 SVR4/EABI -fpic SVR4 pic object file
22112 SVR4/EABI -fPIC SVR4 PIC translation unit
22113 SVR4/EABI -mrelocatable EABI TOC function
22114 SVR4/EABI -maix AIX TOC object file
22115 SVR4/EABI -maix -mminimal-toc
22116 AIX minimal TOC translation unit
22118 Name Reg. Set by entries contains:
22119 made by addrs? fp? sum?
22121 AIX TOC 2 crt0 as Y option option
22122 AIX minimal TOC 30 prolog gcc Y Y option
22123 SVR4 SDATA 13 crt0 gcc N Y N
22124 SVR4 pic 30 prolog ld Y not yet N
22125 SVR4 PIC 30 prolog gcc Y option option
22126 EABI TOC 30 prolog gcc Y option option
22130 /* Hash functions for the hash table. */
22133 rs6000_hash_constant (rtx k)
22135 enum rtx_code code = GET_CODE (k);
22136 enum machine_mode mode = GET_MODE (k);
22137 unsigned result = (code << 3) ^ mode;
22138 const char *format;
22141 format = GET_RTX_FORMAT (code);
22142 flen = strlen (format);
22148 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22151 if (mode != VOIDmode)
22152 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22164 for (; fidx < flen; fidx++)
22165 switch (format[fidx])
22170 const char *str = XSTR (k, fidx);
22171 len = strlen (str);
22172 result = result * 613 + len;
22173 for (i = 0; i < len; i++)
22174 result = result * 613 + (unsigned) str[i];
22179 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22183 result = result * 613 + (unsigned) XINT (k, fidx);
22186 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22187 result = result * 613 + (unsigned) XWINT (k, fidx);
22191 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22192 result = result * 613 + (unsigned) (XWINT (k, fidx)
22199 gcc_unreachable ();
22206 toc_hash_function (const void *hash_entry)
22208 const struct toc_hash_struct *thc =
22209 (const struct toc_hash_struct *) hash_entry;
22210 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22213 /* Compare H1 and H2 for equivalence. */
22216 toc_hash_eq (const void *h1, const void *h2)
22218 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22219 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22221 if (((const struct toc_hash_struct *) h1)->key_mode
22222 != ((const struct toc_hash_struct *) h2)->key_mode)
22225 return rtx_equal_p (r1, r2);
22228 /* These are the names given by the C++ front-end to vtables, and
22229 vtable-like objects. Ideally, this logic should not be here;
22230 instead, there should be some programmatic way of inquiring as
22231 to whether or not an object is a vtable. */
22233 #define VTABLE_NAME_P(NAME) \
22234 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22235 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22236 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22237 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22238 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22240 #ifdef NO_DOLLAR_IN_LABEL
22241 /* Return a GGC-allocated character string translating dollar signs in
22242 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22245 rs6000_xcoff_strip_dollar (const char *name)
22250 p = strchr (name, '$');
22252 if (p == 0 || p == name)
22255 len = strlen (name);
22256 strip = (char *) alloca (len + 1);
22257 strcpy (strip, name);
22258 p = strchr (strip, '$');
22262 p = strchr (p + 1, '$');
22265 return ggc_alloc_string (strip, len);
22270 rs6000_output_symbol_ref (FILE *file, rtx x)
22272 /* Currently C++ toc references to vtables can be emitted before it
22273 is decided whether the vtable is public or private. If this is
22274 the case, then the linker will eventually complain that there is
22275 a reference to an unknown section. Thus, for vtables only,
22276 we emit the TOC reference to reference the symbol and not the
22278 const char *name = XSTR (x, 0);
22280 if (VTABLE_NAME_P (name))
22282 RS6000_OUTPUT_BASENAME (file, name);
22285 assemble_name (file, name);
22288 /* Output a TOC entry. We derive the entry name from what is being
22292 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22295 const char *name = buf;
22297 HOST_WIDE_INT offset = 0;
22299 gcc_assert (!TARGET_NO_TOC);
22301 /* When the linker won't eliminate them, don't output duplicate
22302 TOC entries (this happens on AIX if there is any kind of TOC,
22303 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22305 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22307 struct toc_hash_struct *h;
22310 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22311 time because GGC is not initialized at that point. */
22312 if (toc_hash_table == NULL)
22313 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22314 toc_hash_eq, NULL);
22316 h = ggc_alloc_toc_hash_struct ();
22318 h->key_mode = mode;
22319 h->labelno = labelno;
22321 found = htab_find_slot (toc_hash_table, h, INSERT);
22322 if (*found == NULL)
22324 else /* This is indeed a duplicate.
22325 Set this label equal to that label. */
22327 fputs ("\t.set ", file);
22328 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22329 fprintf (file, "%d,", labelno);
22330 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22331 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22337 /* If we're going to put a double constant in the TOC, make sure it's
22338 aligned properly when strict alignment is on. */
22339 if (GET_CODE (x) == CONST_DOUBLE
22340 && STRICT_ALIGNMENT
22341 && GET_MODE_BITSIZE (mode) >= 64
22342 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22343 ASM_OUTPUT_ALIGN (file, 3);
22346 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22348 /* Handle FP constants specially. Note that if we have a minimal
22349 TOC, things we put here aren't actually in the TOC, so we can allow
22351 if (GET_CODE (x) == CONST_DOUBLE &&
22352 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22354 REAL_VALUE_TYPE rv;
22357 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22358 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22359 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22361 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22365 if (TARGET_MINIMAL_TOC)
22366 fputs (DOUBLE_INT_ASM_OP, file);
22368 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22369 k[0] & 0xffffffff, k[1] & 0xffffffff,
22370 k[2] & 0xffffffff, k[3] & 0xffffffff);
22371 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22372 k[0] & 0xffffffff, k[1] & 0xffffffff,
22373 k[2] & 0xffffffff, k[3] & 0xffffffff);
22378 if (TARGET_MINIMAL_TOC)
22379 fputs ("\t.long ", file);
22381 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22382 k[0] & 0xffffffff, k[1] & 0xffffffff,
22383 k[2] & 0xffffffff, k[3] & 0xffffffff);
22384 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22385 k[0] & 0xffffffff, k[1] & 0xffffffff,
22386 k[2] & 0xffffffff, k[3] & 0xffffffff);
22390 else if (GET_CODE (x) == CONST_DOUBLE &&
22391 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22393 REAL_VALUE_TYPE rv;
22396 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22398 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22399 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22401 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22405 if (TARGET_MINIMAL_TOC)
22406 fputs (DOUBLE_INT_ASM_OP, file);
22408 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22409 k[0] & 0xffffffff, k[1] & 0xffffffff);
22410 fprintf (file, "0x%lx%08lx\n",
22411 k[0] & 0xffffffff, k[1] & 0xffffffff);
22416 if (TARGET_MINIMAL_TOC)
22417 fputs ("\t.long ", file);
22419 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22420 k[0] & 0xffffffff, k[1] & 0xffffffff);
22421 fprintf (file, "0x%lx,0x%lx\n",
22422 k[0] & 0xffffffff, k[1] & 0xffffffff);
22426 else if (GET_CODE (x) == CONST_DOUBLE &&
22427 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22429 REAL_VALUE_TYPE rv;
22432 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22433 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22434 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22436 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22440 if (TARGET_MINIMAL_TOC)
22441 fputs (DOUBLE_INT_ASM_OP, file);
22443 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22444 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22449 if (TARGET_MINIMAL_TOC)
22450 fputs ("\t.long ", file);
22452 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22453 fprintf (file, "0x%lx\n", l & 0xffffffff);
22457 else if (GET_MODE (x) == VOIDmode
22458 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22460 unsigned HOST_WIDE_INT low;
22461 HOST_WIDE_INT high;
22463 if (GET_CODE (x) == CONST_DOUBLE)
22465 low = CONST_DOUBLE_LOW (x);
22466 high = CONST_DOUBLE_HIGH (x);
22469 #if HOST_BITS_PER_WIDE_INT == 32
22472 high = (low & 0x80000000) ? ~0 : 0;
22476 low = INTVAL (x) & 0xffffffff;
22477 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22481 /* TOC entries are always Pmode-sized, but since this
22482 is a bigendian machine then if we're putting smaller
22483 integer constants in the TOC we have to pad them.
22484 (This is still a win over putting the constants in
22485 a separate constant pool, because then we'd have
22486 to have both a TOC entry _and_ the actual constant.)
22488 For a 32-bit target, CONST_INT values are loaded and shifted
22489 entirely within `low' and can be stored in one TOC entry. */
22491 /* It would be easy to make this work, but it doesn't now. */
22492 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22494 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22496 #if HOST_BITS_PER_WIDE_INT == 32
22497 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22498 POINTER_SIZE, &low, &high, 0);
22501 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22502 high = (HOST_WIDE_INT) low >> 32;
22509 if (TARGET_MINIMAL_TOC)
22510 fputs (DOUBLE_INT_ASM_OP, file);
22512 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22513 (long) high & 0xffffffff, (long) low & 0xffffffff);
22514 fprintf (file, "0x%lx%08lx\n",
22515 (long) high & 0xffffffff, (long) low & 0xffffffff);
22520 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22522 if (TARGET_MINIMAL_TOC)
22523 fputs ("\t.long ", file);
22525 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22526 (long) high & 0xffffffff, (long) low & 0xffffffff);
22527 fprintf (file, "0x%lx,0x%lx\n",
22528 (long) high & 0xffffffff, (long) low & 0xffffffff);
22532 if (TARGET_MINIMAL_TOC)
22533 fputs ("\t.long ", file);
22535 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22536 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22542 if (GET_CODE (x) == CONST)
22544 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22545 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22547 base = XEXP (XEXP (x, 0), 0);
22548 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22551 switch (GET_CODE (base))
22554 name = XSTR (base, 0);
22558 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22559 CODE_LABEL_NUMBER (XEXP (base, 0)));
22563 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22567 gcc_unreachable ();
22570 if (TARGET_MINIMAL_TOC)
22571 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22574 fputs ("\t.tc ", file);
22575 RS6000_OUTPUT_BASENAME (file, name);
22578 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22580 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22582 fputs ("[TC],", file);
22585 /* Currently C++ toc references to vtables can be emitted before it
22586 is decided whether the vtable is public or private. If this is
22587 the case, then the linker will eventually complain that there is
22588 a TOC reference to an unknown section. Thus, for vtables only,
22589 we emit the TOC reference to reference the symbol and not the
22591 if (VTABLE_NAME_P (name))
22593 RS6000_OUTPUT_BASENAME (file, name);
22595 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22596 else if (offset > 0)
22597 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22600 output_addr_const (file, x);
22604 /* Output an assembler pseudo-op to write an ASCII string of N characters
22605 starting at P to FILE.
22607 On the RS/6000, we have to do this using the .byte operation and
22608 write out special characters outside the quoted string.
22609 Also, the assembler is broken; very long strings are truncated,
22610 so we must artificially break them up early. */
22613 output_ascii (FILE *file, const char *p, int n)
22616 int i, count_string;
22617 const char *for_string = "\t.byte \"";
22618 const char *for_decimal = "\t.byte ";
22619 const char *to_close = NULL;
22622 for (i = 0; i < n; i++)
22625 if (c >= ' ' && c < 0177)
22628 fputs (for_string, file);
22631 /* Write two quotes to get one. */
22639 for_decimal = "\"\n\t.byte ";
22643 if (count_string >= 512)
22645 fputs (to_close, file);
22647 for_string = "\t.byte \"";
22648 for_decimal = "\t.byte ";
22656 fputs (for_decimal, file);
22657 fprintf (file, "%d", c);
22659 for_string = "\n\t.byte \"";
22660 for_decimal = ", ";
22666 /* Now close the string if we have written one. Then end the line. */
22668 fputs (to_close, file);
22671 /* Generate a unique section name for FILENAME for a section type
22672 represented by SECTION_DESC. Output goes into BUF.
22674 SECTION_DESC can be any string, as long as it is different for each
22675 possible section type.
22677 We name the section in the same manner as xlc. The name begins with an
22678 underscore followed by the filename (after stripping any leading directory
22679 names) with the last period replaced by the string SECTION_DESC. If
22680 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22684 rs6000_gen_section_name (char **buf, const char *filename,
22685 const char *section_desc)
22687 const char *q, *after_last_slash, *last_period = 0;
22691 after_last_slash = filename;
22692 for (q = filename; *q; q++)
22695 after_last_slash = q + 1;
22696 else if (*q == '.')
22700 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22701 *buf = (char *) xmalloc (len);
22706 for (q = after_last_slash; *q; q++)
22708 if (q == last_period)
22710 strcpy (p, section_desc);
22711 p += strlen (section_desc);
22715 else if (ISALNUM (*q))
22719 if (last_period == 0)
22720 strcpy (p, section_desc);
22725 /* Emit profile function. */
22728 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22730 /* Non-standard profiling for kernels, which just saves LR then calls
22731 _mcount without worrying about arg saves. The idea is to change
22732 the function prologue as little as possible as it isn't easy to
22733 account for arg save/restore code added just for _mcount. */
22734 if (TARGET_PROFILE_KERNEL)
22737 if (DEFAULT_ABI == ABI_AIX)
22739 #ifndef NO_PROFILE_COUNTERS
22740 # define NO_PROFILE_COUNTERS 0
22742 if (NO_PROFILE_COUNTERS)
22743 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22744 LCT_NORMAL, VOIDmode, 0);
22748 const char *label_name;
22751 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22752 label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
22753 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22755 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22756 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22759 else if (DEFAULT_ABI == ABI_DARWIN)
22761 const char *mcount_name = RS6000_MCOUNT;
22762 int caller_addr_regno = LR_REGNO;
22764 /* Be conservative and always set this, at least for now. */
22765 crtl->uses_pic_offset_table = 1;
22768 /* For PIC code, set up a stub and collect the caller's address
22769 from r0, which is where the prologue puts it. */
22770 if (MACHOPIC_INDIRECT
22771 && crtl->uses_pic_offset_table)
22772 caller_addr_regno = 0;
22774 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22775 LCT_NORMAL, VOIDmode, 1,
22776 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22780 /* Write function profiler code. */
22783 output_function_profiler (FILE *file, int labelno)
22787 switch (DEFAULT_ABI)
22790 gcc_unreachable ();
22795 warning (0, "no profiling of 64-bit code for this ABI");
22798 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22799 fprintf (file, "\tmflr %s\n", reg_names[0]);
22800 if (NO_PROFILE_COUNTERS)
22802 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22803 reg_names[0], reg_names[1]);
22805 else if (TARGET_SECURE_PLT && flag_pic)
22807 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22808 reg_names[0], reg_names[1]);
22809 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22810 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22811 reg_names[12], reg_names[12]);
22812 assemble_name (file, buf);
22813 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22814 assemble_name (file, buf);
22815 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22817 else if (flag_pic == 1)
22819 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22820 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22821 reg_names[0], reg_names[1]);
22822 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22823 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22824 assemble_name (file, buf);
22825 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22827 else if (flag_pic > 1)
22829 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22830 reg_names[0], reg_names[1]);
22831 /* Now, we need to get the address of the label. */
22832 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22833 assemble_name (file, buf);
22834 fputs ("-.\n1:", file);
22835 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22836 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22837 reg_names[0], reg_names[11]);
22838 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22839 reg_names[0], reg_names[0], reg_names[11]);
22843 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22844 assemble_name (file, buf);
22845 fputs ("@ha\n", file);
22846 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22847 reg_names[0], reg_names[1]);
22848 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22849 assemble_name (file, buf);
22850 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22853 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22854 fprintf (file, "\tbl %s%s\n",
22855 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22860 if (!TARGET_PROFILE_KERNEL)
22862 /* Don't do anything, done in output_profile_hook (). */
22866 gcc_assert (!TARGET_32BIT);
22868 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22869 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22871 if (cfun->static_chain_decl != NULL)
22873 asm_fprintf (file, "\tstd %s,24(%s)\n",
22874 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22875 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22876 asm_fprintf (file, "\tld %s,24(%s)\n",
22877 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22880 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22888 /* The following variable value is the last issued insn. */
22890 static rtx last_scheduled_insn;
22892 /* The following variable helps to balance issuing of load and
22893 store instructions */
22895 static int load_store_pendulum;
22897 /* Power4 load update and store update instructions are cracked into a
22898 load or store and an integer insn which are executed in the same cycle.
22899 Branches have their own dispatch slot which does not count against the
22900 GCC issue rate, but it changes the program flow so there are no other
22901 instructions to issue in this cycle. */
22904 rs6000_variable_issue_1 (rtx insn, int more)
22906 last_scheduled_insn = insn;
22907 if (GET_CODE (PATTERN (insn)) == USE
22908 || GET_CODE (PATTERN (insn)) == CLOBBER)
22910 cached_can_issue_more = more;
22911 return cached_can_issue_more;
22914 if (insn_terminates_group_p (insn, current_group))
22916 cached_can_issue_more = 0;
22917 return cached_can_issue_more;
22920 /* If no reservation, but reach here */
22921 if (recog_memoized (insn) < 0)
22924 if (rs6000_sched_groups)
22926 if (is_microcoded_insn (insn))
22927 cached_can_issue_more = 0;
22928 else if (is_cracked_insn (insn))
22929 cached_can_issue_more = more > 2 ? more - 2 : 0;
22931 cached_can_issue_more = more - 1;
22933 return cached_can_issue_more;
22936 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22939 cached_can_issue_more = more - 1;
22940 return cached_can_issue_more;
22944 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22946 int r = rs6000_variable_issue_1 (insn, more);
22948 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22952 /* Adjust the cost of a scheduling dependency. Return the new cost of
22953 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22956 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22958 enum attr_type attr_type;
22960 if (! recog_memoized (insn))
22963 switch (REG_NOTE_KIND (link))
22967 /* Data dependency; DEP_INSN writes a register that INSN reads
22968 some cycles later. */
22970 /* Separate a load from a narrower, dependent store. */
22971 if (rs6000_sched_groups
22972 && GET_CODE (PATTERN (insn)) == SET
22973 && GET_CODE (PATTERN (dep_insn)) == SET
22974 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22975 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22976 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22977 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22980 attr_type = get_attr_type (insn);
22985 /* Tell the first scheduling pass about the latency between
22986 a mtctr and bctr (and mtlr and br/blr). The first
22987 scheduling pass will not know about this latency since
22988 the mtctr instruction, which has the latency associated
22989 to it, will be generated by reload. */
22990 return TARGET_POWER ? 5 : 4;
22992 /* Leave some extra cycles between a compare and its
22993 dependent branch, to inhibit expensive mispredicts. */
22994 if ((rs6000_cpu_attr == CPU_PPC603
22995 || rs6000_cpu_attr == CPU_PPC604
22996 || rs6000_cpu_attr == CPU_PPC604E
22997 || rs6000_cpu_attr == CPU_PPC620
22998 || rs6000_cpu_attr == CPU_PPC630
22999 || rs6000_cpu_attr == CPU_PPC750
23000 || rs6000_cpu_attr == CPU_PPC7400
23001 || rs6000_cpu_attr == CPU_PPC7450
23002 || rs6000_cpu_attr == CPU_POWER4
23003 || rs6000_cpu_attr == CPU_POWER5
23004 || rs6000_cpu_attr == CPU_POWER7
23005 || rs6000_cpu_attr == CPU_CELL)
23006 && recog_memoized (dep_insn)
23007 && (INSN_CODE (dep_insn) >= 0))
23009 switch (get_attr_type (dep_insn))
23013 case TYPE_DELAYED_COMPARE:
23014 case TYPE_IMUL_COMPARE:
23015 case TYPE_LMUL_COMPARE:
23016 case TYPE_FPCOMPARE:
23017 case TYPE_CR_LOGICAL:
23018 case TYPE_DELAYED_CR:
23027 case TYPE_STORE_UX:
23029 case TYPE_FPSTORE_U:
23030 case TYPE_FPSTORE_UX:
23031 if ((rs6000_cpu == PROCESSOR_POWER6)
23032 && recog_memoized (dep_insn)
23033 && (INSN_CODE (dep_insn) >= 0))
23036 if (GET_CODE (PATTERN (insn)) != SET)
23037 /* If this happens, we have to extend this to schedule
23038 optimally. Return default for now. */
23041 /* Adjust the cost for the case where the value written
23042 by a fixed point operation is used as the address
23043 gen value on a store. */
23044 switch (get_attr_type (dep_insn))
23051 if (! store_data_bypass_p (dep_insn, insn))
23055 case TYPE_LOAD_EXT:
23056 case TYPE_LOAD_EXT_U:
23057 case TYPE_LOAD_EXT_UX:
23058 case TYPE_VAR_SHIFT_ROTATE:
23059 case TYPE_VAR_DELAYED_COMPARE:
23061 if (! store_data_bypass_p (dep_insn, insn))
23067 case TYPE_FAST_COMPARE:
23070 case TYPE_INSERT_WORD:
23071 case TYPE_INSERT_DWORD:
23072 case TYPE_FPLOAD_U:
23073 case TYPE_FPLOAD_UX:
23075 case TYPE_STORE_UX:
23076 case TYPE_FPSTORE_U:
23077 case TYPE_FPSTORE_UX:
23079 if (! store_data_bypass_p (dep_insn, insn))
23087 case TYPE_IMUL_COMPARE:
23088 case TYPE_LMUL_COMPARE:
23090 if (! store_data_bypass_p (dep_insn, insn))
23096 if (! store_data_bypass_p (dep_insn, insn))
23102 if (! store_data_bypass_p (dep_insn, insn))
23115 case TYPE_LOAD_EXT:
23116 case TYPE_LOAD_EXT_U:
23117 case TYPE_LOAD_EXT_UX:
23118 if ((rs6000_cpu == PROCESSOR_POWER6)
23119 && recog_memoized (dep_insn)
23120 && (INSN_CODE (dep_insn) >= 0))
23123 /* Adjust the cost for the case where the value written
23124 by a fixed point instruction is used within the address
23125 gen portion of a subsequent load(u)(x) */
23126 switch (get_attr_type (dep_insn))
23133 if (set_to_load_agen (dep_insn, insn))
23137 case TYPE_LOAD_EXT:
23138 case TYPE_LOAD_EXT_U:
23139 case TYPE_LOAD_EXT_UX:
23140 case TYPE_VAR_SHIFT_ROTATE:
23141 case TYPE_VAR_DELAYED_COMPARE:
23143 if (set_to_load_agen (dep_insn, insn))
23149 case TYPE_FAST_COMPARE:
23152 case TYPE_INSERT_WORD:
23153 case TYPE_INSERT_DWORD:
23154 case TYPE_FPLOAD_U:
23155 case TYPE_FPLOAD_UX:
23157 case TYPE_STORE_UX:
23158 case TYPE_FPSTORE_U:
23159 case TYPE_FPSTORE_UX:
23161 if (set_to_load_agen (dep_insn, insn))
23169 case TYPE_IMUL_COMPARE:
23170 case TYPE_LMUL_COMPARE:
23172 if (set_to_load_agen (dep_insn, insn))
23178 if (set_to_load_agen (dep_insn, insn))
23184 if (set_to_load_agen (dep_insn, insn))
23195 if ((rs6000_cpu == PROCESSOR_POWER6)
23196 && recog_memoized (dep_insn)
23197 && (INSN_CODE (dep_insn) >= 0)
23198 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23205 /* Fall out to return default cost. */
23209 case REG_DEP_OUTPUT:
23210 /* Output dependency; DEP_INSN writes a register that INSN writes some
23212 if ((rs6000_cpu == PROCESSOR_POWER6)
23213 && recog_memoized (dep_insn)
23214 && (INSN_CODE (dep_insn) >= 0))
23216 attr_type = get_attr_type (insn);
23221 if (get_attr_type (dep_insn) == TYPE_FP)
23225 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23233 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23238 gcc_unreachable ();
23244 /* Debug version of rs6000_adjust_cost. */
23247 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23249 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23255 switch (REG_NOTE_KIND (link))
23257 default: dep = "unknown depencency"; break;
23258 case REG_DEP_TRUE: dep = "data dependency"; break;
23259 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23260 case REG_DEP_ANTI: dep = "anti depencency"; break;
23264 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23265 "%s, insn:\n", ret, cost, dep);
23273 /* The function returns a true if INSN is microcoded.
23274 Return false otherwise. */
23277 is_microcoded_insn (rtx insn)
23279 if (!insn || !NONDEBUG_INSN_P (insn)
23280 || GET_CODE (PATTERN (insn)) == USE
23281 || GET_CODE (PATTERN (insn)) == CLOBBER)
23284 if (rs6000_cpu_attr == CPU_CELL)
23285 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23287 if (rs6000_sched_groups)
23289 enum attr_type type = get_attr_type (insn);
23290 if (type == TYPE_LOAD_EXT_U
23291 || type == TYPE_LOAD_EXT_UX
23292 || type == TYPE_LOAD_UX
23293 || type == TYPE_STORE_UX
23294 || type == TYPE_MFCR)
23301 /* The function returns true if INSN is cracked into 2 instructions
23302 by the processor (and therefore occupies 2 issue slots). */
23305 is_cracked_insn (rtx insn)
23307 if (!insn || !NONDEBUG_INSN_P (insn)
23308 || GET_CODE (PATTERN (insn)) == USE
23309 || GET_CODE (PATTERN (insn)) == CLOBBER)
23312 if (rs6000_sched_groups)
23314 enum attr_type type = get_attr_type (insn);
23315 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23316 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23317 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23318 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23319 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23320 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23321 || type == TYPE_IDIV || type == TYPE_LDIV
23322 || type == TYPE_INSERT_WORD)
23329 /* The function returns true if INSN can be issued only from
23330 the branch slot. */
23333 is_branch_slot_insn (rtx insn)
23335 if (!insn || !NONDEBUG_INSN_P (insn)
23336 || GET_CODE (PATTERN (insn)) == USE
23337 || GET_CODE (PATTERN (insn)) == CLOBBER)
23340 if (rs6000_sched_groups)
23342 enum attr_type type = get_attr_type (insn);
23343 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23351 /* The function returns true if out_inst sets a value that is
23352 used in the address generation computation of in_insn */
23354 set_to_load_agen (rtx out_insn, rtx in_insn)
23356 rtx out_set, in_set;
23358 /* For performance reasons, only handle the simple case where
23359 both loads are a single_set. */
23360 out_set = single_set (out_insn);
23363 in_set = single_set (in_insn);
23365 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23371 /* The function returns true if the target storage location of
23372 out_insn is adjacent to the target storage location of in_insn */
23373 /* Return 1 if memory locations are adjacent. */
23376 adjacent_mem_locations (rtx insn1, rtx insn2)
23379 rtx a = get_store_dest (PATTERN (insn1));
23380 rtx b = get_store_dest (PATTERN (insn2));
23382 if ((GET_CODE (XEXP (a, 0)) == REG
23383 || (GET_CODE (XEXP (a, 0)) == PLUS
23384 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23385 && (GET_CODE (XEXP (b, 0)) == REG
23386 || (GET_CODE (XEXP (b, 0)) == PLUS
23387 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23389 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23392 if (GET_CODE (XEXP (a, 0)) == PLUS)
23394 reg0 = XEXP (XEXP (a, 0), 0);
23395 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23398 reg0 = XEXP (a, 0);
23400 if (GET_CODE (XEXP (b, 0)) == PLUS)
23402 reg1 = XEXP (XEXP (b, 0), 0);
23403 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23406 reg1 = XEXP (b, 0);
23408 val_diff = val1 - val0;
23410 return ((REGNO (reg0) == REGNO (reg1))
23411 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23412 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23418 /* A C statement (sans semicolon) to update the integer scheduling
23419 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23420 INSN earlier, reduce the priority to execute INSN later. Do not
23421 define this macro if you do not need to adjust the scheduling
23422 priorities of insns. */
23425 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23427 /* On machines (like the 750) which have asymmetric integer units,
23428 where one integer unit can do multiply and divides and the other
23429 can't, reduce the priority of multiply/divide so it is scheduled
23430 before other integer operations. */
23433 if (! INSN_P (insn))
23436 if (GET_CODE (PATTERN (insn)) == USE)
23439 switch (rs6000_cpu_attr) {
23441 switch (get_attr_type (insn))
23448 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23449 priority, priority);
23450 if (priority >= 0 && priority < 0x01000000)
23457 if (insn_must_be_first_in_group (insn)
23458 && reload_completed
23459 && current_sched_info->sched_max_insns_priority
23460 && rs6000_sched_restricted_insns_priority)
23463 /* Prioritize insns that can be dispatched only in the first
23465 if (rs6000_sched_restricted_insns_priority == 1)
23466 /* Attach highest priority to insn. This means that in
23467 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23468 precede 'priority' (critical path) considerations. */
23469 return current_sched_info->sched_max_insns_priority;
23470 else if (rs6000_sched_restricted_insns_priority == 2)
23471 /* Increase priority of insn by a minimal amount. This means that in
23472 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23473 considerations precede dispatch-slot restriction considerations. */
23474 return (priority + 1);
23477 if (rs6000_cpu == PROCESSOR_POWER6
23478 && ((load_store_pendulum == -2 && is_load_insn (insn))
23479 || (load_store_pendulum == 2 && is_store_insn (insn))))
23480 /* Attach highest priority to insn if the scheduler has just issued two
23481 stores and this instruction is a load, or two loads and this instruction
23482 is a store. Power6 wants loads and stores scheduled alternately
23484 return current_sched_info->sched_max_insns_priority;
23489 /* Return true if the instruction is nonpipelined on the Cell. */
23491 is_nonpipeline_insn (rtx insn)
23493 enum attr_type type;
23494 if (!insn || !NONDEBUG_INSN_P (insn)
23495 || GET_CODE (PATTERN (insn)) == USE
23496 || GET_CODE (PATTERN (insn)) == CLOBBER)
23499 type = get_attr_type (insn);
23500 if (type == TYPE_IMUL
23501 || type == TYPE_IMUL2
23502 || type == TYPE_IMUL3
23503 || type == TYPE_LMUL
23504 || type == TYPE_IDIV
23505 || type == TYPE_LDIV
23506 || type == TYPE_SDIV
23507 || type == TYPE_DDIV
23508 || type == TYPE_SSQRT
23509 || type == TYPE_DSQRT
23510 || type == TYPE_MFCR
23511 || type == TYPE_MFCRF
23512 || type == TYPE_MFJMPR)
23520 /* Return how many instructions the machine can issue per cycle. */
23523 rs6000_issue_rate (void)
23525 /* Unless scheduling for register pressure, use issue rate of 1 for
23526 first scheduling pass to decrease degradation. */
23527 if (!reload_completed && !flag_sched_pressure)
23530 switch (rs6000_cpu_attr) {
23531 case CPU_RIOS1: /* ? */
23533 case CPU_PPC601: /* ? */
23542 case CPU_PPCE300C2:
23543 case CPU_PPCE300C3:
23544 case CPU_PPCE500MC:
23545 case CPU_PPCE500MC64:
23565 /* Return how many instructions to look ahead for better insn
23569 rs6000_use_sched_lookahead (void)
23571 if (rs6000_cpu_attr == CPU_PPC8540)
23573 if (rs6000_cpu_attr == CPU_CELL)
23574 return (reload_completed ? 8 : 0);
23578 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23580 rs6000_use_sched_lookahead_guard (rtx insn)
23582 if (rs6000_cpu_attr != CPU_CELL)
23585 if (insn == NULL_RTX || !INSN_P (insn))
23588 if (!reload_completed
23589 || is_nonpipeline_insn (insn)
23590 || is_microcoded_insn (insn))
23596 /* Determine is PAT refers to memory. */
23599 is_mem_ref (rtx pat)
23605 /* stack_tie does not produce any real memory traffic. */
23606 if (GET_CODE (pat) == UNSPEC
23607 && XINT (pat, 1) == UNSPEC_TIE)
23610 if (GET_CODE (pat) == MEM)
23613 /* Recursively process the pattern. */
23614 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23616 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23619 ret |= is_mem_ref (XEXP (pat, i));
23620 else if (fmt[i] == 'E')
23621 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23622 ret |= is_mem_ref (XVECEXP (pat, i, j));
23628 /* Determine if PAT is a PATTERN of a load insn. */
23631 is_load_insn1 (rtx pat)
23633 if (!pat || pat == NULL_RTX)
23636 if (GET_CODE (pat) == SET)
23637 return is_mem_ref (SET_SRC (pat));
23639 if (GET_CODE (pat) == PARALLEL)
23643 for (i = 0; i < XVECLEN (pat, 0); i++)
23644 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23651 /* Determine if INSN loads from memory. */
23654 is_load_insn (rtx insn)
23656 if (!insn || !INSN_P (insn))
23659 if (GET_CODE (insn) == CALL_INSN)
23662 return is_load_insn1 (PATTERN (insn));
23665 /* Determine if PAT is a PATTERN of a store insn. */
23668 is_store_insn1 (rtx pat)
23670 if (!pat || pat == NULL_RTX)
23673 if (GET_CODE (pat) == SET)
23674 return is_mem_ref (SET_DEST (pat));
23676 if (GET_CODE (pat) == PARALLEL)
23680 for (i = 0; i < XVECLEN (pat, 0); i++)
23681 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23688 /* Determine if INSN stores to memory. */
23691 is_store_insn (rtx insn)
23693 if (!insn || !INSN_P (insn))
23696 return is_store_insn1 (PATTERN (insn));
23699 /* Return the dest of a store insn. */
23702 get_store_dest (rtx pat)
23704 gcc_assert (is_store_insn1 (pat));
23706 if (GET_CODE (pat) == SET)
23707 return SET_DEST (pat);
23708 else if (GET_CODE (pat) == PARALLEL)
23712 for (i = 0; i < XVECLEN (pat, 0); i++)
23714 rtx inner_pat = XVECEXP (pat, 0, i);
23715 if (GET_CODE (inner_pat) == SET
23716 && is_mem_ref (SET_DEST (inner_pat)))
23720 /* We shouldn't get here, because we should have either a simple
23721 store insn or a store with update which are covered above. */
23725 /* Returns whether the dependence between INSN and NEXT is considered
23726 costly by the given target. */
23729 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23734 /* If the flag is not enabled - no dependence is considered costly;
23735 allow all dependent insns in the same group.
23736 This is the most aggressive option. */
23737 if (rs6000_sched_costly_dep == no_dep_costly)
23740 /* If the flag is set to 1 - a dependence is always considered costly;
23741 do not allow dependent instructions in the same group.
23742 This is the most conservative option. */
23743 if (rs6000_sched_costly_dep == all_deps_costly)
23746 insn = DEP_PRO (dep);
23747 next = DEP_CON (dep);
23749 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23750 && is_load_insn (next)
23751 && is_store_insn (insn))
23752 /* Prevent load after store in the same group. */
23755 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23756 && is_load_insn (next)
23757 && is_store_insn (insn)
23758 && DEP_TYPE (dep) == REG_DEP_TRUE)
23759 /* Prevent load after store in the same group if it is a true
23763 /* The flag is set to X; dependences with latency >= X are considered costly,
23764 and will not be scheduled in the same group. */
23765 if (rs6000_sched_costly_dep <= max_dep_latency
23766 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23772 /* Return the next insn after INSN that is found before TAIL is reached,
23773 skipping any "non-active" insns - insns that will not actually occupy
23774 an issue slot. Return NULL_RTX if such an insn is not found. */
23777 get_next_active_insn (rtx insn, rtx tail)
23779 if (insn == NULL_RTX || insn == tail)
23784 insn = NEXT_INSN (insn);
23785 if (insn == NULL_RTX || insn == tail)
23790 || (NONJUMP_INSN_P (insn)
23791 && GET_CODE (PATTERN (insn)) != USE
23792 && GET_CODE (PATTERN (insn)) != CLOBBER
23793 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23799 /* We are about to begin issuing insns for this clock cycle. */
23802 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23803 rtx *ready ATTRIBUTE_UNUSED,
23804 int *pn_ready ATTRIBUTE_UNUSED,
23805 int clock_var ATTRIBUTE_UNUSED)
23807 int n_ready = *pn_ready;
23810 fprintf (dump, "// rs6000_sched_reorder :\n");
23812 /* Reorder the ready list, if the second to last ready insn
23813 is a nonepipeline insn. */
23814 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23816 if (is_nonpipeline_insn (ready[n_ready - 1])
23817 && (recog_memoized (ready[n_ready - 2]) > 0))
23818 /* Simply swap first two insns. */
23820 rtx tmp = ready[n_ready - 1];
23821 ready[n_ready - 1] = ready[n_ready - 2];
23822 ready[n_ready - 2] = tmp;
23826 if (rs6000_cpu == PROCESSOR_POWER6)
23827 load_store_pendulum = 0;
23829 return rs6000_issue_rate ();
23832 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23835 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23836 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23839 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23841 /* For Power6, we need to handle some special cases to try and keep the
23842 store queue from overflowing and triggering expensive flushes.
23844 This code monitors how load and store instructions are being issued
23845 and skews the ready list one way or the other to increase the likelihood
23846 that a desired instruction is issued at the proper time.
23848 A couple of things are done. First, we maintain a "load_store_pendulum"
23849 to track the current state of load/store issue.
23851 - If the pendulum is at zero, then no loads or stores have been
23852 issued in the current cycle so we do nothing.
23854 - If the pendulum is 1, then a single load has been issued in this
23855 cycle and we attempt to locate another load in the ready list to
23858 - If the pendulum is -2, then two stores have already been
23859 issued in this cycle, so we increase the priority of the first load
23860 in the ready list to increase it's likelihood of being chosen first
23863 - If the pendulum is -1, then a single store has been issued in this
23864 cycle and we attempt to locate another store in the ready list to
23865 issue with it, preferring a store to an adjacent memory location to
23866 facilitate store pairing in the store queue.
23868 - If the pendulum is 2, then two loads have already been
23869 issued in this cycle, so we increase the priority of the first store
23870 in the ready list to increase it's likelihood of being chosen first
23873 - If the pendulum < -2 or > 2, then do nothing.
23875 Note: This code covers the most common scenarios. There exist non
23876 load/store instructions which make use of the LSU and which
23877 would need to be accounted for to strictly model the behavior
23878 of the machine. Those instructions are currently unaccounted
23879 for to help minimize compile time overhead of this code.
23881 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23887 if (is_store_insn (last_scheduled_insn))
23888 /* Issuing a store, swing the load_store_pendulum to the left */
23889 load_store_pendulum--;
23890 else if (is_load_insn (last_scheduled_insn))
23891 /* Issuing a load, swing the load_store_pendulum to the right */
23892 load_store_pendulum++;
23894 return cached_can_issue_more;
23896 /* If the pendulum is balanced, or there is only one instruction on
23897 the ready list, then all is well, so return. */
23898 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23899 return cached_can_issue_more;
23901 if (load_store_pendulum == 1)
23903 /* A load has been issued in this cycle. Scan the ready list
23904 for another load to issue with it */
23909 if (is_load_insn (ready[pos]))
23911 /* Found a load. Move it to the head of the ready list,
23912 and adjust it's priority so that it is more likely to
23915 for (i=pos; i<*pn_ready-1; i++)
23916 ready[i] = ready[i + 1];
23917 ready[*pn_ready-1] = tmp;
23919 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23920 INSN_PRIORITY (tmp)++;
23926 else if (load_store_pendulum == -2)
23928 /* Two stores have been issued in this cycle. Increase the
23929 priority of the first load in the ready list to favor it for
23930 issuing in the next cycle. */
23935 if (is_load_insn (ready[pos])
23937 && INSN_PRIORITY_KNOWN (ready[pos]))
23939 INSN_PRIORITY (ready[pos])++;
23941 /* Adjust the pendulum to account for the fact that a load
23942 was found and increased in priority. This is to prevent
23943 increasing the priority of multiple loads */
23944 load_store_pendulum--;
23951 else if (load_store_pendulum == -1)
23953 /* A store has been issued in this cycle. Scan the ready list for
23954 another store to issue with it, preferring a store to an adjacent
23956 int first_store_pos = -1;
23962 if (is_store_insn (ready[pos]))
23964 /* Maintain the index of the first store found on the
23966 if (first_store_pos == -1)
23967 first_store_pos = pos;
23969 if (is_store_insn (last_scheduled_insn)
23970 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23972 /* Found an adjacent store. Move it to the head of the
23973 ready list, and adjust it's priority so that it is
23974 more likely to stay there */
23976 for (i=pos; i<*pn_ready-1; i++)
23977 ready[i] = ready[i + 1];
23978 ready[*pn_ready-1] = tmp;
23980 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23981 INSN_PRIORITY (tmp)++;
23983 first_store_pos = -1;
23991 if (first_store_pos >= 0)
23993 /* An adjacent store wasn't found, but a non-adjacent store was,
23994 so move the non-adjacent store to the front of the ready
23995 list, and adjust its priority so that it is more likely to
23997 tmp = ready[first_store_pos];
23998 for (i=first_store_pos; i<*pn_ready-1; i++)
23999 ready[i] = ready[i + 1];
24000 ready[*pn_ready-1] = tmp;
24001 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24002 INSN_PRIORITY (tmp)++;
24005 else if (load_store_pendulum == 2)
24007 /* Two loads have been issued in this cycle. Increase the priority
24008 of the first store in the ready list to favor it for issuing in
24014 if (is_store_insn (ready[pos])
24016 && INSN_PRIORITY_KNOWN (ready[pos]))
24018 INSN_PRIORITY (ready[pos])++;
24020 /* Adjust the pendulum to account for the fact that a store
24021 was found and increased in priority. This is to prevent
24022 increasing the priority of multiple stores */
24023 load_store_pendulum++;
24032 return cached_can_issue_more;
24035 /* Return whether the presence of INSN causes a dispatch group termination
24036 of group WHICH_GROUP.
24038 If WHICH_GROUP == current_group, this function will return true if INSN
24039 causes the termination of the current group (i.e, the dispatch group to
24040 which INSN belongs). This means that INSN will be the last insn in the
24041 group it belongs to.
24043 If WHICH_GROUP == previous_group, this function will return true if INSN
24044 causes the termination of the previous group (i.e, the dispatch group that
24045 precedes the group to which INSN belongs). This means that INSN will be
24046 the first insn in the group it belongs to). */
24049 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24056 first = insn_must_be_first_in_group (insn);
24057 last = insn_must_be_last_in_group (insn);
24062 if (which_group == current_group)
24064 else if (which_group == previous_group)
24072 insn_must_be_first_in_group (rtx insn)
24074 enum attr_type type;
24077 || GET_CODE (insn) == NOTE
24078 || DEBUG_INSN_P (insn)
24079 || GET_CODE (PATTERN (insn)) == USE
24080 || GET_CODE (PATTERN (insn)) == CLOBBER)
24083 switch (rs6000_cpu)
24085 case PROCESSOR_POWER5:
24086 if (is_cracked_insn (insn))
24088 case PROCESSOR_POWER4:
24089 if (is_microcoded_insn (insn))
24092 if (!rs6000_sched_groups)
24095 type = get_attr_type (insn);
24102 case TYPE_DELAYED_CR:
24103 case TYPE_CR_LOGICAL:
24117 case PROCESSOR_POWER6:
24118 type = get_attr_type (insn);
24122 case TYPE_INSERT_DWORD:
24126 case TYPE_VAR_SHIFT_ROTATE:
24133 case TYPE_INSERT_WORD:
24134 case TYPE_DELAYED_COMPARE:
24135 case TYPE_IMUL_COMPARE:
24136 case TYPE_LMUL_COMPARE:
24137 case TYPE_FPCOMPARE:
24148 case TYPE_LOAD_EXT_UX:
24150 case TYPE_STORE_UX:
24151 case TYPE_FPLOAD_U:
24152 case TYPE_FPLOAD_UX:
24153 case TYPE_FPSTORE_U:
24154 case TYPE_FPSTORE_UX:
24160 case PROCESSOR_POWER7:
24161 type = get_attr_type (insn);
24165 case TYPE_CR_LOGICAL:
24172 case TYPE_DELAYED_COMPARE:
24173 case TYPE_VAR_DELAYED_COMPARE:
24179 case TYPE_LOAD_EXT:
24180 case TYPE_LOAD_EXT_U:
24181 case TYPE_LOAD_EXT_UX:
24183 case TYPE_STORE_UX:
24184 case TYPE_FPLOAD_U:
24185 case TYPE_FPLOAD_UX:
24186 case TYPE_FPSTORE_U:
24187 case TYPE_FPSTORE_UX:
24203 insn_must_be_last_in_group (rtx insn)
24205 enum attr_type type;
24208 || GET_CODE (insn) == NOTE
24209 || DEBUG_INSN_P (insn)
24210 || GET_CODE (PATTERN (insn)) == USE
24211 || GET_CODE (PATTERN (insn)) == CLOBBER)
24214 switch (rs6000_cpu) {
24215 case PROCESSOR_POWER4:
24216 case PROCESSOR_POWER5:
24217 if (is_microcoded_insn (insn))
24220 if (is_branch_slot_insn (insn))
24224 case PROCESSOR_POWER6:
24225 type = get_attr_type (insn);
24232 case TYPE_VAR_SHIFT_ROTATE:
24239 case TYPE_DELAYED_COMPARE:
24240 case TYPE_IMUL_COMPARE:
24241 case TYPE_LMUL_COMPARE:
24242 case TYPE_FPCOMPARE:
24256 case PROCESSOR_POWER7:
24257 type = get_attr_type (insn);
24265 case TYPE_LOAD_EXT_U:
24266 case TYPE_LOAD_EXT_UX:
24267 case TYPE_STORE_UX:
24280 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24281 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24284 is_costly_group (rtx *group_insns, rtx next_insn)
24287 int issue_rate = rs6000_issue_rate ();
24289 for (i = 0; i < issue_rate; i++)
24291 sd_iterator_def sd_it;
24293 rtx insn = group_insns[i];
24298 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24300 rtx next = DEP_CON (dep);
24302 if (next == next_insn
24303 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24311 /* Utility of the function redefine_groups.
24312 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24313 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24314 to keep it "far" (in a separate group) from GROUP_INSNS, following
24315 one of the following schemes, depending on the value of the flag
24316 -minsert_sched_nops = X:
24317 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24318 in order to force NEXT_INSN into a separate group.
24319 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24320 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24321 insertion (has a group just ended, how many vacant issue slots remain in the
24322 last group, and how many dispatch groups were encountered so far). */
24325 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24326 rtx next_insn, bool *group_end, int can_issue_more,
24331 int issue_rate = rs6000_issue_rate ();
24332 bool end = *group_end;
24335 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24336 return can_issue_more;
24338 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24339 return can_issue_more;
24341 force = is_costly_group (group_insns, next_insn);
24343 return can_issue_more;
24345 if (sched_verbose > 6)
24346 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24347 *group_count ,can_issue_more);
24349 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24352 can_issue_more = 0;
24354 /* Since only a branch can be issued in the last issue_slot, it is
24355 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24356 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24357 in this case the last nop will start a new group and the branch
24358 will be forced to the new group. */
24359 if (can_issue_more && !is_branch_slot_insn (next_insn))
24362 while (can_issue_more > 0)
24365 emit_insn_before (nop, next_insn);
24373 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24375 int n_nops = rs6000_sched_insert_nops;
24377 /* Nops can't be issued from the branch slot, so the effective
24378 issue_rate for nops is 'issue_rate - 1'. */
24379 if (can_issue_more == 0)
24380 can_issue_more = issue_rate;
24382 if (can_issue_more == 0)
24384 can_issue_more = issue_rate - 1;
24387 for (i = 0; i < issue_rate; i++)
24389 group_insns[i] = 0;
24396 emit_insn_before (nop, next_insn);
24397 if (can_issue_more == issue_rate - 1) /* new group begins */
24400 if (can_issue_more == 0)
24402 can_issue_more = issue_rate - 1;
24405 for (i = 0; i < issue_rate; i++)
24407 group_insns[i] = 0;
24413 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24416 /* Is next_insn going to start a new group? */
24419 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24420 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24421 || (can_issue_more < issue_rate &&
24422 insn_terminates_group_p (next_insn, previous_group)));
24423 if (*group_end && end)
24426 if (sched_verbose > 6)
24427 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24428 *group_count, can_issue_more);
24429 return can_issue_more;
24432 return can_issue_more;
24435 /* This function tries to synch the dispatch groups that the compiler "sees"
24436 with the dispatch groups that the processor dispatcher is expected to
24437 form in practice. It tries to achieve this synchronization by forcing the
24438 estimated processor grouping on the compiler (as opposed to the function
24439 'pad_goups' which tries to force the scheduler's grouping on the processor).
24441 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24442 examines the (estimated) dispatch groups that will be formed by the processor
24443 dispatcher. It marks these group boundaries to reflect the estimated
24444 processor grouping, overriding the grouping that the scheduler had marked.
24445 Depending on the value of the flag '-minsert-sched-nops' this function can
24446 force certain insns into separate groups or force a certain distance between
24447 them by inserting nops, for example, if there exists a "costly dependence"
24450 The function estimates the group boundaries that the processor will form as
24451 follows: It keeps track of how many vacant issue slots are available after
24452 each insn. A subsequent insn will start a new group if one of the following
24454 - no more vacant issue slots remain in the current dispatch group.
24455 - only the last issue slot, which is the branch slot, is vacant, but the next
24456 insn is not a branch.
24457 - only the last 2 or less issue slots, including the branch slot, are vacant,
24458 which means that a cracked insn (which occupies two issue slots) can't be
24459 issued in this group.
24460 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24461 start a new group. */
24464 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24466 rtx insn, next_insn;
24468 int can_issue_more;
24471 int group_count = 0;
24475 issue_rate = rs6000_issue_rate ();
24476 group_insns = XALLOCAVEC (rtx, issue_rate);
24477 for (i = 0; i < issue_rate; i++)
24479 group_insns[i] = 0;
24481 can_issue_more = issue_rate;
24483 insn = get_next_active_insn (prev_head_insn, tail);
24486 while (insn != NULL_RTX)
24488 slot = (issue_rate - can_issue_more);
24489 group_insns[slot] = insn;
24491 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24492 if (insn_terminates_group_p (insn, current_group))
24493 can_issue_more = 0;
24495 next_insn = get_next_active_insn (insn, tail);
24496 if (next_insn == NULL_RTX)
24497 return group_count + 1;
24499 /* Is next_insn going to start a new group? */
24501 = (can_issue_more == 0
24502 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24503 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24504 || (can_issue_more < issue_rate &&
24505 insn_terminates_group_p (next_insn, previous_group)));
24507 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24508 next_insn, &group_end, can_issue_more,
24514 can_issue_more = 0;
24515 for (i = 0; i < issue_rate; i++)
24517 group_insns[i] = 0;
24521 if (GET_MODE (next_insn) == TImode && can_issue_more)
24522 PUT_MODE (next_insn, VOIDmode);
24523 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24524 PUT_MODE (next_insn, TImode);
24527 if (can_issue_more == 0)
24528 can_issue_more = issue_rate;
24531 return group_count;
24534 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24535 dispatch group boundaries that the scheduler had marked. Pad with nops
24536 any dispatch groups which have vacant issue slots, in order to force the
24537 scheduler's grouping on the processor dispatcher. The function
24538 returns the number of dispatch groups found. */
24541 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24543 rtx insn, next_insn;
24546 int can_issue_more;
24548 int group_count = 0;
24550 /* Initialize issue_rate. */
24551 issue_rate = rs6000_issue_rate ();
24552 can_issue_more = issue_rate;
24554 insn = get_next_active_insn (prev_head_insn, tail);
24555 next_insn = get_next_active_insn (insn, tail);
24557 while (insn != NULL_RTX)
24560 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24562 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24564 if (next_insn == NULL_RTX)
24569 /* If the scheduler had marked group termination at this location
24570 (between insn and next_insn), and neither insn nor next_insn will
24571 force group termination, pad the group with nops to force group
24574 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24575 && !insn_terminates_group_p (insn, current_group)
24576 && !insn_terminates_group_p (next_insn, previous_group))
24578 if (!is_branch_slot_insn (next_insn))
24581 while (can_issue_more)
24584 emit_insn_before (nop, next_insn);
24589 can_issue_more = issue_rate;
24594 next_insn = get_next_active_insn (insn, tail);
24597 return group_count;
24600 /* We're beginning a new block. Initialize data structures as necessary. */
24603 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24604 int sched_verbose ATTRIBUTE_UNUSED,
24605 int max_ready ATTRIBUTE_UNUSED)
24607 last_scheduled_insn = NULL_RTX;
24608 load_store_pendulum = 0;
24611 /* The following function is called at the end of scheduling BB.
24612 After reload, it inserts nops at insn group bundling. */
24615 rs6000_sched_finish (FILE *dump, int sched_verbose)
24620 fprintf (dump, "=== Finishing schedule.\n");
24622 if (reload_completed && rs6000_sched_groups)
24624 /* Do not run sched_finish hook when selective scheduling enabled. */
24625 if (sel_sched_p ())
24628 if (rs6000_sched_insert_nops == sched_finish_none)
24631 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24632 n_groups = pad_groups (dump, sched_verbose,
24633 current_sched_info->prev_head,
24634 current_sched_info->next_tail);
24636 n_groups = redefine_groups (dump, sched_verbose,
24637 current_sched_info->prev_head,
24638 current_sched_info->next_tail);
24640 if (sched_verbose >= 6)
24642 fprintf (dump, "ngroups = %d\n", n_groups);
24643 print_rtl (dump, current_sched_info->prev_head);
24644 fprintf (dump, "Done finish_sched\n");
24649 struct _rs6000_sched_context
24651 short cached_can_issue_more;
24652 rtx last_scheduled_insn;
24653 int load_store_pendulum;
24656 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24657 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24659 /* Allocate store for new scheduling context. */
24661 rs6000_alloc_sched_context (void)
24663 return xmalloc (sizeof (rs6000_sched_context_def));
24666 /* If CLEAN_P is true then initializes _SC with clean data,
24667 and from the global context otherwise. */
24669 rs6000_init_sched_context (void *_sc, bool clean_p)
24671 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24675 sc->cached_can_issue_more = 0;
24676 sc->last_scheduled_insn = NULL_RTX;
24677 sc->load_store_pendulum = 0;
24681 sc->cached_can_issue_more = cached_can_issue_more;
24682 sc->last_scheduled_insn = last_scheduled_insn;
24683 sc->load_store_pendulum = load_store_pendulum;
24687 /* Sets the global scheduling context to the one pointed to by _SC. */
24689 rs6000_set_sched_context (void *_sc)
24691 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24693 gcc_assert (sc != NULL);
24695 cached_can_issue_more = sc->cached_can_issue_more;
24696 last_scheduled_insn = sc->last_scheduled_insn;
24697 load_store_pendulum = sc->load_store_pendulum;
24702 rs6000_free_sched_context (void *_sc)
24704 gcc_assert (_sc != NULL);
24710 /* Length in units of the trampoline for entering a nested function. */
24713 rs6000_trampoline_size (void)
24717 switch (DEFAULT_ABI)
24720 gcc_unreachable ();
24723 ret = (TARGET_32BIT) ? 12 : 24;
24728 ret = (TARGET_32BIT) ? 40 : 48;
24735 /* Emit RTL insns to initialize the variable parts of a trampoline.
24736 FNADDR is an RTX for the address of the function's pure code.
24737 CXT is an RTX for the static chain value for the function. */
24740 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24742 int regsize = (TARGET_32BIT) ? 4 : 8;
24743 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24744 rtx ctx_reg = force_reg (Pmode, cxt);
24745 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24747 switch (DEFAULT_ABI)
24750 gcc_unreachable ();
24752 /* Under AIX, just build the 3 word function descriptor */
24755 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24756 rtx fn_reg = gen_reg_rtx (Pmode);
24757 rtx toc_reg = gen_reg_rtx (Pmode);
24759 /* Macro to shorten the code expansions below. */
24760 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24762 m_tramp = replace_equiv_address (m_tramp, addr);
24764 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24765 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24766 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24767 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24768 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24774 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24777 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24778 LCT_NORMAL, VOIDmode, 4,
24780 GEN_INT (rs6000_trampoline_size ()), SImode,
24788 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24789 identifier as an argument, so the front end shouldn't look it up. */
24792 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24794 return is_attribute_p ("altivec", attr_id);
24797 /* Handle the "altivec" attribute. The attribute may have
24798 arguments as follows:
24800 __attribute__((altivec(vector__)))
24801 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24802 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24804 and may appear more than once (e.g., 'vector bool char') in a
24805 given declaration. */
24808 rs6000_handle_altivec_attribute (tree *node,
24809 tree name ATTRIBUTE_UNUSED,
24811 int flags ATTRIBUTE_UNUSED,
24812 bool *no_add_attrs)
24814 tree type = *node, result = NULL_TREE;
24815 enum machine_mode mode;
24818 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24819 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24820 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24823 while (POINTER_TYPE_P (type)
24824 || TREE_CODE (type) == FUNCTION_TYPE
24825 || TREE_CODE (type) == METHOD_TYPE
24826 || TREE_CODE (type) == ARRAY_TYPE)
24827 type = TREE_TYPE (type);
24829 mode = TYPE_MODE (type);
24831 /* Check for invalid AltiVec type qualifiers. */
24832 if (type == long_double_type_node)
24833 error ("use of %<long double%> in AltiVec types is invalid");
24834 else if (type == boolean_type_node)
24835 error ("use of boolean types in AltiVec types is invalid");
24836 else if (TREE_CODE (type) == COMPLEX_TYPE)
24837 error ("use of %<complex%> in AltiVec types is invalid");
24838 else if (DECIMAL_FLOAT_MODE_P (mode))
24839 error ("use of decimal floating point types in AltiVec types is invalid");
24840 else if (!TARGET_VSX)
24842 if (type == long_unsigned_type_node || type == long_integer_type_node)
24845 error ("use of %<long%> in AltiVec types is invalid for "
24846 "64-bit code without -mvsx");
24847 else if (rs6000_warn_altivec_long)
24848 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24851 else if (type == long_long_unsigned_type_node
24852 || type == long_long_integer_type_node)
24853 error ("use of %<long long%> in AltiVec types is invalid without "
24855 else if (type == double_type_node)
24856 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24859 switch (altivec_type)
24862 unsigned_p = TYPE_UNSIGNED (type);
24866 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24869 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24872 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24875 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24877 case SFmode: result = V4SF_type_node; break;
24878 case DFmode: result = V2DF_type_node; break;
24879 /* If the user says 'vector int bool', we may be handed the 'bool'
24880 attribute _before_ the 'vector' attribute, and so select the
24881 proper type in the 'b' case below. */
24882 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24883 case V2DImode: case V2DFmode:
24891 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24892 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24893 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24894 case QImode: case V16QImode: result = bool_V16QI_type_node;
24901 case V8HImode: result = pixel_V8HI_type_node;
24907 /* Propagate qualifiers attached to the element type
24908 onto the vector type. */
24909 if (result && result != type && TYPE_QUALS (type))
24910 result = build_qualified_type (result, TYPE_QUALS (type));
24912 *no_add_attrs = true; /* No need to hang on to the attribute. */
24915 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24920 /* AltiVec defines four built-in scalar types that serve as vector
24921 elements; we must teach the compiler how to mangle them. */
24923 static const char *
24924 rs6000_mangle_type (const_tree type)
24926 type = TYPE_MAIN_VARIANT (type);
24928 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24929 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24932 if (type == bool_char_type_node) return "U6__boolc";
24933 if (type == bool_short_type_node) return "U6__bools";
24934 if (type == pixel_type_node) return "u7__pixel";
24935 if (type == bool_int_type_node) return "U6__booli";
24936 if (type == bool_long_type_node) return "U6__booll";
24938 /* Mangle IBM extended float long double as `g' (__float128) on
24939 powerpc*-linux where long-double-64 previously was the default. */
24940 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24942 && TARGET_LONG_DOUBLE_128
24943 && !TARGET_IEEEQUAD)
24946 /* For all other types, use normal C++ mangling. */
24950 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24951 struct attribute_spec.handler. */
24954 rs6000_handle_longcall_attribute (tree *node, tree name,
24955 tree args ATTRIBUTE_UNUSED,
24956 int flags ATTRIBUTE_UNUSED,
24957 bool *no_add_attrs)
24959 if (TREE_CODE (*node) != FUNCTION_TYPE
24960 && TREE_CODE (*node) != FIELD_DECL
24961 && TREE_CODE (*node) != TYPE_DECL)
24963 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24965 *no_add_attrs = true;
24971 /* Set longcall attributes on all functions declared when
24972 rs6000_default_long_calls is true. */
24974 rs6000_set_default_type_attributes (tree type)
24976 if (rs6000_default_long_calls
24977 && (TREE_CODE (type) == FUNCTION_TYPE
24978 || TREE_CODE (type) == METHOD_TYPE))
24979 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24981 TYPE_ATTRIBUTES (type));
24984 darwin_set_default_type_attributes (type);
24988 /* Return a reference suitable for calling a function with the
24989 longcall attribute. */
24992 rs6000_longcall_ref (rtx call_ref)
24994 const char *call_name;
24997 if (GET_CODE (call_ref) != SYMBOL_REF)
25000 /* System V adds '.' to the internal name, so skip them. */
25001 call_name = XSTR (call_ref, 0);
25002 if (*call_name == '.')
25004 while (*call_name == '.')
25007 node = get_identifier (call_name);
25008 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25011 return force_reg (Pmode, call_ref);
25014 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25015 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25018 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25019 struct attribute_spec.handler. */
25021 rs6000_handle_struct_attribute (tree *node, tree name,
25022 tree args ATTRIBUTE_UNUSED,
25023 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25026 if (DECL_P (*node))
25028 if (TREE_CODE (*node) == TYPE_DECL)
25029 type = &TREE_TYPE (*node);
25034 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25035 || TREE_CODE (*type) == UNION_TYPE)))
25037 warning (OPT_Wattributes, "%qE attribute ignored", name);
25038 *no_add_attrs = true;
25041 else if ((is_attribute_p ("ms_struct", name)
25042 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25043 || ((is_attribute_p ("gcc_struct", name)
25044 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25046 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25048 *no_add_attrs = true;
25055 rs6000_ms_bitfield_layout_p (const_tree record_type)
25057 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25058 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25059 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25062 #ifdef USING_ELFOS_H
25064 /* A get_unnamed_section callback, used for switching to toc_section. */
25067 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25069 if (DEFAULT_ABI == ABI_AIX
25070 && TARGET_MINIMAL_TOC
25071 && !TARGET_RELOCATABLE)
25073 if (!toc_initialized)
25075 toc_initialized = 1;
25076 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25077 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25078 fprintf (asm_out_file, "\t.tc ");
25079 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25080 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25081 fprintf (asm_out_file, "\n");
25083 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25084 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25085 fprintf (asm_out_file, " = .+32768\n");
25088 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25090 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25091 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25094 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25095 if (!toc_initialized)
25097 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25098 fprintf (asm_out_file, " = .+32768\n");
25099 toc_initialized = 1;
25104 /* Implement TARGET_ASM_INIT_SECTIONS. */
25107 rs6000_elf_asm_init_sections (void)
25110 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25113 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25114 SDATA2_SECTION_ASM_OP);
25117 /* Implement TARGET_SELECT_RTX_SECTION. */
25120 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25121 unsigned HOST_WIDE_INT align)
25123 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25124 return toc_section;
25126 return default_elf_select_rtx_section (mode, x, align);
25129 /* For a SYMBOL_REF, set generic flags and then perform some
25130 target-specific processing.
25132 When the AIX ABI is requested on a non-AIX system, replace the
25133 function name with the real name (with a leading .) rather than the
25134 function descriptor name. This saves a lot of overriding code to
25135 read the prefixes. */
25138 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25140 default_encode_section_info (decl, rtl, first);
25143 && TREE_CODE (decl) == FUNCTION_DECL
25145 && DEFAULT_ABI == ABI_AIX)
25147 rtx sym_ref = XEXP (rtl, 0);
25148 size_t len = strlen (XSTR (sym_ref, 0));
25149 char *str = XALLOCAVEC (char, len + 2);
25151 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25152 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25157 compare_section_name (const char *section, const char *templ)
25161 len = strlen (templ);
25162 return (strncmp (section, templ, len) == 0
25163 && (section[len] == 0 || section[len] == '.'));
25167 rs6000_elf_in_small_data_p (const_tree decl)
25169 if (rs6000_sdata == SDATA_NONE)
25172 /* We want to merge strings, so we never consider them small data. */
25173 if (TREE_CODE (decl) == STRING_CST)
25176 /* Functions are never in the small data area. */
25177 if (TREE_CODE (decl) == FUNCTION_DECL)
25180 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25182 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25183 if (compare_section_name (section, ".sdata")
25184 || compare_section_name (section, ".sdata2")
25185 || compare_section_name (section, ".gnu.linkonce.s")
25186 || compare_section_name (section, ".sbss")
25187 || compare_section_name (section, ".sbss2")
25188 || compare_section_name (section, ".gnu.linkonce.sb")
25189 || strcmp (section, ".PPC.EMB.sdata0") == 0
25190 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25195 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25198 && size <= g_switch_value
25199 /* If it's not public, and we're not going to reference it there,
25200 there's no need to put it in the small data section. */
25201 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25208 #endif /* USING_ELFOS_H */
25210 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25213 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25215 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25218 /* Return a REG that occurs in ADDR with coefficient 1.
25219 ADDR can be effectively incremented by incrementing REG.
25221 r0 is special and we must not select it as an address
25222 register by this routine since our caller will try to
25223 increment the returned register via an "la" instruction. */
25226 find_addr_reg (rtx addr)
25228 while (GET_CODE (addr) == PLUS)
25230 if (GET_CODE (XEXP (addr, 0)) == REG
25231 && REGNO (XEXP (addr, 0)) != 0)
25232 addr = XEXP (addr, 0);
25233 else if (GET_CODE (XEXP (addr, 1)) == REG
25234 && REGNO (XEXP (addr, 1)) != 0)
25235 addr = XEXP (addr, 1);
25236 else if (CONSTANT_P (XEXP (addr, 0)))
25237 addr = XEXP (addr, 1);
25238 else if (CONSTANT_P (XEXP (addr, 1)))
25239 addr = XEXP (addr, 0);
25241 gcc_unreachable ();
25243 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25248 rs6000_fatal_bad_address (rtx op)
25250 fatal_insn ("bad address", op);
25255 typedef struct branch_island_d {
25256 tree function_name;
25261 DEF_VEC_O(branch_island);
25262 DEF_VEC_ALLOC_O(branch_island,gc);
25264 static VEC(branch_island,gc) *branch_islands;
25266 /* Remember to generate a branch island for far calls to the given
25270 add_compiler_branch_island (tree label_name, tree function_name,
25273 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25275 bi->function_name = function_name;
25276 bi->label_name = label_name;
25277 bi->line_number = line_number;
25280 /* Generate far-jump branch islands for everything recorded in
25281 branch_islands. Invoked immediately after the last instruction of
25282 the epilogue has been emitted; the branch islands must be appended
25283 to, and contiguous with, the function body. Mach-O stubs are
25284 generated in machopic_output_stub(). */
25287 macho_branch_islands (void)
25291 while (!VEC_empty (branch_island, branch_islands))
25293 branch_island *bi = VEC_last (branch_island, branch_islands);
25294 const char *label = IDENTIFIER_POINTER (bi->label_name);
25295 const char *name = IDENTIFIER_POINTER (bi->function_name);
25296 char name_buf[512];
25297 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25298 if (name[0] == '*' || name[0] == '&')
25299 strcpy (name_buf, name+1);
25303 strcpy (name_buf+1, name);
25305 strcpy (tmp_buf, "\n");
25306 strcat (tmp_buf, label);
25307 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25308 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25309 dbxout_stabd (N_SLINE, bi->line_number);
25310 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25313 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25314 strcat (tmp_buf, label);
25315 strcat (tmp_buf, "_pic\n");
25316 strcat (tmp_buf, label);
25317 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25319 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25320 strcat (tmp_buf, name_buf);
25321 strcat (tmp_buf, " - ");
25322 strcat (tmp_buf, label);
25323 strcat (tmp_buf, "_pic)\n");
25325 strcat (tmp_buf, "\tmtlr r0\n");
25327 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25328 strcat (tmp_buf, name_buf);
25329 strcat (tmp_buf, " - ");
25330 strcat (tmp_buf, label);
25331 strcat (tmp_buf, "_pic)\n");
25333 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25337 strcat (tmp_buf, ":\nlis r12,hi16(");
25338 strcat (tmp_buf, name_buf);
25339 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25340 strcat (tmp_buf, name_buf);
25341 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25343 output_asm_insn (tmp_buf, 0);
25344 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25345 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25346 dbxout_stabd (N_SLINE, bi->line_number);
25347 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25348 VEC_pop (branch_island, branch_islands);
25352 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25353 already there or not. */
25356 no_previous_def (tree function_name)
25361 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25362 if (function_name == bi->function_name)
25367 /* GET_PREV_LABEL gets the label name from the previous definition of
25371 get_prev_label (tree function_name)
25376 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25377 if (function_name == bi->function_name)
25378 return bi->label_name;
25382 /* INSN is either a function call or a millicode call. It may have an
25383 unconditional jump in its delay slot.
25385 CALL_DEST is the routine we are calling. */
25388 output_call (rtx insn, rtx *operands, int dest_operand_number,
25389 int cookie_operand_number)
25391 static char buf[256];
25392 if (darwin_emit_branch_islands
25393 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25394 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25397 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25399 if (no_previous_def (funname))
25401 rtx label_rtx = gen_label_rtx ();
25402 char *label_buf, temp_buf[256];
25403 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25404 CODE_LABEL_NUMBER (label_rtx));
25405 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25406 labelname = get_identifier (label_buf);
25407 add_compiler_branch_island (labelname, funname, insn_line (insn));
25410 labelname = get_prev_label (funname);
25412 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25413 instruction will reach 'foo', otherwise link as 'bl L42'".
25414 "L42" should be a 'branch island', that will do a far jump to
25415 'foo'. Branch islands are generated in
25416 macho_branch_islands(). */
25417 sprintf (buf, "jbsr %%z%d,%.246s",
25418 dest_operand_number, IDENTIFIER_POINTER (labelname));
25421 sprintf (buf, "bl %%z%d", dest_operand_number);
25425 /* Generate PIC and indirect symbol stubs. */
25428 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25430 unsigned int length;
25431 char *symbol_name, *lazy_ptr_name;
25432 char *local_label_0;
25433 static int label = 0;
25435 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25436 symb = (*targetm.strip_name_encoding) (symb);
25439 length = strlen (symb);
25440 symbol_name = XALLOCAVEC (char, length + 32);
25441 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25443 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25444 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25447 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25449 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25453 fprintf (file, "\t.align 5\n");
25455 fprintf (file, "%s:\n", stub);
25456 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25459 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25460 sprintf (local_label_0, "\"L%011d$spb\"", label);
25462 fprintf (file, "\tmflr r0\n");
25463 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25464 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25465 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25466 lazy_ptr_name, local_label_0);
25467 fprintf (file, "\tmtlr r0\n");
25468 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25469 (TARGET_64BIT ? "ldu" : "lwzu"),
25470 lazy_ptr_name, local_label_0);
25471 fprintf (file, "\tmtctr r12\n");
25472 fprintf (file, "\tbctr\n");
25476 fprintf (file, "\t.align 4\n");
25478 fprintf (file, "%s:\n", stub);
25479 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25481 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25482 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25483 (TARGET_64BIT ? "ldu" : "lwzu"),
25485 fprintf (file, "\tmtctr r12\n");
25486 fprintf (file, "\tbctr\n");
25489 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25490 fprintf (file, "%s:\n", lazy_ptr_name);
25491 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25492 fprintf (file, "%sdyld_stub_binding_helper\n",
25493 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25496 /* Legitimize PIC addresses. If the address is already
25497 position-independent, we return ORIG. Newly generated
25498 position-independent addresses go into a reg. This is REG if non
25499 zero, otherwise we allocate register(s) as necessary. */
25501 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25504 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25509 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25510 reg = gen_reg_rtx (Pmode);
25512 if (GET_CODE (orig) == CONST)
25516 if (GET_CODE (XEXP (orig, 0)) == PLUS
25517 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25520 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25522 /* Use a different reg for the intermediate value, as
25523 it will be marked UNCHANGING. */
25524 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25525 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25528 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25531 if (GET_CODE (offset) == CONST_INT)
25533 if (SMALL_INT (offset))
25534 return plus_constant (base, INTVAL (offset));
25535 else if (! reload_in_progress && ! reload_completed)
25536 offset = force_reg (Pmode, offset);
25539 rtx mem = force_const_mem (Pmode, orig);
25540 return machopic_legitimize_pic_address (mem, Pmode, reg);
25543 return gen_rtx_PLUS (Pmode, base, offset);
25546 /* Fall back on generic machopic code. */
25547 return machopic_legitimize_pic_address (orig, mode, reg);
25550 /* Output a .machine directive for the Darwin assembler, and call
25551 the generic start_file routine. */
25554 rs6000_darwin_file_start (void)
25556 static const struct
25562 { "ppc64", "ppc64", MASK_64BIT },
25563 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25564 { "power4", "ppc970", 0 },
25565 { "G5", "ppc970", 0 },
25566 { "7450", "ppc7450", 0 },
25567 { "7400", "ppc7400", MASK_ALTIVEC },
25568 { "G4", "ppc7400", 0 },
25569 { "750", "ppc750", 0 },
25570 { "740", "ppc750", 0 },
25571 { "G3", "ppc750", 0 },
25572 { "604e", "ppc604e", 0 },
25573 { "604", "ppc604", 0 },
25574 { "603e", "ppc603", 0 },
25575 { "603", "ppc603", 0 },
25576 { "601", "ppc601", 0 },
25577 { NULL, "ppc", 0 } };
25578 const char *cpu_id = "";
25581 rs6000_file_start ();
25582 darwin_file_start ();
25584 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25586 if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0')
25587 cpu_id = rs6000_default_cpu;
25589 if (global_options_set.x_rs6000_cpu_index)
25590 cpu_id = processor_target_table[rs6000_cpu_index].name;
25592 /* Look through the mapping array. Pick the first name that either
25593 matches the argument, has a bit set in IF_SET that is also set
25594 in the target flags, or has a NULL name. */
25597 while (mapping[i].arg != NULL
25598 && strcmp (mapping[i].arg, cpu_id) != 0
25599 && (mapping[i].if_set & target_flags) == 0)
25602 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25605 #endif /* TARGET_MACHO */
25609 rs6000_elf_reloc_rw_mask (void)
25613 else if (DEFAULT_ABI == ABI_AIX)
25619 /* Record an element in the table of global constructors. SYMBOL is
25620 a SYMBOL_REF of the function to be called; PRIORITY is a number
25621 between 0 and MAX_INIT_PRIORITY.
25623 This differs from default_named_section_asm_out_constructor in
25624 that we have special handling for -mrelocatable. */
25627 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25629 const char *section = ".ctors";
25632 if (priority != DEFAULT_INIT_PRIORITY)
25634 sprintf (buf, ".ctors.%.5u",
25635 /* Invert the numbering so the linker puts us in the proper
25636 order; constructors are run from right to left, and the
25637 linker sorts in increasing order. */
25638 MAX_INIT_PRIORITY - priority);
25642 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25643 assemble_align (POINTER_SIZE);
25645 if (TARGET_RELOCATABLE)
25647 fputs ("\t.long (", asm_out_file);
25648 output_addr_const (asm_out_file, symbol);
25649 fputs (")@fixup\n", asm_out_file);
25652 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25656 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25658 const char *section = ".dtors";
25661 if (priority != DEFAULT_INIT_PRIORITY)
25663 sprintf (buf, ".dtors.%.5u",
25664 /* Invert the numbering so the linker puts us in the proper
25665 order; constructors are run from right to left, and the
25666 linker sorts in increasing order. */
25667 MAX_INIT_PRIORITY - priority);
25671 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25672 assemble_align (POINTER_SIZE);
25674 if (TARGET_RELOCATABLE)
25676 fputs ("\t.long (", asm_out_file);
25677 output_addr_const (asm_out_file, symbol);
25678 fputs (")@fixup\n", asm_out_file);
25681 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25685 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25689 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25690 ASM_OUTPUT_LABEL (file, name);
25691 fputs (DOUBLE_INT_ASM_OP, file);
25692 rs6000_output_function_entry (file, name);
25693 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25696 fputs ("\t.size\t", file);
25697 assemble_name (file, name);
25698 fputs (",24\n\t.type\t.", file);
25699 assemble_name (file, name);
25700 fputs (",@function\n", file);
25701 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25703 fputs ("\t.globl\t.", file);
25704 assemble_name (file, name);
25709 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25710 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25711 rs6000_output_function_entry (file, name);
25712 fputs (":\n", file);
25716 if (TARGET_RELOCATABLE
25717 && !TARGET_SECURE_PLT
25718 && (get_pool_size () != 0 || crtl->profile)
25723 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25725 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25726 fprintf (file, "\t.long ");
25727 assemble_name (file, buf);
25729 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25730 assemble_name (file, buf);
25734 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25735 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25737 if (DEFAULT_ABI == ABI_AIX)
25739 const char *desc_name, *orig_name;
25741 orig_name = (*targetm.strip_name_encoding) (name);
25742 desc_name = orig_name;
25743 while (*desc_name == '.')
25746 if (TREE_PUBLIC (decl))
25747 fprintf (file, "\t.globl %s\n", desc_name);
25749 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25750 fprintf (file, "%s:\n", desc_name);
25751 fprintf (file, "\t.long %s\n", orig_name);
25752 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25753 if (DEFAULT_ABI == ABI_AIX)
25754 fputs ("\t.long 0\n", file);
25755 fprintf (file, "\t.previous\n");
25757 ASM_OUTPUT_LABEL (file, name);
25761 rs6000_elf_file_end (void)
25763 #ifdef HAVE_AS_GNU_ATTRIBUTE
25764 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
25766 if (rs6000_passes_float)
25767 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
25768 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
25769 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
25771 if (rs6000_passes_vector)
25772 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
25773 (TARGET_ALTIVEC_ABI ? 2
25774 : TARGET_SPE_ABI ? 3
25776 if (rs6000_returns_struct)
25777 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
25778 aix_struct_return ? 2 : 1);
25781 #ifdef POWERPC_LINUX
25783 file_end_indicate_exec_stack ();
25790 rs6000_xcoff_asm_output_anchor (rtx symbol)
25794 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25795 SYMBOL_REF_BLOCK_OFFSET (symbol));
25796 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25800 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25802 fputs (GLOBAL_ASM_OP, stream);
25803 RS6000_OUTPUT_BASENAME (stream, name);
25804 putc ('\n', stream);
25807 /* A get_unnamed_decl callback, used for read-only sections. PTR
25808 points to the section string variable. */
25811 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25813 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25814 *(const char *const *) directive,
25815 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25818 /* Likewise for read-write sections. */
25821 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25823 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25824 *(const char *const *) directive,
25825 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25828 /* A get_unnamed_section callback, used for switching to toc_section. */
25831 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25833 if (TARGET_MINIMAL_TOC)
25835 /* toc_section is always selected at least once from
25836 rs6000_xcoff_file_start, so this is guaranteed to
25837 always be defined once and only once in each file. */
25838 if (!toc_initialized)
25840 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25841 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25842 toc_initialized = 1;
25844 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25845 (TARGET_32BIT ? "" : ",3"));
25848 fputs ("\t.toc\n", asm_out_file);
25851 /* Implement TARGET_ASM_INIT_SECTIONS. */
25854 rs6000_xcoff_asm_init_sections (void)
25856 read_only_data_section
25857 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25858 &xcoff_read_only_section_name);
25860 private_data_section
25861 = get_unnamed_section (SECTION_WRITE,
25862 rs6000_xcoff_output_readwrite_section_asm_op,
25863 &xcoff_private_data_section_name);
25865 read_only_private_data_section
25866 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25867 &xcoff_private_data_section_name);
25870 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25872 readonly_data_section = read_only_data_section;
25873 exception_section = data_section;
25877 rs6000_xcoff_reloc_rw_mask (void)
25883 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25884 tree decl ATTRIBUTE_UNUSED)
25887 static const char * const suffix[3] = { "PR", "RO", "RW" };
25889 if (flags & SECTION_CODE)
25891 else if (flags & SECTION_WRITE)
25896 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25897 (flags & SECTION_CODE) ? "." : "",
25898 name, suffix[smclass], flags & SECTION_ENTSIZE);
25902 rs6000_xcoff_select_section (tree decl, int reloc,
25903 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25905 if (decl_readonly_section (decl, reloc))
25907 if (TREE_PUBLIC (decl))
25908 return read_only_data_section;
25910 return read_only_private_data_section;
25914 if (TREE_PUBLIC (decl))
25915 return data_section;
25917 return private_data_section;
25922 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25926 /* Use select_section for private and uninitialized data. */
25927 if (!TREE_PUBLIC (decl)
25928 || DECL_COMMON (decl)
25929 || DECL_INITIAL (decl) == NULL_TREE
25930 || DECL_INITIAL (decl) == error_mark_node
25931 || (flag_zero_initialized_in_bss
25932 && initializer_zerop (DECL_INITIAL (decl))))
25935 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25936 name = (*targetm.strip_name_encoding) (name);
25937 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25940 /* Select section for constant in constant pool.
25942 On RS/6000, all constants are in the private read-only data area.
25943 However, if this is being placed in the TOC it must be output as a
25947 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25948 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25950 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25951 return toc_section;
25953 return read_only_private_data_section;
25956 /* Remove any trailing [DS] or the like from the symbol name. */
25958 static const char *
25959 rs6000_xcoff_strip_name_encoding (const char *name)
25964 len = strlen (name);
25965 if (name[len - 1] == ']')
25966 return ggc_alloc_string (name, len - 4);
25971 /* Section attributes. AIX is always PIC. */
25973 static unsigned int
25974 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25976 unsigned int align;
25977 unsigned int flags = default_section_type_flags (decl, name, reloc);
25979 /* Align to at least UNIT size. */
25980 if (flags & SECTION_CODE)
25981 align = MIN_UNITS_PER_WORD;
25983 /* Increase alignment of large objects if not already stricter. */
25984 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25985 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25986 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25988 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25991 /* Output at beginning of assembler file.
25993 Initialize the section names for the RS/6000 at this point.
25995 Specify filename, including full path, to assembler.
25997 We want to go into the TOC section so at least one .toc will be emitted.
25998 Also, in order to output proper .bs/.es pairs, we need at least one static
25999 [RW] section emitted.
26001 Finally, declare mcount when profiling to make the assembler happy. */
26004 rs6000_xcoff_file_start (void)
26006 rs6000_gen_section_name (&xcoff_bss_section_name,
26007 main_input_filename, ".bss_");
26008 rs6000_gen_section_name (&xcoff_private_data_section_name,
26009 main_input_filename, ".rw_");
26010 rs6000_gen_section_name (&xcoff_read_only_section_name,
26011 main_input_filename, ".ro_");
26013 fputs ("\t.file\t", asm_out_file);
26014 output_quoted_string (asm_out_file, main_input_filename);
26015 fputc ('\n', asm_out_file);
26016 if (write_symbols != NO_DEBUG)
26017 switch_to_section (private_data_section);
26018 switch_to_section (text_section);
26020 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26021 rs6000_file_start ();
26024 /* Output at end of assembler file.
26025 On the RS/6000, referencing data should automatically pull in text. */
26028 rs6000_xcoff_file_end (void)
26030 switch_to_section (text_section);
26031 fputs ("_section_.text:\n", asm_out_file);
26032 switch_to_section (data_section);
26033 fputs (TARGET_32BIT
26034 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26037 #endif /* TARGET_XCOFF */
26039 /* Compute a (partial) cost for rtx X. Return true if the complete
26040 cost has been computed, and false if subexpressions should be
26041 scanned. In either case, *TOTAL contains the cost result. */
26044 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26047 enum machine_mode mode = GET_MODE (x);
26051 /* On the RS/6000, if it is valid in the insn, it is free. */
26053 if (((outer_code == SET
26054 || outer_code == PLUS
26055 || outer_code == MINUS)
26056 && (satisfies_constraint_I (x)
26057 || satisfies_constraint_L (x)))
26058 || (outer_code == AND
26059 && (satisfies_constraint_K (x)
26061 ? satisfies_constraint_L (x)
26062 : satisfies_constraint_J (x))
26063 || mask_operand (x, mode)
26065 && mask64_operand (x, DImode))))
26066 || ((outer_code == IOR || outer_code == XOR)
26067 && (satisfies_constraint_K (x)
26069 ? satisfies_constraint_L (x)
26070 : satisfies_constraint_J (x))))
26071 || outer_code == ASHIFT
26072 || outer_code == ASHIFTRT
26073 || outer_code == LSHIFTRT
26074 || outer_code == ROTATE
26075 || outer_code == ROTATERT
26076 || outer_code == ZERO_EXTRACT
26077 || (outer_code == MULT
26078 && satisfies_constraint_I (x))
26079 || ((outer_code == DIV || outer_code == UDIV
26080 || outer_code == MOD || outer_code == UMOD)
26081 && exact_log2 (INTVAL (x)) >= 0)
26082 || (outer_code == COMPARE
26083 && (satisfies_constraint_I (x)
26084 || satisfies_constraint_K (x)))
26085 || ((outer_code == EQ || outer_code == NE)
26086 && (satisfies_constraint_I (x)
26087 || satisfies_constraint_K (x)
26089 ? satisfies_constraint_L (x)
26090 : satisfies_constraint_J (x))))
26091 || (outer_code == GTU
26092 && satisfies_constraint_I (x))
26093 || (outer_code == LTU
26094 && satisfies_constraint_P (x)))
26099 else if ((outer_code == PLUS
26100 && reg_or_add_cint_operand (x, VOIDmode))
26101 || (outer_code == MINUS
26102 && reg_or_sub_cint_operand (x, VOIDmode))
26103 || ((outer_code == SET
26104 || outer_code == IOR
26105 || outer_code == XOR)
26107 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26109 *total = COSTS_N_INSNS (1);
26115 if (mode == DImode && code == CONST_DOUBLE)
26117 if ((outer_code == IOR || outer_code == XOR)
26118 && CONST_DOUBLE_HIGH (x) == 0
26119 && (CONST_DOUBLE_LOW (x)
26120 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26125 else if ((outer_code == AND && and64_2_operand (x, DImode))
26126 || ((outer_code == SET
26127 || outer_code == IOR
26128 || outer_code == XOR)
26129 && CONST_DOUBLE_HIGH (x) == 0))
26131 *total = COSTS_N_INSNS (1);
26141 /* When optimizing for size, MEM should be slightly more expensive
26142 than generating address, e.g., (plus (reg) (const)).
26143 L1 cache latency is about two instructions. */
26144 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26153 if (FLOAT_MODE_P (mode))
26154 *total = rs6000_cost->fp;
26156 *total = COSTS_N_INSNS (1);
26160 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26161 && satisfies_constraint_I (XEXP (x, 1)))
26163 if (INTVAL (XEXP (x, 1)) >= -256
26164 && INTVAL (XEXP (x, 1)) <= 255)
26165 *total = rs6000_cost->mulsi_const9;
26167 *total = rs6000_cost->mulsi_const;
26169 else if (mode == SFmode)
26170 *total = rs6000_cost->fp;
26171 else if (FLOAT_MODE_P (mode))
26172 *total = rs6000_cost->dmul;
26173 else if (mode == DImode)
26174 *total = rs6000_cost->muldi;
26176 *total = rs6000_cost->mulsi;
26180 if (mode == SFmode)
26181 *total = rs6000_cost->fp;
26183 *total = rs6000_cost->dmul;
26188 if (FLOAT_MODE_P (mode))
26190 *total = mode == DFmode ? rs6000_cost->ddiv
26191 : rs6000_cost->sdiv;
26198 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26199 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26201 if (code == DIV || code == MOD)
26203 *total = COSTS_N_INSNS (2);
26206 *total = COSTS_N_INSNS (1);
26210 if (GET_MODE (XEXP (x, 1)) == DImode)
26211 *total = rs6000_cost->divdi;
26213 *total = rs6000_cost->divsi;
26215 /* Add in shift and subtract for MOD. */
26216 if (code == MOD || code == UMOD)
26217 *total += COSTS_N_INSNS (2);
26222 *total = COSTS_N_INSNS (4);
26226 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26230 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26234 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26246 *total = COSTS_N_INSNS (1);
26254 /* Handle mul_highpart. */
26255 if (outer_code == TRUNCATE
26256 && GET_CODE (XEXP (x, 0)) == MULT)
26258 if (mode == DImode)
26259 *total = rs6000_cost->muldi;
26261 *total = rs6000_cost->mulsi;
26264 else if (outer_code == AND)
26267 *total = COSTS_N_INSNS (1);
26272 if (GET_CODE (XEXP (x, 0)) == MEM)
26275 *total = COSTS_N_INSNS (1);
26281 if (!FLOAT_MODE_P (mode))
26283 *total = COSTS_N_INSNS (1);
26289 case UNSIGNED_FLOAT:
26292 case FLOAT_TRUNCATE:
26293 *total = rs6000_cost->fp;
26297 if (mode == DFmode)
26300 *total = rs6000_cost->fp;
26304 switch (XINT (x, 1))
26307 *total = rs6000_cost->fp;
26319 *total = COSTS_N_INSNS (1);
26322 else if (FLOAT_MODE_P (mode)
26323 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26325 *total = rs6000_cost->fp;
26333 /* Carry bit requires mode == Pmode.
26334 NEG or PLUS already counted so only add one. */
26336 && (outer_code == NEG || outer_code == PLUS))
26338 *total = COSTS_N_INSNS (1);
26341 if (outer_code == SET)
26343 if (XEXP (x, 1) == const0_rtx)
26345 if (TARGET_ISEL && !TARGET_MFCRF)
26346 *total = COSTS_N_INSNS (8);
26348 *total = COSTS_N_INSNS (2);
26351 else if (mode == Pmode)
26353 *total = COSTS_N_INSNS (3);
26362 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26364 if (TARGET_ISEL && !TARGET_MFCRF)
26365 *total = COSTS_N_INSNS (8);
26367 *total = COSTS_N_INSNS (2);
26371 if (outer_code == COMPARE)
26385 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26388 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26391 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26394 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26395 "total = %d, speed = %s, x:\n",
26396 ret ? "complete" : "scan inner",
26397 GET_RTX_NAME (code),
26398 GET_RTX_NAME (outer_code),
26400 speed ? "true" : "false");
26407 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26410 rs6000_debug_address_cost (rtx x, bool speed)
26412 int ret = TARGET_ADDRESS_COST (x, speed);
26414 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26415 ret, speed ? "true" : "false");
26422 /* A C expression returning the cost of moving data from a register of class
26423 CLASS1 to one of CLASS2. */
26426 rs6000_register_move_cost (enum machine_mode mode,
26427 reg_class_t from, reg_class_t to)
26431 /* Moves from/to GENERAL_REGS. */
26432 if (reg_classes_intersect_p (to, GENERAL_REGS)
26433 || reg_classes_intersect_p (from, GENERAL_REGS))
26435 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26438 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26439 ret = (rs6000_memory_move_cost (mode, from, false)
26440 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26442 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26444 else if (from == CR_REGS)
26447 /* Power6 has slower LR/CTR moves so make them more expensive than
26448 memory in order to bias spills to memory .*/
26449 else if (rs6000_cpu == PROCESSOR_POWER6
26450 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26451 ret = 6 * hard_regno_nregs[0][mode];
26454 /* A move will cost one instruction per GPR moved. */
26455 ret = 2 * hard_regno_nregs[0][mode];
26458 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26459 else if (VECTOR_UNIT_VSX_P (mode)
26460 && reg_classes_intersect_p (to, VSX_REGS)
26461 && reg_classes_intersect_p (from, VSX_REGS))
26462 ret = 2 * hard_regno_nregs[32][mode];
26464 /* Moving between two similar registers is just one instruction. */
26465 else if (reg_classes_intersect_p (to, from))
26466 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26468 /* Everything else has to go through GENERAL_REGS. */
26470 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26471 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26473 if (TARGET_DEBUG_COST)
26475 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26476 ret, GET_MODE_NAME (mode), reg_class_names[from],
26477 reg_class_names[to]);
26482 /* A C expressions returning the cost of moving data of MODE from a register to
26486 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26487 bool in ATTRIBUTE_UNUSED)
26491 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26492 ret = 4 * hard_regno_nregs[0][mode];
26493 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26494 ret = 4 * hard_regno_nregs[32][mode];
26495 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26496 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26498 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26500 if (TARGET_DEBUG_COST)
26502 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26503 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26508 /* Returns a code for a target-specific builtin that implements
26509 reciprocal of the function, or NULL_TREE if not available. */
26512 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26513 bool sqrt ATTRIBUTE_UNUSED)
26515 if (optimize_insn_for_size_p ())
26521 case VSX_BUILTIN_XVSQRTDP:
26522 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26525 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26527 case VSX_BUILTIN_XVSQRTSP:
26528 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26531 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26540 case BUILT_IN_SQRT:
26541 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26544 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26546 case BUILT_IN_SQRTF:
26547 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26550 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26557 /* Load up a constant. If the mode is a vector mode, splat the value across
26558 all of the vector elements. */
26561 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26565 if (mode == SFmode || mode == DFmode)
26567 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26568 reg = force_reg (mode, d);
26570 else if (mode == V4SFmode)
26572 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26573 rtvec v = gen_rtvec (4, d, d, d, d);
26574 reg = gen_reg_rtx (mode);
26575 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26577 else if (mode == V2DFmode)
26579 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26580 rtvec v = gen_rtvec (2, d, d);
26581 reg = gen_reg_rtx (mode);
26582 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26585 gcc_unreachable ();
26590 /* Generate an FMA instruction. */
26593 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26595 enum machine_mode mode = GET_MODE (target);
26598 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26599 gcc_assert (dst != NULL);
26602 emit_move_insn (target, dst);
26605 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26608 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26610 enum machine_mode mode = GET_MODE (target);
26613 /* Altivec does not support fms directly;
26614 generate in terms of fma in that case. */
26615 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26616 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26619 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26620 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26622 gcc_assert (dst != NULL);
26625 emit_move_insn (target, dst);
26628 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26631 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26633 enum machine_mode mode = GET_MODE (dst);
26636 /* This is a tad more complicated, since the fnma_optab is for
26637 a different expression: fma(-m1, m2, a), which is the same
26638 thing except in the case of signed zeros.
26640 Fortunately we know that if FMA is supported that FNMSUB is
26641 also supported in the ISA. Just expand it directly. */
26643 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26645 r = gen_rtx_NEG (mode, a);
26646 r = gen_rtx_FMA (mode, m1, m2, r);
26647 r = gen_rtx_NEG (mode, r);
26648 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26651 /* Newton-Raphson approximation of floating point divide with just 2 passes
26652 (either single precision floating point, or newer machines with higher
26653 accuracy estimates). Support both scalar and vector divide. Assumes no
26654 trapping math and finite arguments. */
26657 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26659 enum machine_mode mode = GET_MODE (dst);
26660 rtx x0, e0, e1, y1, u0, v0;
26661 enum insn_code code = optab_handler (smul_optab, mode);
26662 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26663 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26665 gcc_assert (code != CODE_FOR_nothing);
26667 /* x0 = 1./d estimate */
26668 x0 = gen_reg_rtx (mode);
26669 emit_insn (gen_rtx_SET (VOIDmode, x0,
26670 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26673 e0 = gen_reg_rtx (mode);
26674 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26676 e1 = gen_reg_rtx (mode);
26677 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26679 y1 = gen_reg_rtx (mode);
26680 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26682 u0 = gen_reg_rtx (mode);
26683 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26685 v0 = gen_reg_rtx (mode);
26686 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26688 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26691 /* Newton-Raphson approximation of floating point divide that has a low
26692 precision estimate. Assumes no trapping math and finite arguments. */
26695 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26697 enum machine_mode mode = GET_MODE (dst);
26698 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26699 enum insn_code code = optab_handler (smul_optab, mode);
26700 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26702 gcc_assert (code != CODE_FOR_nothing);
26704 one = rs6000_load_constant_and_splat (mode, dconst1);
26706 /* x0 = 1./d estimate */
26707 x0 = gen_reg_rtx (mode);
26708 emit_insn (gen_rtx_SET (VOIDmode, x0,
26709 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26712 e0 = gen_reg_rtx (mode);
26713 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26715 y1 = gen_reg_rtx (mode);
26716 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26718 e1 = gen_reg_rtx (mode);
26719 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26721 y2 = gen_reg_rtx (mode);
26722 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26724 e2 = gen_reg_rtx (mode);
26725 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26727 y3 = gen_reg_rtx (mode);
26728 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26730 u0 = gen_reg_rtx (mode);
26731 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26733 v0 = gen_reg_rtx (mode);
26734 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26736 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26739 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26740 add a reg_note saying that this was a division. Support both scalar and
26741 vector divide. Assumes no trapping math and finite arguments. */
26744 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26746 enum machine_mode mode = GET_MODE (dst);
26748 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26749 rs6000_emit_swdiv_high_precision (dst, n, d);
26751 rs6000_emit_swdiv_low_precision (dst, n, d);
26754 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26757 /* Newton-Raphson approximation of single/double-precision floating point
26758 rsqrt. Assumes no trapping math and finite arguments. */
26761 rs6000_emit_swrsqrt (rtx dst, rtx src)
26763 enum machine_mode mode = GET_MODE (src);
26764 rtx x0 = gen_reg_rtx (mode);
26765 rtx y = gen_reg_rtx (mode);
26766 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26767 REAL_VALUE_TYPE dconst3_2;
26770 enum insn_code code = optab_handler (smul_optab, mode);
26771 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26773 gcc_assert (code != CODE_FOR_nothing);
26775 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26776 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26777 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26779 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26781 /* x0 = rsqrt estimate */
26782 emit_insn (gen_rtx_SET (VOIDmode, x0,
26783 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26786 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26787 rs6000_emit_msub (y, src, halfthree, src);
26789 for (i = 0; i < passes; i++)
26791 rtx x1 = gen_reg_rtx (mode);
26792 rtx u = gen_reg_rtx (mode);
26793 rtx v = gen_reg_rtx (mode);
26795 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26796 emit_insn (gen_mul (u, x0, x0));
26797 rs6000_emit_nmsub (v, y, u, halfthree);
26798 emit_insn (gen_mul (x1, x0, v));
26802 emit_move_insn (dst, x0);
26806 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26807 (Power7) targets. DST is the target, and SRC is the argument operand. */
26810 rs6000_emit_popcount (rtx dst, rtx src)
26812 enum machine_mode mode = GET_MODE (dst);
26815 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26816 if (TARGET_POPCNTD)
26818 if (mode == SImode)
26819 emit_insn (gen_popcntdsi2 (dst, src));
26821 emit_insn (gen_popcntddi2 (dst, src));
26825 tmp1 = gen_reg_rtx (mode);
26827 if (mode == SImode)
26829 emit_insn (gen_popcntbsi2 (tmp1, src));
26830 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26832 tmp2 = force_reg (SImode, tmp2);
26833 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26837 emit_insn (gen_popcntbdi2 (tmp1, src));
26838 tmp2 = expand_mult (DImode, tmp1,
26839 GEN_INT ((HOST_WIDE_INT)
26840 0x01010101 << 32 | 0x01010101),
26842 tmp2 = force_reg (DImode, tmp2);
26843 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26848 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26849 target, and SRC is the argument operand. */
26852 rs6000_emit_parity (rtx dst, rtx src)
26854 enum machine_mode mode = GET_MODE (dst);
26857 tmp = gen_reg_rtx (mode);
26859 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26862 if (mode == SImode)
26864 emit_insn (gen_popcntbsi2 (tmp, src));
26865 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26869 emit_insn (gen_popcntbdi2 (tmp, src));
26870 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26875 if (mode == SImode)
26877 /* Is mult+shift >= shift+xor+shift+xor? */
26878 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26880 rtx tmp1, tmp2, tmp3, tmp4;
26882 tmp1 = gen_reg_rtx (SImode);
26883 emit_insn (gen_popcntbsi2 (tmp1, src));
26885 tmp2 = gen_reg_rtx (SImode);
26886 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26887 tmp3 = gen_reg_rtx (SImode);
26888 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26890 tmp4 = gen_reg_rtx (SImode);
26891 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26892 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26895 rs6000_emit_popcount (tmp, src);
26896 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26900 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26901 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26903 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26905 tmp1 = gen_reg_rtx (DImode);
26906 emit_insn (gen_popcntbdi2 (tmp1, src));
26908 tmp2 = gen_reg_rtx (DImode);
26909 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26910 tmp3 = gen_reg_rtx (DImode);
26911 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26913 tmp4 = gen_reg_rtx (DImode);
26914 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26915 tmp5 = gen_reg_rtx (DImode);
26916 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26918 tmp6 = gen_reg_rtx (DImode);
26919 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26920 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26923 rs6000_emit_popcount (tmp, src);
26924 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26928 /* Return an RTX representing where to find the function value of a
26929 function returning MODE. */
26931 rs6000_complex_function_value (enum machine_mode mode)
26933 unsigned int regno;
26935 enum machine_mode inner = GET_MODE_INNER (mode);
26936 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26938 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26939 regno = FP_ARG_RETURN;
26942 regno = GP_ARG_RETURN;
26944 /* 32-bit is OK since it'll go in r3/r4. */
26945 if (TARGET_32BIT && inner_bytes >= 4)
26946 return gen_rtx_REG (mode, regno);
26949 if (inner_bytes >= 8)
26950 return gen_rtx_REG (mode, regno);
26952 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26954 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26955 GEN_INT (inner_bytes));
26956 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26959 /* Target hook for TARGET_FUNCTION_VALUE.
26961 On the SPE, both FPs and vectors are returned in r3.
26963 On RS/6000 an integer value is in r3 and a floating-point value is in
26964 fp1, unless -msoft-float. */
26967 rs6000_function_value (const_tree valtype,
26968 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26969 bool outgoing ATTRIBUTE_UNUSED)
26971 enum machine_mode mode;
26972 unsigned int regno;
26974 /* Special handling for structs in darwin64. */
26976 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26978 CUMULATIVE_ARGS valcum;
26982 valcum.fregno = FP_ARG_MIN_REG;
26983 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26984 /* Do a trial code generation as if this were going to be passed as
26985 an argument; if any part goes in memory, we return NULL. */
26986 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
26989 /* Otherwise fall through to standard ABI rules. */
26992 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26994 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26995 return gen_rtx_PARALLEL (DImode,
26997 gen_rtx_EXPR_LIST (VOIDmode,
26998 gen_rtx_REG (SImode, GP_ARG_RETURN),
27000 gen_rtx_EXPR_LIST (VOIDmode,
27001 gen_rtx_REG (SImode,
27002 GP_ARG_RETURN + 1),
27005 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27007 return gen_rtx_PARALLEL (DCmode,
27009 gen_rtx_EXPR_LIST (VOIDmode,
27010 gen_rtx_REG (SImode, GP_ARG_RETURN),
27012 gen_rtx_EXPR_LIST (VOIDmode,
27013 gen_rtx_REG (SImode,
27014 GP_ARG_RETURN + 1),
27016 gen_rtx_EXPR_LIST (VOIDmode,
27017 gen_rtx_REG (SImode,
27018 GP_ARG_RETURN + 2),
27020 gen_rtx_EXPR_LIST (VOIDmode,
27021 gen_rtx_REG (SImode,
27022 GP_ARG_RETURN + 3),
27026 mode = TYPE_MODE (valtype);
27027 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27028 || POINTER_TYPE_P (valtype))
27029 mode = TARGET_32BIT ? SImode : DImode;
27031 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27032 /* _Decimal128 must use an even/odd register pair. */
27033 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27034 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27035 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27036 regno = FP_ARG_RETURN;
27037 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27038 && targetm.calls.split_complex_arg)
27039 return rs6000_complex_function_value (mode);
27040 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
27041 return register is used in both cases, and we won't see V2DImode/V2DFmode
27042 for pure altivec, combine the two cases. */
27043 else if (TREE_CODE (valtype) == VECTOR_TYPE
27044 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27045 && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
27046 regno = ALTIVEC_ARG_RETURN;
27047 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27048 && (mode == DFmode || mode == DCmode
27049 || mode == TFmode || mode == TCmode))
27050 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27052 regno = GP_ARG_RETURN;
27054 return gen_rtx_REG (mode, regno);
27057 /* Define how to find the value returned by a library function
27058 assuming the value has mode MODE. */
27060 rs6000_libcall_value (enum machine_mode mode)
27062 unsigned int regno;
27064 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27066 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27067 return gen_rtx_PARALLEL (DImode,
27069 gen_rtx_EXPR_LIST (VOIDmode,
27070 gen_rtx_REG (SImode, GP_ARG_RETURN),
27072 gen_rtx_EXPR_LIST (VOIDmode,
27073 gen_rtx_REG (SImode,
27074 GP_ARG_RETURN + 1),
27078 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27079 /* _Decimal128 must use an even/odd register pair. */
27080 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27081 else if (SCALAR_FLOAT_MODE_P (mode)
27082 && TARGET_HARD_FLOAT && TARGET_FPRS
27083 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27084 regno = FP_ARG_RETURN;
27085 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
27086 return register is used in both cases, and we won't see V2DImode/V2DFmode
27087 for pure altivec, combine the two cases. */
27088 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
27089 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27090 regno = ALTIVEC_ARG_RETURN;
27091 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27092 return rs6000_complex_function_value (mode);
27093 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27094 && (mode == DFmode || mode == DCmode
27095 || mode == TFmode || mode == TCmode))
27096 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27098 regno = GP_ARG_RETURN;
27100 return gen_rtx_REG (mode, regno);
27104 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27105 Frame pointer elimination is automatically handled.
27107 For the RS/6000, if frame pointer elimination is being done, we would like
27108 to convert ap into fp, not sp.
27110 We need r30 if -mminimal-toc was specified, and there are constant pool
27114 rs6000_can_eliminate (const int from, const int to)
27116 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27117 ? ! frame_pointer_needed
27118 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27119 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27123 /* Define the offset between two registers, FROM to be eliminated and its
27124 replacement TO, at the start of a routine. */
27126 rs6000_initial_elimination_offset (int from, int to)
27128 rs6000_stack_t *info = rs6000_stack_info ();
27129 HOST_WIDE_INT offset;
27131 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27132 offset = info->push_p ? 0 : -info->total_size;
27133 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27135 offset = info->push_p ? 0 : -info->total_size;
27136 if (FRAME_GROWS_DOWNWARD)
27137 offset += info->fixed_size + info->vars_size + info->parm_size;
27139 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27140 offset = FRAME_GROWS_DOWNWARD
27141 ? info->fixed_size + info->vars_size + info->parm_size
27143 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27144 offset = info->total_size;
27145 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27146 offset = info->push_p ? info->total_size : 0;
27147 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27150 gcc_unreachable ();
27156 rs6000_dwarf_register_span (rtx reg)
27160 unsigned regno = REGNO (reg);
27161 enum machine_mode mode = GET_MODE (reg);
27165 && (SPE_VECTOR_MODE (GET_MODE (reg))
27166 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27167 && mode != SFmode && mode != SDmode && mode != SCmode)))
27172 regno = REGNO (reg);
27174 /* The duality of the SPE register size wreaks all kinds of havoc.
27175 This is a way of distinguishing r0 in 32-bits from r0 in
27177 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27178 gcc_assert (words <= 4);
27179 for (i = 0; i < words; i++, regno++)
27181 if (BYTES_BIG_ENDIAN)
27183 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27184 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27188 parts[2 * i] = gen_rtx_REG (SImode, regno);
27189 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27193 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27196 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27199 rs6000_init_dwarf_reg_sizes_extra (tree address)
27204 enum machine_mode mode = TYPE_MODE (char_type_node);
27205 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27206 rtx mem = gen_rtx_MEM (BLKmode, addr);
27207 rtx value = gen_int_mode (4, mode);
27209 for (i = 1201; i < 1232; i++)
27211 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27212 HOST_WIDE_INT offset
27213 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27215 emit_move_insn (adjust_address (mem, mode, offset), value);
27220 /* Map internal gcc register numbers to DWARF2 register numbers. */
27223 rs6000_dbx_register_number (unsigned int regno)
27225 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27227 if (regno == MQ_REGNO)
27229 if (regno == LR_REGNO)
27231 if (regno == CTR_REGNO)
27233 if (CR_REGNO_P (regno))
27234 return regno - CR0_REGNO + 86;
27235 if (regno == CA_REGNO)
27236 return 101; /* XER */
27237 if (ALTIVEC_REGNO_P (regno))
27238 return regno - FIRST_ALTIVEC_REGNO + 1124;
27239 if (regno == VRSAVE_REGNO)
27241 if (regno == VSCR_REGNO)
27243 if (regno == SPE_ACC_REGNO)
27245 if (regno == SPEFSCR_REGNO)
27247 /* SPE high reg number. We get these values of regno from
27248 rs6000_dwarf_register_span. */
27249 gcc_assert (regno >= 1200 && regno < 1232);
27253 /* target hook eh_return_filter_mode */
27254 static enum machine_mode
27255 rs6000_eh_return_filter_mode (void)
27257 return TARGET_32BIT ? SImode : word_mode;
27260 /* Target hook for scalar_mode_supported_p. */
27262 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27264 if (DECIMAL_FLOAT_MODE_P (mode))
27265 return default_decimal_float_supported_p ();
27267 return default_scalar_mode_supported_p (mode);
27270 /* Target hook for vector_mode_supported_p. */
27272 rs6000_vector_mode_supported_p (enum machine_mode mode)
27275 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27278 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27281 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27288 /* Target hook for invalid_arg_for_unprototyped_fn. */
27289 static const char *
27290 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27292 return (!rs6000_darwin64_abi
27294 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27295 && (funcdecl == NULL_TREE
27296 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27297 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27298 ? N_("AltiVec argument passed to unprototyped function")
27302 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27303 setup by using __stack_chk_fail_local hidden function instead of
27304 calling __stack_chk_fail directly. Otherwise it is better to call
27305 __stack_chk_fail directly. */
27308 rs6000_stack_protect_fail (void)
27310 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27311 ? default_hidden_stack_protect_fail ()
27312 : default_external_stack_protect_fail ();
27316 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27317 int num_operands ATTRIBUTE_UNUSED)
27319 if (rs6000_warn_cell_microcode)
27322 int insn_code_number = recog_memoized (insn);
27323 location_t location = locator_location (INSN_LOCATOR (insn));
27325 /* Punt on insns we cannot recognize. */
27326 if (insn_code_number < 0)
27329 temp = get_insn_template (insn_code_number, insn);
27331 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27332 warning_at (location, OPT_mwarn_cell_microcode,
27333 "emitting microcode insn %s\t[%s] #%d",
27334 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27335 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27336 warning_at (location, OPT_mwarn_cell_microcode,
27337 "emitting conditional microcode insn %s\t[%s] #%d",
27338 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27343 /* Mask options that we want to support inside of attribute((target)) and
27344 #pragma GCC target operations. Note, we do not include things like
27345 64/32-bit, endianess, hard/soft floating point, etc. that would have
27346 different calling sequences. */
27348 struct rs6000_opt_mask {
27349 const char *name; /* option name */
27350 int mask; /* mask to set */
27351 bool invert; /* invert sense of mask */
27352 bool valid_target; /* option is a target option */
27355 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27357 { "altivec", MASK_ALTIVEC, false, true },
27358 { "cmpb", MASK_CMPB, false, true },
27359 { "dlmzb", MASK_DLMZB, false, true },
27360 { "fprnd", MASK_FPRND, false, true },
27361 { "hard-dfp", MASK_DFP, false, true },
27362 { "isel", MASK_ISEL, false, true },
27363 { "mfcrf", MASK_MFCRF, false, true },
27364 { "mfpgpr", MASK_MFPGPR, false, true },
27365 { "mulhw", MASK_MULHW, false, true },
27366 { "multiple", MASK_MULTIPLE, false, true },
27367 { "update", MASK_NO_UPDATE, true , true },
27368 { "popcntb", MASK_POPCNTB, false, true },
27369 { "popcntd", MASK_POPCNTD, false, true },
27370 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27371 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27372 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27373 { "string", MASK_STRING, false, true },
27374 { "vsx", MASK_VSX, false, true },
27377 { "aix64", MASK_64BIT, false, false },
27378 { "aix32", MASK_64BIT, true, false },
27380 { "64", MASK_64BIT, false, false },
27381 { "32", MASK_64BIT, true, false },
27385 { "eabi", MASK_EABI, false, false },
27387 #ifdef MASK_LITTLE_ENDIAN
27388 { "little", MASK_LITTLE_ENDIAN, false, false },
27389 { "big", MASK_LITTLE_ENDIAN, true, false },
27391 #ifdef MASK_RELOCATABLE
27392 { "relocatable", MASK_RELOCATABLE, false, false },
27394 #ifdef MASK_STRICT_ALIGN
27395 { "strict-align", MASK_STRICT_ALIGN, false, false },
27397 { "power", MASK_POWER, false, false },
27398 { "power2", MASK_POWER2, false, false },
27399 { "powerpc", MASK_POWERPC, false, false },
27400 { "soft-float", MASK_SOFT_FLOAT, false, false },
27401 { "string", MASK_STRING, false, false },
27404 /* Option variables that we want to support inside attribute((target)) and
27405 #pragma GCC target operations. */
27407 struct rs6000_opt_var {
27408 const char *name; /* option name */
27409 size_t global_offset; /* offset of the option in global_options. */
27410 size_t target_offset; /* offset of the option in target optiosn. */
27413 static struct rs6000_opt_var const rs6000_opt_vars[] =
27416 offsetof (struct gcc_options, x_TARGET_FRIZ),
27417 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27418 { "avoid-indexed-addresses",
27419 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27420 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27422 offsetof (struct gcc_options, x_rs6000_paired_float),
27423 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27425 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27426 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27429 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27430 parsing. Return true if there were no errors. */
27433 rs6000_inner_target_options (tree args, bool attr_p)
27437 if (args == NULL_TREE)
27440 else if (TREE_CODE (args) == STRING_CST)
27442 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27445 while ((q = strtok (p, ",")) != NULL)
27447 bool error_p = false;
27448 bool not_valid_p = false;
27449 const char *cpu_opt = NULL;
27452 if (strncmp (q, "cpu=", 4) == 0)
27454 int cpu_index = rs6000_cpu_name_lookup (q+4);
27455 if (cpu_index >= 0)
27456 rs6000_cpu_index = cpu_index;
27463 else if (strncmp (q, "tune=", 5) == 0)
27465 int tune_index = rs6000_cpu_name_lookup (q+5);
27466 if (tune_index >= 0)
27467 rs6000_tune_index = tune_index;
27477 bool invert = false;
27481 if (strncmp (r, "no-", 3) == 0)
27487 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27488 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27490 int mask = rs6000_opt_masks[i].mask;
27492 if (!rs6000_opt_masks[i].valid_target)
27493 not_valid_p = true;
27497 target_flags_explicit |= mask;
27499 if (rs6000_opt_masks[i].invert)
27503 target_flags &= ~mask;
27505 target_flags |= mask;
27510 if (error_p && !not_valid_p)
27512 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27513 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27515 size_t j = rs6000_opt_vars[i].global_offset;
27516 ((int *) &global_options)[j] = !invert;
27525 const char *eprefix, *esuffix;
27530 eprefix = "__attribute__((__target__(";
27535 eprefix = "#pragma GCC target ";
27540 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27542 else if (not_valid_p)
27543 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27545 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27550 else if (TREE_CODE (args) == TREE_LIST)
27554 tree value = TREE_VALUE (args);
27557 bool ret2 = rs6000_inner_target_options (value, attr_p);
27561 args = TREE_CHAIN (args);
27563 while (args != NULL_TREE);
27567 gcc_unreachable ();
27572 /* Print out the target options as a list for -mdebug=target. */
27575 rs6000_debug_target_options (tree args, const char *prefix)
27577 if (args == NULL_TREE)
27578 fprintf (stderr, "%s<NULL>", prefix);
27580 else if (TREE_CODE (args) == STRING_CST)
27582 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27585 while ((q = strtok (p, ",")) != NULL)
27588 fprintf (stderr, "%s\"%s\"", prefix, q);
27593 else if (TREE_CODE (args) == TREE_LIST)
27597 tree value = TREE_VALUE (args);
27600 rs6000_debug_target_options (value, prefix);
27603 args = TREE_CHAIN (args);
27605 while (args != NULL_TREE);
27609 gcc_unreachable ();
27615 /* Hook to validate attribute((target("..."))). */
27618 rs6000_valid_attribute_p (tree fndecl,
27619 tree ARG_UNUSED (name),
27623 struct cl_target_option cur_target;
27625 tree old_optimize = build_optimization_node ();
27626 tree new_target, new_optimize;
27627 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27629 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27631 if (TARGET_DEBUG_TARGET)
27633 tree tname = DECL_NAME (fndecl);
27634 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27636 fprintf (stderr, "function: %.*s\n",
27637 (int) IDENTIFIER_LENGTH (tname),
27638 IDENTIFIER_POINTER (tname));
27640 fprintf (stderr, "function: unknown\n");
27642 fprintf (stderr, "args:");
27643 rs6000_debug_target_options (args, " ");
27644 fprintf (stderr, "\n");
27647 fprintf (stderr, "flags: 0x%x\n", flags);
27649 fprintf (stderr, "--------------------\n");
27652 old_optimize = build_optimization_node ();
27653 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27655 /* If the function changed the optimization levels as well as setting target
27656 options, start with the optimizations specified. */
27657 if (func_optimize && func_optimize != old_optimize)
27658 cl_optimization_restore (&global_options,
27659 TREE_OPTIMIZATION (func_optimize));
27661 /* The target attributes may also change some optimization flags, so update
27662 the optimization options if necessary. */
27663 cl_target_option_save (&cur_target, &global_options);
27664 rs6000_cpu_index = rs6000_tune_index = -1;
27665 ret = rs6000_inner_target_options (args, true);
27667 /* Set up any additional state. */
27670 ret = rs6000_option_override_internal (false);
27671 new_target = build_target_option_node ();
27676 new_optimize = build_optimization_node ();
27683 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27685 if (old_optimize != new_optimize)
27686 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27689 cl_target_option_restore (&global_options, &cur_target);
27691 if (old_optimize != new_optimize)
27692 cl_optimization_restore (&global_options,
27693 TREE_OPTIMIZATION (old_optimize));
27699 /* Hook to validate the current #pragma GCC target and set the state, and
27700 update the macros based on what was changed. If ARGS is NULL, then
27701 POP_TARGET is used to reset the options. */
27704 rs6000_pragma_target_parse (tree args, tree pop_target)
27709 if (TARGET_DEBUG_TARGET)
27711 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27712 fprintf (stderr, "args:");
27713 rs6000_debug_target_options (args, " ");
27714 fprintf (stderr, "\n");
27718 fprintf (stderr, "pop_target:\n");
27719 debug_tree (pop_target);
27722 fprintf (stderr, "pop_target: <NULL>\n");
27724 fprintf (stderr, "--------------------\n");
27730 cur_tree = ((pop_target)
27732 : target_option_default_node);
27733 cl_target_option_restore (&global_options,
27734 TREE_TARGET_OPTION (cur_tree));
27738 rs6000_cpu_index = rs6000_tune_index = -1;
27739 ret = rs6000_inner_target_options (args, false);
27740 cur_tree = build_target_option_node ();
27747 target_option_current_node = cur_tree;
27753 /* Remember the last target of rs6000_set_current_function. */
27754 static GTY(()) tree rs6000_previous_fndecl;
27756 /* Establish appropriate back-end context for processing the function
27757 FNDECL. The argument might be NULL to indicate processing at top
27758 level, outside of any function scope. */
27760 rs6000_set_current_function (tree fndecl)
27762 tree old_tree = (rs6000_previous_fndecl
27763 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
27766 tree new_tree = (fndecl
27767 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
27770 if (TARGET_DEBUG_TARGET)
27772 bool print_final = false;
27773 fprintf (stderr, "\n==================== rs6000_set_current_function");
27776 fprintf (stderr, ", fndecl %s (%p)",
27777 (DECL_NAME (fndecl)
27778 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
27779 : "<unknown>"), (void *)fndecl);
27781 if (rs6000_previous_fndecl)
27782 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
27784 fprintf (stderr, "\n");
27787 fprintf (stderr, "\nnew fndecl target specific options:\n");
27788 debug_tree (new_tree);
27789 print_final = true;
27794 fprintf (stderr, "\nold fndecl target specific options:\n");
27795 debug_tree (old_tree);
27796 print_final = true;
27800 fprintf (stderr, "--------------------\n");
27803 /* Only change the context if the function changes. This hook is called
27804 several times in the course of compiling a function, and we don't want to
27805 slow things down too much or call target_reinit when it isn't safe. */
27806 if (fndecl && fndecl != rs6000_previous_fndecl)
27808 rs6000_previous_fndecl = fndecl;
27809 if (old_tree == new_tree)
27814 cl_target_option_restore (&global_options,
27815 TREE_TARGET_OPTION (new_tree));
27821 struct cl_target_option *def
27822 = TREE_TARGET_OPTION (target_option_current_node);
27824 cl_target_option_restore (&global_options, def);
27831 /* Save the current options */
27834 rs6000_function_specific_save (struct cl_target_option *ptr)
27836 ptr->rs6000_target_flags_explicit = target_flags_explicit;
27839 /* Restore the current options */
27842 rs6000_function_specific_restore (struct cl_target_option *ptr)
27844 target_flags_explicit = ptr->rs6000_target_flags_explicit;
27845 (void) rs6000_option_override_internal (false);
27848 /* Print the current options */
27851 rs6000_function_specific_print (FILE *file, int indent,
27852 struct cl_target_option *ptr)
27855 int flags = ptr->x_target_flags;
27857 /* Print the various mask options. */
27858 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27859 if ((flags & rs6000_opt_masks[i].mask) != 0)
27861 flags &= ~ rs6000_opt_masks[i].mask;
27862 fprintf (file, "%*s-m%s%s\n", indent, "",
27863 rs6000_opt_masks[i].invert ? "no-" : "",
27864 rs6000_opt_masks[i].name);
27867 /* Print the various options that are variables. */
27868 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27870 size_t j = rs6000_opt_vars[i].target_offset;
27871 if (((signed char *) ptr)[j])
27872 fprintf (file, "%*s-m%s\n", indent, "",
27873 rs6000_opt_vars[i].name);
27878 /* Hook to determine if one function can safely inline another. */
27881 rs6000_can_inline_p (tree caller, tree callee)
27884 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
27885 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
27887 /* If callee has no option attributes, then it is ok to inline. */
27891 /* If caller has no option attributes, but callee does then it is not ok to
27893 else if (!caller_tree)
27898 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
27899 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
27901 /* Callee's options should a subset of the caller's, i.e. a vsx function
27902 can inline an altivec function but a non-vsx function can't inline a
27904 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
27905 == callee_opts->x_target_flags)
27909 if (TARGET_DEBUG_TARGET)
27910 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27911 (DECL_NAME (caller)
27912 ? IDENTIFIER_POINTER (DECL_NAME (caller))
27914 (DECL_NAME (callee)
27915 ? IDENTIFIER_POINTER (DECL_NAME (callee))
27917 (ret ? "can" : "cannot"));
27922 /* Allocate a stack temp and fixup the address so it meets the particular
27923 memory requirements (either offetable or REG+REG addressing). */
27926 rs6000_allocate_stack_temp (enum machine_mode mode,
27927 bool offsettable_p,
27930 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27931 rtx addr = XEXP (stack, 0);
27932 int strict_p = (reload_in_progress || reload_completed);
27934 if (!legitimate_indirect_address_p (addr, strict_p))
27937 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27938 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27940 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27941 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27947 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27948 to such a form to deal with memory reference instructions like STFIWX that
27949 only take reg+reg addressing. */
27952 rs6000_address_for_fpconvert (rtx x)
27954 int strict_p = (reload_in_progress || reload_completed);
27957 gcc_assert (MEM_P (x));
27958 addr = XEXP (x, 0);
27959 if (! legitimate_indirect_address_p (addr, strict_p)
27960 && ! legitimate_indexed_address_p (addr, strict_p))
27962 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27964 rtx reg = XEXP (addr, 0);
27965 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27966 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27967 gcc_assert (REG_P (reg));
27968 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27971 else if (GET_CODE (addr) == PRE_MODIFY)
27973 rtx reg = XEXP (addr, 0);
27974 rtx expr = XEXP (addr, 1);
27975 gcc_assert (REG_P (reg));
27976 gcc_assert (GET_CODE (expr) == PLUS);
27977 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27981 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27987 /* Given a memory reference, if it is not in the form for altivec memory
27988 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27989 convert to the altivec format. */
27992 rs6000_address_for_altivec (rtx x)
27994 gcc_assert (MEM_P (x));
27995 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
27997 rtx addr = XEXP (x, 0);
27998 int strict_p = (reload_in_progress || reload_completed);
28000 if (!legitimate_indexed_address_p (addr, strict_p)
28001 && !legitimate_indirect_address_p (addr, strict_p))
28002 addr = copy_to_mode_reg (Pmode, addr);
28004 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28005 x = change_address (x, GET_MODE (x), addr);
28011 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
28013 On the RS/6000, all integer constants are acceptable, most won't be valid
28014 for particular insns, though. Only easy FP constants are acceptable. */
28017 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
28019 if (rs6000_tls_referenced_p (x))
28022 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
28023 || GET_MODE (x) == VOIDmode
28024 || (TARGET_POWERPC64 && mode == DImode)
28025 || easy_fp_constant (x, mode)
28026 || easy_vector_constant (x, mode));
28029 #include "gt-rs6000.h"