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 "common/common-target.h"
52 #include "langhooks.h"
54 #include "cfglayout.h"
56 #include "sched-int.h"
58 #include "tree-flow.h"
61 #include "tm-constrs.h"
64 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
67 #include "gstab.h" /* for N_SLINE */
70 #ifndef TARGET_NO_PROTOTYPE
71 #define TARGET_NO_PROTOTYPE 0
74 #define min(A,B) ((A) < (B) ? (A) : (B))
75 #define max(A,B) ((A) > (B) ? (A) : (B))
77 /* Structure used to define the rs6000 stack */
78 typedef struct rs6000_stack
{
79 int reload_completed
; /* stack info won't change from here on */
80 int first_gp_reg_save
; /* first callee saved GP register used */
81 int first_fp_reg_save
; /* first callee saved FP register used */
82 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
83 int lr_save_p
; /* true if the link reg needs to be saved */
84 int cr_save_p
; /* true if the CR reg needs to be saved */
85 unsigned int vrsave_mask
; /* mask of vec registers to save */
86 int push_p
; /* true if we need to allocate stack space */
87 int calls_p
; /* true if the function makes any calls */
88 int world_save_p
; /* true if we're saving *everything*:
89 r13-r31, cr, f14-f31, vrsave, v20-v31 */
90 enum rs6000_abi abi
; /* which ABI to use */
91 int gp_save_offset
; /* offset to save GP regs from initial SP */
92 int fp_save_offset
; /* offset to save FP regs from initial SP */
93 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
94 int lr_save_offset
; /* offset to save LR from initial SP */
95 int cr_save_offset
; /* offset to save CR from initial SP */
96 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
97 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
98 int varargs_save_offset
; /* offset to save the varargs registers */
99 int ehrd_offset
; /* offset to EH return data */
100 int reg_size
; /* register size (4 or 8) */
101 HOST_WIDE_INT vars_size
; /* variable save area size */
102 int parm_size
; /* outgoing parameter size */
103 int save_size
; /* save area size */
104 int fixed_size
; /* fixed size of stack frame */
105 int gp_size
; /* size of saved GP registers */
106 int fp_size
; /* size of saved FP registers */
107 int altivec_size
; /* size of saved AltiVec registers */
108 int cr_size
; /* size to hold CR if not in save_size */
109 int vrsave_size
; /* size to hold VRSAVE if not in save_size */
110 int altivec_padding_size
; /* size of altivec alignment padding if
112 int spe_gp_size
; /* size of 64-bit GPR save size for SPE */
113 int spe_padding_size
;
114 HOST_WIDE_INT total_size
; /* total bytes allocated for stack */
115 int spe_64bit_regs_used
;
119 /* A C structure for machine-specific, per-function data.
120 This is added to the cfun structure. */
121 typedef struct GTY(()) machine_function
123 /* Some local-dynamic symbol. */
124 const char *some_ld_name
;
125 /* Whether the instruction chain has been scanned already. */
126 int insn_chain_scanned_p
;
127 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
128 int ra_needs_full_frame
;
129 /* Flags if __builtin_return_address (0) was used. */
131 /* Cache lr_save_p after expansion of builtin_eh_return. */
133 /* Whether we need to save the TOC to the reserved stack location in the
134 function prologue. */
135 bool save_toc_in_prologue
;
136 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
137 varargs save area. */
138 HOST_WIDE_INT varargs_save_offset
;
139 /* Temporary stack slot to use for SDmode copies. This slot is
140 64-bits wide and is allocated early enough so that the offset
141 does not overflow the 16-bit load/store offset field. */
142 rtx sdmode_stack_slot
;
145 /* Support targetm.vectorize.builtin_mask_for_load. */
146 static GTY(()) tree altivec_builtin_mask_for_load
;
148 /* Set to nonzero once AIX common-mode calls have been defined. */
149 static GTY(()) int common_mode_defined
;
151 /* Label number of label created for -mrelocatable, to call to so we can
152 get the address of the GOT section */
153 static int rs6000_pic_labelno
;
156 /* Counter for labels which are to be placed in .fixup. */
157 int fixuplabelno
= 0;
160 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
163 /* Specify the machine mode that pointers have. After generation of rtl, the
164 compiler makes no further distinction between pointers and any other objects
165 of this machine mode. The type is unsigned since not all things that
166 include rs6000.h also include machmode.h. */
167 unsigned rs6000_pmode
;
169 /* Width in bits of a pointer. */
170 unsigned rs6000_pointer_size
;
172 #ifdef HAVE_AS_GNU_ATTRIBUTE
173 /* Flag whether floating point values have been passed/returned. */
174 static bool rs6000_passes_float
;
175 /* Flag whether vector values have been passed/returned. */
176 static bool rs6000_passes_vector
;
177 /* Flag whether small (<= 8 byte) structures have been returned. */
178 static bool rs6000_returns_struct
;
181 /* Value is TRUE if register/mode pair is acceptable. */
182 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
184 /* Maximum number of registers needed for a given register class and mode. */
185 unsigned char rs6000_class_max_nregs
[NUM_MACHINE_MODES
][LIM_REG_CLASSES
];
187 /* How many registers are needed for a given register and mode. */
188 unsigned char rs6000_hard_regno_nregs
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
190 /* Map register number to register class. */
191 enum reg_class rs6000_regno_regclass
[FIRST_PSEUDO_REGISTER
];
193 /* Reload functions based on the type and the vector unit. */
194 static enum insn_code rs6000_vector_reload
[NUM_MACHINE_MODES
][2];
196 static int dbg_cost_ctrl
;
198 /* Built in types. */
199 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
200 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
202 /* Flag to say the TOC is initialized */
204 char toc_label_name
[10];
206 /* Cached value of rs6000_variable_issue. This is cached in
207 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
208 static short cached_can_issue_more
;
210 static GTY(()) section
*read_only_data_section
;
211 static GTY(()) section
*private_data_section
;
212 static GTY(()) section
*read_only_private_data_section
;
213 static GTY(()) section
*sdata2_section
;
214 static GTY(()) section
*toc_section
;
216 struct builtin_description
218 /* mask is not const because we're going to alter it below. This
219 nonsense will go away when we rewrite the -march infrastructure
220 to give us more target flag bits. */
222 const enum insn_code icode
;
223 const char *const name
;
224 const enum rs6000_builtins code
;
227 /* Describe the vector unit used for modes. */
228 enum rs6000_vector rs6000_vector_unit
[NUM_MACHINE_MODES
];
229 enum rs6000_vector rs6000_vector_mem
[NUM_MACHINE_MODES
];
231 /* Register classes for various constraints that are based on the target
233 enum reg_class rs6000_constraints
[RS6000_CONSTRAINT_MAX
];
235 /* Describe the alignment of a vector. */
236 int rs6000_vector_align
[NUM_MACHINE_MODES
];
238 /* Map selected modes to types for builtins. */
239 static GTY(()) tree builtin_mode_to_type
[MAX_MACHINE_MODE
][2];
241 /* What modes to automatically generate reciprocal divide estimate (fre) and
242 reciprocal sqrt (frsqrte) for. */
243 unsigned char rs6000_recip_bits
[MAX_MACHINE_MODE
];
245 /* Masks to determine which reciprocal esitmate instructions to generate
247 enum rs6000_recip_mask
{
248 RECIP_SF_DIV
= 0x001, /* Use divide estimate */
249 RECIP_DF_DIV
= 0x002,
250 RECIP_V4SF_DIV
= 0x004,
251 RECIP_V2DF_DIV
= 0x008,
253 RECIP_SF_RSQRT
= 0x010, /* Use reciprocal sqrt estimate. */
254 RECIP_DF_RSQRT
= 0x020,
255 RECIP_V4SF_RSQRT
= 0x040,
256 RECIP_V2DF_RSQRT
= 0x080,
258 /* Various combination of flags for -mrecip=xxx. */
260 RECIP_ALL
= (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
261 | RECIP_V2DF_DIV
| RECIP_SF_RSQRT
| RECIP_DF_RSQRT
262 | RECIP_V4SF_RSQRT
| RECIP_V2DF_RSQRT
),
264 RECIP_HIGH_PRECISION
= RECIP_ALL
,
266 /* On low precision machines like the power5, don't enable double precision
267 reciprocal square root estimate, since it isn't accurate enough. */
268 RECIP_LOW_PRECISION
= (RECIP_ALL
& ~(RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
))
271 /* -mrecip options. */
274 const char *string
; /* option name */
275 unsigned int mask
; /* mask bits to set */
276 } recip_options
[] = {
277 { "all", RECIP_ALL
},
278 { "none", RECIP_NONE
},
279 { "div", (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
281 { "divf", (RECIP_SF_DIV
| RECIP_V4SF_DIV
) },
282 { "divd", (RECIP_DF_DIV
| RECIP_V2DF_DIV
) },
283 { "rsqrt", (RECIP_SF_RSQRT
| RECIP_DF_RSQRT
| RECIP_V4SF_RSQRT
284 | RECIP_V2DF_RSQRT
) },
285 { "rsqrtf", (RECIP_SF_RSQRT
| RECIP_V4SF_RSQRT
) },
286 { "rsqrtd", (RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
) },
289 /* 2 argument gen function typedef. */
290 typedef rtx (*gen_2arg_fn_t
) (rtx
, rtx
, rtx
);
293 /* Target cpu costs. */
295 struct processor_costs
{
296 const int mulsi
; /* cost of SImode multiplication. */
297 const int mulsi_const
; /* cost of SImode multiplication by constant. */
298 const int mulsi_const9
; /* cost of SImode mult by short constant. */
299 const int muldi
; /* cost of DImode multiplication. */
300 const int divsi
; /* cost of SImode division. */
301 const int divdi
; /* cost of DImode division. */
302 const int fp
; /* cost of simple SFmode and DFmode insns. */
303 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
304 const int sdiv
; /* cost of SFmode division (fdivs). */
305 const int ddiv
; /* cost of DFmode division (fdiv). */
306 const int cache_line_size
; /* cache line size in bytes. */
307 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
308 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
309 const int simultaneous_prefetches
; /* number of parallel prefetch
313 const struct processor_costs
*rs6000_cost
;
315 /* Processor costs (relative to an add) */
317 /* Instruction size costs on 32bit processors. */
319 struct processor_costs size32_cost
= {
320 COSTS_N_INSNS (1), /* mulsi */
321 COSTS_N_INSNS (1), /* mulsi_const */
322 COSTS_N_INSNS (1), /* mulsi_const9 */
323 COSTS_N_INSNS (1), /* muldi */
324 COSTS_N_INSNS (1), /* divsi */
325 COSTS_N_INSNS (1), /* divdi */
326 COSTS_N_INSNS (1), /* fp */
327 COSTS_N_INSNS (1), /* dmul */
328 COSTS_N_INSNS (1), /* sdiv */
329 COSTS_N_INSNS (1), /* ddiv */
336 /* Instruction size costs on 64bit processors. */
338 struct processor_costs size64_cost
= {
339 COSTS_N_INSNS (1), /* mulsi */
340 COSTS_N_INSNS (1), /* mulsi_const */
341 COSTS_N_INSNS (1), /* mulsi_const9 */
342 COSTS_N_INSNS (1), /* muldi */
343 COSTS_N_INSNS (1), /* divsi */
344 COSTS_N_INSNS (1), /* divdi */
345 COSTS_N_INSNS (1), /* fp */
346 COSTS_N_INSNS (1), /* dmul */
347 COSTS_N_INSNS (1), /* sdiv */
348 COSTS_N_INSNS (1), /* ddiv */
355 /* Instruction costs on RIOS1 processors. */
357 struct processor_costs rios1_cost
= {
358 COSTS_N_INSNS (5), /* mulsi */
359 COSTS_N_INSNS (4), /* mulsi_const */
360 COSTS_N_INSNS (3), /* mulsi_const9 */
361 COSTS_N_INSNS (5), /* muldi */
362 COSTS_N_INSNS (19), /* divsi */
363 COSTS_N_INSNS (19), /* divdi */
364 COSTS_N_INSNS (2), /* fp */
365 COSTS_N_INSNS (2), /* dmul */
366 COSTS_N_INSNS (19), /* sdiv */
367 COSTS_N_INSNS (19), /* ddiv */
368 128, /* cache line size */
374 /* Instruction costs on RIOS2 processors. */
376 struct processor_costs rios2_cost
= {
377 COSTS_N_INSNS (2), /* mulsi */
378 COSTS_N_INSNS (2), /* mulsi_const */
379 COSTS_N_INSNS (2), /* mulsi_const9 */
380 COSTS_N_INSNS (2), /* muldi */
381 COSTS_N_INSNS (13), /* divsi */
382 COSTS_N_INSNS (13), /* divdi */
383 COSTS_N_INSNS (2), /* fp */
384 COSTS_N_INSNS (2), /* dmul */
385 COSTS_N_INSNS (17), /* sdiv */
386 COSTS_N_INSNS (17), /* ddiv */
387 256, /* cache line size */
393 /* Instruction costs on RS64A processors. */
395 struct processor_costs rs64a_cost
= {
396 COSTS_N_INSNS (20), /* mulsi */
397 COSTS_N_INSNS (12), /* mulsi_const */
398 COSTS_N_INSNS (8), /* mulsi_const9 */
399 COSTS_N_INSNS (34), /* muldi */
400 COSTS_N_INSNS (65), /* divsi */
401 COSTS_N_INSNS (67), /* divdi */
402 COSTS_N_INSNS (4), /* fp */
403 COSTS_N_INSNS (4), /* dmul */
404 COSTS_N_INSNS (31), /* sdiv */
405 COSTS_N_INSNS (31), /* ddiv */
406 128, /* cache line size */
412 /* Instruction costs on MPCCORE processors. */
414 struct processor_costs mpccore_cost
= {
415 COSTS_N_INSNS (2), /* mulsi */
416 COSTS_N_INSNS (2), /* mulsi_const */
417 COSTS_N_INSNS (2), /* mulsi_const9 */
418 COSTS_N_INSNS (2), /* muldi */
419 COSTS_N_INSNS (6), /* divsi */
420 COSTS_N_INSNS (6), /* divdi */
421 COSTS_N_INSNS (4), /* fp */
422 COSTS_N_INSNS (5), /* dmul */
423 COSTS_N_INSNS (10), /* sdiv */
424 COSTS_N_INSNS (17), /* ddiv */
425 32, /* cache line size */
431 /* Instruction costs on PPC403 processors. */
433 struct processor_costs ppc403_cost
= {
434 COSTS_N_INSNS (4), /* mulsi */
435 COSTS_N_INSNS (4), /* mulsi_const */
436 COSTS_N_INSNS (4), /* mulsi_const9 */
437 COSTS_N_INSNS (4), /* muldi */
438 COSTS_N_INSNS (33), /* divsi */
439 COSTS_N_INSNS (33), /* divdi */
440 COSTS_N_INSNS (11), /* fp */
441 COSTS_N_INSNS (11), /* dmul */
442 COSTS_N_INSNS (11), /* sdiv */
443 COSTS_N_INSNS (11), /* ddiv */
444 32, /* cache line size */
450 /* Instruction costs on PPC405 processors. */
452 struct processor_costs ppc405_cost
= {
453 COSTS_N_INSNS (5), /* mulsi */
454 COSTS_N_INSNS (4), /* mulsi_const */
455 COSTS_N_INSNS (3), /* mulsi_const9 */
456 COSTS_N_INSNS (5), /* muldi */
457 COSTS_N_INSNS (35), /* divsi */
458 COSTS_N_INSNS (35), /* divdi */
459 COSTS_N_INSNS (11), /* fp */
460 COSTS_N_INSNS (11), /* dmul */
461 COSTS_N_INSNS (11), /* sdiv */
462 COSTS_N_INSNS (11), /* ddiv */
463 32, /* cache line size */
469 /* Instruction costs on PPC440 processors. */
471 struct processor_costs ppc440_cost
= {
472 COSTS_N_INSNS (3), /* mulsi */
473 COSTS_N_INSNS (2), /* mulsi_const */
474 COSTS_N_INSNS (2), /* mulsi_const9 */
475 COSTS_N_INSNS (3), /* muldi */
476 COSTS_N_INSNS (34), /* divsi */
477 COSTS_N_INSNS (34), /* divdi */
478 COSTS_N_INSNS (5), /* fp */
479 COSTS_N_INSNS (5), /* dmul */
480 COSTS_N_INSNS (19), /* sdiv */
481 COSTS_N_INSNS (33), /* ddiv */
482 32, /* cache line size */
488 /* Instruction costs on PPC476 processors. */
490 struct processor_costs ppc476_cost
= {
491 COSTS_N_INSNS (4), /* mulsi */
492 COSTS_N_INSNS (4), /* mulsi_const */
493 COSTS_N_INSNS (4), /* mulsi_const9 */
494 COSTS_N_INSNS (4), /* muldi */
495 COSTS_N_INSNS (11), /* divsi */
496 COSTS_N_INSNS (11), /* divdi */
497 COSTS_N_INSNS (6), /* fp */
498 COSTS_N_INSNS (6), /* dmul */
499 COSTS_N_INSNS (19), /* sdiv */
500 COSTS_N_INSNS (33), /* ddiv */
501 32, /* l1 cache line size */
507 /* Instruction costs on PPC601 processors. */
509 struct processor_costs ppc601_cost
= {
510 COSTS_N_INSNS (5), /* mulsi */
511 COSTS_N_INSNS (5), /* mulsi_const */
512 COSTS_N_INSNS (5), /* mulsi_const9 */
513 COSTS_N_INSNS (5), /* muldi */
514 COSTS_N_INSNS (36), /* divsi */
515 COSTS_N_INSNS (36), /* divdi */
516 COSTS_N_INSNS (4), /* fp */
517 COSTS_N_INSNS (5), /* dmul */
518 COSTS_N_INSNS (17), /* sdiv */
519 COSTS_N_INSNS (31), /* ddiv */
520 32, /* cache line size */
526 /* Instruction costs on PPC603 processors. */
528 struct processor_costs ppc603_cost
= {
529 COSTS_N_INSNS (5), /* mulsi */
530 COSTS_N_INSNS (3), /* mulsi_const */
531 COSTS_N_INSNS (2), /* mulsi_const9 */
532 COSTS_N_INSNS (5), /* muldi */
533 COSTS_N_INSNS (37), /* divsi */
534 COSTS_N_INSNS (37), /* divdi */
535 COSTS_N_INSNS (3), /* fp */
536 COSTS_N_INSNS (4), /* dmul */
537 COSTS_N_INSNS (18), /* sdiv */
538 COSTS_N_INSNS (33), /* ddiv */
539 32, /* cache line size */
545 /* Instruction costs on PPC604 processors. */
547 struct processor_costs ppc604_cost
= {
548 COSTS_N_INSNS (4), /* mulsi */
549 COSTS_N_INSNS (4), /* mulsi_const */
550 COSTS_N_INSNS (4), /* mulsi_const9 */
551 COSTS_N_INSNS (4), /* muldi */
552 COSTS_N_INSNS (20), /* divsi */
553 COSTS_N_INSNS (20), /* divdi */
554 COSTS_N_INSNS (3), /* fp */
555 COSTS_N_INSNS (3), /* dmul */
556 COSTS_N_INSNS (18), /* sdiv */
557 COSTS_N_INSNS (32), /* ddiv */
558 32, /* cache line size */
564 /* Instruction costs on PPC604e processors. */
566 struct processor_costs ppc604e_cost
= {
567 COSTS_N_INSNS (2), /* mulsi */
568 COSTS_N_INSNS (2), /* mulsi_const */
569 COSTS_N_INSNS (2), /* mulsi_const9 */
570 COSTS_N_INSNS (2), /* muldi */
571 COSTS_N_INSNS (20), /* divsi */
572 COSTS_N_INSNS (20), /* divdi */
573 COSTS_N_INSNS (3), /* fp */
574 COSTS_N_INSNS (3), /* dmul */
575 COSTS_N_INSNS (18), /* sdiv */
576 COSTS_N_INSNS (32), /* ddiv */
577 32, /* cache line size */
583 /* Instruction costs on PPC620 processors. */
585 struct processor_costs ppc620_cost
= {
586 COSTS_N_INSNS (5), /* mulsi */
587 COSTS_N_INSNS (4), /* mulsi_const */
588 COSTS_N_INSNS (3), /* mulsi_const9 */
589 COSTS_N_INSNS (7), /* muldi */
590 COSTS_N_INSNS (21), /* divsi */
591 COSTS_N_INSNS (37), /* divdi */
592 COSTS_N_INSNS (3), /* fp */
593 COSTS_N_INSNS (3), /* dmul */
594 COSTS_N_INSNS (18), /* sdiv */
595 COSTS_N_INSNS (32), /* ddiv */
596 128, /* cache line size */
602 /* Instruction costs on PPC630 processors. */
604 struct processor_costs ppc630_cost
= {
605 COSTS_N_INSNS (5), /* mulsi */
606 COSTS_N_INSNS (4), /* mulsi_const */
607 COSTS_N_INSNS (3), /* mulsi_const9 */
608 COSTS_N_INSNS (7), /* muldi */
609 COSTS_N_INSNS (21), /* divsi */
610 COSTS_N_INSNS (37), /* divdi */
611 COSTS_N_INSNS (3), /* fp */
612 COSTS_N_INSNS (3), /* dmul */
613 COSTS_N_INSNS (17), /* sdiv */
614 COSTS_N_INSNS (21), /* ddiv */
615 128, /* cache line size */
621 /* Instruction costs on Cell processor. */
622 /* COSTS_N_INSNS (1) ~ one add. */
624 struct processor_costs ppccell_cost
= {
625 COSTS_N_INSNS (9/2)+2, /* mulsi */
626 COSTS_N_INSNS (6/2), /* mulsi_const */
627 COSTS_N_INSNS (6/2), /* mulsi_const9 */
628 COSTS_N_INSNS (15/2)+2, /* muldi */
629 COSTS_N_INSNS (38/2), /* divsi */
630 COSTS_N_INSNS (70/2), /* divdi */
631 COSTS_N_INSNS (10/2), /* fp */
632 COSTS_N_INSNS (10/2), /* dmul */
633 COSTS_N_INSNS (74/2), /* sdiv */
634 COSTS_N_INSNS (74/2), /* ddiv */
635 128, /* cache line size */
641 /* Instruction costs on PPC750 and PPC7400 processors. */
643 struct processor_costs ppc750_cost
= {
644 COSTS_N_INSNS (5), /* mulsi */
645 COSTS_N_INSNS (3), /* mulsi_const */
646 COSTS_N_INSNS (2), /* mulsi_const9 */
647 COSTS_N_INSNS (5), /* muldi */
648 COSTS_N_INSNS (17), /* divsi */
649 COSTS_N_INSNS (17), /* divdi */
650 COSTS_N_INSNS (3), /* fp */
651 COSTS_N_INSNS (3), /* dmul */
652 COSTS_N_INSNS (17), /* sdiv */
653 COSTS_N_INSNS (31), /* ddiv */
654 32, /* cache line size */
660 /* Instruction costs on PPC7450 processors. */
662 struct processor_costs ppc7450_cost
= {
663 COSTS_N_INSNS (4), /* mulsi */
664 COSTS_N_INSNS (3), /* mulsi_const */
665 COSTS_N_INSNS (3), /* mulsi_const9 */
666 COSTS_N_INSNS (4), /* muldi */
667 COSTS_N_INSNS (23), /* divsi */
668 COSTS_N_INSNS (23), /* divdi */
669 COSTS_N_INSNS (5), /* fp */
670 COSTS_N_INSNS (5), /* dmul */
671 COSTS_N_INSNS (21), /* sdiv */
672 COSTS_N_INSNS (35), /* ddiv */
673 32, /* cache line size */
679 /* Instruction costs on PPC8540 processors. */
681 struct processor_costs ppc8540_cost
= {
682 COSTS_N_INSNS (4), /* mulsi */
683 COSTS_N_INSNS (4), /* mulsi_const */
684 COSTS_N_INSNS (4), /* mulsi_const9 */
685 COSTS_N_INSNS (4), /* muldi */
686 COSTS_N_INSNS (19), /* divsi */
687 COSTS_N_INSNS (19), /* divdi */
688 COSTS_N_INSNS (4), /* fp */
689 COSTS_N_INSNS (4), /* dmul */
690 COSTS_N_INSNS (29), /* sdiv */
691 COSTS_N_INSNS (29), /* ddiv */
692 32, /* cache line size */
695 1, /* prefetch streams /*/
698 /* Instruction costs on E300C2 and E300C3 cores. */
700 struct processor_costs ppce300c2c3_cost
= {
701 COSTS_N_INSNS (4), /* mulsi */
702 COSTS_N_INSNS (4), /* mulsi_const */
703 COSTS_N_INSNS (4), /* mulsi_const9 */
704 COSTS_N_INSNS (4), /* muldi */
705 COSTS_N_INSNS (19), /* divsi */
706 COSTS_N_INSNS (19), /* divdi */
707 COSTS_N_INSNS (3), /* fp */
708 COSTS_N_INSNS (4), /* dmul */
709 COSTS_N_INSNS (18), /* sdiv */
710 COSTS_N_INSNS (33), /* ddiv */
714 1, /* prefetch streams /*/
717 /* Instruction costs on PPCE500MC processors. */
719 struct processor_costs ppce500mc_cost
= {
720 COSTS_N_INSNS (4), /* mulsi */
721 COSTS_N_INSNS (4), /* mulsi_const */
722 COSTS_N_INSNS (4), /* mulsi_const9 */
723 COSTS_N_INSNS (4), /* muldi */
724 COSTS_N_INSNS (14), /* divsi */
725 COSTS_N_INSNS (14), /* divdi */
726 COSTS_N_INSNS (8), /* fp */
727 COSTS_N_INSNS (10), /* dmul */
728 COSTS_N_INSNS (36), /* sdiv */
729 COSTS_N_INSNS (66), /* ddiv */
730 64, /* cache line size */
733 1, /* prefetch streams /*/
736 /* Instruction costs on PPCE500MC64 processors. */
738 struct processor_costs ppce500mc64_cost
= {
739 COSTS_N_INSNS (4), /* mulsi */
740 COSTS_N_INSNS (4), /* mulsi_const */
741 COSTS_N_INSNS (4), /* mulsi_const9 */
742 COSTS_N_INSNS (4), /* muldi */
743 COSTS_N_INSNS (14), /* divsi */
744 COSTS_N_INSNS (14), /* divdi */
745 COSTS_N_INSNS (4), /* fp */
746 COSTS_N_INSNS (10), /* dmul */
747 COSTS_N_INSNS (36), /* sdiv */
748 COSTS_N_INSNS (66), /* ddiv */
749 64, /* cache line size */
752 1, /* prefetch streams /*/
755 /* Instruction costs on AppliedMicro Titan processors. */
757 struct processor_costs titan_cost
= {
758 COSTS_N_INSNS (5), /* mulsi */
759 COSTS_N_INSNS (5), /* mulsi_const */
760 COSTS_N_INSNS (5), /* mulsi_const9 */
761 COSTS_N_INSNS (5), /* muldi */
762 COSTS_N_INSNS (18), /* divsi */
763 COSTS_N_INSNS (18), /* divdi */
764 COSTS_N_INSNS (10), /* fp */
765 COSTS_N_INSNS (10), /* dmul */
766 COSTS_N_INSNS (46), /* sdiv */
767 COSTS_N_INSNS (72), /* ddiv */
768 32, /* cache line size */
771 1, /* prefetch streams /*/
774 /* Instruction costs on POWER4 and POWER5 processors. */
776 struct processor_costs power4_cost
= {
777 COSTS_N_INSNS (3), /* mulsi */
778 COSTS_N_INSNS (2), /* mulsi_const */
779 COSTS_N_INSNS (2), /* mulsi_const9 */
780 COSTS_N_INSNS (4), /* muldi */
781 COSTS_N_INSNS (18), /* divsi */
782 COSTS_N_INSNS (34), /* divdi */
783 COSTS_N_INSNS (3), /* fp */
784 COSTS_N_INSNS (3), /* dmul */
785 COSTS_N_INSNS (17), /* sdiv */
786 COSTS_N_INSNS (17), /* ddiv */
787 128, /* cache line size */
790 8, /* prefetch streams /*/
793 /* Instruction costs on POWER6 processors. */
795 struct processor_costs power6_cost
= {
796 COSTS_N_INSNS (8), /* mulsi */
797 COSTS_N_INSNS (8), /* mulsi_const */
798 COSTS_N_INSNS (8), /* mulsi_const9 */
799 COSTS_N_INSNS (8), /* muldi */
800 COSTS_N_INSNS (22), /* divsi */
801 COSTS_N_INSNS (28), /* divdi */
802 COSTS_N_INSNS (3), /* fp */
803 COSTS_N_INSNS (3), /* dmul */
804 COSTS_N_INSNS (13), /* sdiv */
805 COSTS_N_INSNS (16), /* ddiv */
806 128, /* cache line size */
809 16, /* prefetch streams */
812 /* Instruction costs on POWER7 processors. */
814 struct processor_costs power7_cost
= {
815 COSTS_N_INSNS (2), /* mulsi */
816 COSTS_N_INSNS (2), /* mulsi_const */
817 COSTS_N_INSNS (2), /* mulsi_const9 */
818 COSTS_N_INSNS (2), /* muldi */
819 COSTS_N_INSNS (18), /* divsi */
820 COSTS_N_INSNS (34), /* divdi */
821 COSTS_N_INSNS (3), /* fp */
822 COSTS_N_INSNS (3), /* dmul */
823 COSTS_N_INSNS (13), /* sdiv */
824 COSTS_N_INSNS (16), /* ddiv */
825 128, /* cache line size */
828 12, /* prefetch streams */
831 /* Instruction costs on POWER A2 processors. */
833 struct processor_costs ppca2_cost
= {
834 COSTS_N_INSNS (16), /* mulsi */
835 COSTS_N_INSNS (16), /* mulsi_const */
836 COSTS_N_INSNS (16), /* mulsi_const9 */
837 COSTS_N_INSNS (16), /* muldi */
838 COSTS_N_INSNS (22), /* divsi */
839 COSTS_N_INSNS (28), /* divdi */
840 COSTS_N_INSNS (3), /* fp */
841 COSTS_N_INSNS (3), /* dmul */
842 COSTS_N_INSNS (59), /* sdiv */
843 COSTS_N_INSNS (72), /* ddiv */
847 16, /* prefetch streams */
851 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
852 #undef RS6000_BUILTIN
853 #undef RS6000_BUILTIN_EQUATE
854 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
855 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
857 static const enum rs6000_btc builtin_classify
[(int)RS6000_BUILTIN_COUNT
] =
859 #include "rs6000-builtin.def"
862 #undef RS6000_BUILTIN
863 #undef RS6000_BUILTIN_EQUATE
865 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
866 static tree (*rs6000_veclib_handler
) (tree
, tree
, tree
);
869 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
870 static const char *rs6000_invalid_within_doloop (const_rtx
);
871 static bool rs6000_legitimate_address_p (enum machine_mode
, rtx
, bool);
872 static bool rs6000_debug_legitimate_address_p (enum machine_mode
, rtx
, bool);
873 static rtx
rs6000_generate_compare (rtx
, enum machine_mode
);
874 static void rs6000_emit_stack_tie (void);
875 static bool spe_func_has_64bit_regs_p (void);
876 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
877 static unsigned rs6000_hash_constant (rtx
);
878 static unsigned toc_hash_function (const void *);
879 static int toc_hash_eq (const void *, const void *);
880 static bool reg_offset_addressing_ok_p (enum machine_mode
);
881 static bool virtual_stack_registers_memory_p (rtx
);
882 static bool constant_pool_expr_p (rtx
);
883 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
884 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
885 static struct machine_function
* rs6000_init_machine_status (void);
886 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
887 static bool no_global_regs_above (int, bool);
888 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
889 static void rs6000_assemble_visibility (tree
, int);
891 static int rs6000_ra_ever_killed (void);
892 static bool rs6000_attribute_takes_identifier_p (const_tree
);
893 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
894 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
895 static bool rs6000_ms_bitfield_layout_p (const_tree
);
896 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
897 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
898 static const char *rs6000_mangle_type (const_tree
);
899 static void rs6000_set_default_type_attributes (tree
);
900 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
901 static rtx
rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
902 static bool rs6000_reg_live_or_pic_offset_p (int);
903 static tree
rs6000_builtin_vectorized_libmass (tree
, tree
, tree
);
904 static tree
rs6000_builtin_vectorized_function (tree
, tree
, tree
);
905 static void rs6000_restore_saved_cr (rtx
, int);
906 static bool rs6000_output_addr_const_extra (FILE *, rtx
);
907 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
908 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
909 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
911 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
912 static bool rs6000_return_in_memory (const_tree
, const_tree
);
913 static rtx
rs6000_function_value (const_tree
, const_tree
, bool);
914 static void rs6000_file_start (void);
916 static int rs6000_elf_reloc_rw_mask (void);
917 static void rs6000_elf_asm_out_constructor (rtx
, int) ATTRIBUTE_UNUSED
;
918 static void rs6000_elf_asm_out_destructor (rtx
, int) ATTRIBUTE_UNUSED
;
919 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED
;
920 static void rs6000_elf_asm_init_sections (void);
921 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
922 unsigned HOST_WIDE_INT
);
923 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
926 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
927 static void rs6000_alloc_sdmode_stack_slot (void);
928 static void rs6000_instantiate_decls (void);
930 static void rs6000_xcoff_asm_output_anchor (rtx
);
931 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
932 static void rs6000_xcoff_asm_init_sections (void);
933 static int rs6000_xcoff_reloc_rw_mask (void);
934 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
935 static section
*rs6000_xcoff_select_section (tree
, int,
936 unsigned HOST_WIDE_INT
);
937 static void rs6000_xcoff_unique_section (tree
, int);
938 static section
*rs6000_xcoff_select_rtx_section
939 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
940 static const char * rs6000_xcoff_strip_name_encoding (const char *);
941 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
942 static void rs6000_xcoff_file_start (void);
943 static void rs6000_xcoff_file_end (void);
945 static int rs6000_variable_issue (FILE *, int, rtx
, int);
946 static int rs6000_register_move_cost (enum machine_mode
,
947 reg_class_t
, reg_class_t
);
948 static int rs6000_memory_move_cost (enum machine_mode
, reg_class_t
, bool);
949 static bool rs6000_rtx_costs (rtx
, int, int, int, int *, bool);
950 static bool rs6000_debug_rtx_costs (rtx
, int, int, int, int *, bool);
951 static int rs6000_debug_address_cost (rtx
, bool);
952 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
953 static int rs6000_debug_adjust_cost (rtx
, rtx
, rtx
, int);
954 static void rs6000_sched_init (FILE *, int, int);
955 static bool is_microcoded_insn (rtx
);
956 static bool is_nonpipeline_insn (rtx
);
957 static bool is_cracked_insn (rtx
);
958 static bool is_branch_slot_insn (rtx
);
959 static bool is_load_insn (rtx
);
960 static rtx
get_store_dest (rtx pat
);
961 static bool is_store_insn (rtx
);
962 static bool set_to_load_agen (rtx
,rtx
);
963 static bool adjacent_mem_locations (rtx
,rtx
);
964 static int rs6000_adjust_priority (rtx
, int);
965 static int rs6000_issue_rate (void);
966 static bool rs6000_is_costly_dependence (dep_t
, int, int);
967 static rtx
get_next_active_insn (rtx
, rtx
);
968 static bool insn_terminates_group_p (rtx
, enum group_termination
);
969 static bool insn_must_be_first_in_group (rtx
);
970 static bool insn_must_be_last_in_group (rtx
);
971 static bool is_costly_group (rtx
*, rtx
);
972 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
973 static int redefine_groups (FILE *, int, rtx
, rtx
);
974 static int pad_groups (FILE *, int, rtx
, rtx
);
975 static void rs6000_sched_finish (FILE *, int);
976 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
977 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
978 static int rs6000_use_sched_lookahead (void);
979 static int rs6000_use_sched_lookahead_guard (rtx
);
980 static void * rs6000_alloc_sched_context (void);
981 static void rs6000_init_sched_context (void *, bool);
982 static void rs6000_set_sched_context (void *);
983 static void rs6000_free_sched_context (void *);
984 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
985 static tree
rs6000_builtin_mask_for_load (void);
986 static tree
rs6000_builtin_mul_widen_even (tree
);
987 static tree
rs6000_builtin_mul_widen_odd (tree
);
988 static tree
rs6000_builtin_conversion (unsigned int, 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 int rs6000_loop_align_max_skip (rtx
);
1046 static int first_altivec_reg_to_save (void);
1047 static unsigned int compute_vrsave_mask (void);
1048 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
1049 static void is_altivec_return_reg (rtx
, void *);
1050 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
1051 int easy_vector_constant (rtx
, enum machine_mode
);
1052 static rtx
rs6000_dwarf_register_span (rtx
);
1053 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
1054 static rtx
rs6000_legitimize_address (rtx
, rtx
, enum machine_mode
);
1055 static rtx
rs6000_debug_legitimize_address (rtx
, rtx
, enum machine_mode
);
1056 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
1057 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
1058 static rtx
rs6000_delegitimize_address (rtx
);
1059 static rtx
rs6000_tls_get_addr (void);
1060 static rtx
rs6000_got_sym (void);
1061 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
1062 static const char *rs6000_get_some_local_dynamic_name (void);
1063 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
1064 static rtx
rs6000_complex_function_value (enum machine_mode
);
1065 static rtx
rs6000_spe_function_arg (const CUMULATIVE_ARGS
*,
1066 enum machine_mode
, const_tree
);
1067 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
1068 HOST_WIDE_INT
, int);
1069 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
1072 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
1075 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
1076 const_tree
, HOST_WIDE_INT
,
1078 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, bool, bool);
1079 static rtx
rs6000_mixed_function_arg (enum machine_mode
, const_tree
, int);
1080 static void rs6000_function_arg_advance (cumulative_args_t
, enum machine_mode
,
1082 static rtx
rs6000_function_arg (cumulative_args_t
, enum machine_mode
,
1084 static unsigned int rs6000_function_arg_boundary (enum machine_mode
,
1086 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
1087 static void setup_incoming_varargs (cumulative_args_t
,
1088 enum machine_mode
, tree
,
1090 static bool rs6000_pass_by_reference (cumulative_args_t
, enum machine_mode
,
1092 static int rs6000_arg_partial_bytes (cumulative_args_t
, enum machine_mode
,
1094 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
1096 static void macho_branch_islands (void);
1097 static int no_previous_def (tree function_name
);
1098 static tree
get_prev_label (tree function_name
);
1099 static void rs6000_darwin_file_start (void);
1102 static tree
rs6000_build_builtin_va_list (void);
1103 static void rs6000_va_start (tree
, rtx
);
1104 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
1105 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
1106 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
1107 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
1108 static rtx
rs6000_emit_vector_compare_inner (enum rtx_code
, rtx
, rtx
);
1109 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
1111 static tree
rs6000_stack_protect_fail (void);
1113 static rtx
rs6000_legitimize_reload_address (rtx
, enum machine_mode
, int, int,
1116 static rtx
rs6000_debug_legitimize_reload_address (rtx
, enum machine_mode
, int,
1119 rtx (*rs6000_legitimize_reload_address_ptr
) (rtx
, enum machine_mode
, int, int,
1121 = rs6000_legitimize_reload_address
;
1123 static bool rs6000_mode_dependent_address_p (const_rtx
);
1124 static bool rs6000_mode_dependent_address (const_rtx
);
1125 static bool rs6000_debug_mode_dependent_address (const_rtx
);
1126 static bool (*rs6000_mode_dependent_address_ptr
) (const_rtx
)
1127 = rs6000_mode_dependent_address
;
1129 static enum reg_class
rs6000_secondary_reload_class (enum reg_class
,
1130 enum machine_mode
, rtx
);
1131 static enum reg_class
rs6000_debug_secondary_reload_class (enum reg_class
,
1134 enum reg_class (*rs6000_secondary_reload_class_ptr
) (enum reg_class
,
1135 enum machine_mode
, rtx
)
1136 = rs6000_secondary_reload_class
;
1138 static enum reg_class
rs6000_preferred_reload_class (rtx
, enum reg_class
);
1139 static enum reg_class
rs6000_debug_preferred_reload_class (rtx
,
1141 enum reg_class (*rs6000_preferred_reload_class_ptr
) (rtx
, enum reg_class
)
1142 = rs6000_preferred_reload_class
;
1144 static bool rs6000_secondary_memory_needed (enum reg_class
, enum reg_class
,
1147 static bool rs6000_debug_secondary_memory_needed (enum reg_class
,
1151 bool (*rs6000_secondary_memory_needed_ptr
) (enum reg_class
, enum reg_class
,
1153 = rs6000_secondary_memory_needed
;
1155 static bool rs6000_cannot_change_mode_class (enum machine_mode
,
1158 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode
,
1162 bool (*rs6000_cannot_change_mode_class_ptr
) (enum machine_mode
,
1165 = rs6000_cannot_change_mode_class
;
1167 static reg_class_t
rs6000_secondary_reload (bool, rtx
, reg_class_t
,
1169 struct secondary_reload_info
*);
1171 const int INSN_NOT_AVAILABLE
= -1;
1172 static enum machine_mode
rs6000_eh_return_filter_mode (void);
1173 static bool rs6000_can_eliminate (const int, const int);
1174 static void rs6000_conditional_register_usage (void);
1175 static void rs6000_trampoline_init (rtx
, tree
, rtx
);
1176 static bool rs6000_cannot_force_const_mem (enum machine_mode
, rtx
);
1177 static bool rs6000_legitimate_constant_p (enum machine_mode
, rtx
);
1178 static bool rs6000_save_toc_in_prologue_p (void);
1179 static void rs6000_code_end (void) ATTRIBUTE_UNUSED
;
1181 /* Hash table stuff for keeping track of TOC entries. */
1183 struct GTY(()) toc_hash_struct
1185 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1186 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1188 enum machine_mode key_mode
;
1192 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
1194 /* Hash table to keep track of the argument types for builtin functions. */
1196 struct GTY(()) builtin_hash_struct
1199 enum machine_mode mode
[4]; /* return value + 3 arguments. */
1200 unsigned char uns_p
[4]; /* and whether the types are unsigned. */
1203 static GTY ((param_is (struct builtin_hash_struct
))) htab_t builtin_hash_table
;
1205 static bool rs6000_valid_attribute_p (tree
, tree
, tree
, int);
1206 static void rs6000_function_specific_save (struct cl_target_option
*);
1207 static void rs6000_function_specific_restore (struct cl_target_option
*);
1208 static void rs6000_function_specific_print (FILE *, int,
1209 struct cl_target_option
*);
1210 static bool rs6000_can_inline_p (tree
, tree
);
1211 static void rs6000_set_current_function (tree
);
1214 /* Default register names. */
1215 char rs6000_reg_names
[][8] =
1217 "0", "1", "2", "3", "4", "5", "6", "7",
1218 "8", "9", "10", "11", "12", "13", "14", "15",
1219 "16", "17", "18", "19", "20", "21", "22", "23",
1220 "24", "25", "26", "27", "28", "29", "30", "31",
1221 "0", "1", "2", "3", "4", "5", "6", "7",
1222 "8", "9", "10", "11", "12", "13", "14", "15",
1223 "16", "17", "18", "19", "20", "21", "22", "23",
1224 "24", "25", "26", "27", "28", "29", "30", "31",
1225 "mq", "lr", "ctr","ap",
1226 "0", "1", "2", "3", "4", "5", "6", "7",
1228 /* AltiVec registers. */
1229 "0", "1", "2", "3", "4", "5", "6", "7",
1230 "8", "9", "10", "11", "12", "13", "14", "15",
1231 "16", "17", "18", "19", "20", "21", "22", "23",
1232 "24", "25", "26", "27", "28", "29", "30", "31",
1234 /* SPE registers. */
1235 "spe_acc", "spefscr",
1236 /* Soft frame pointer. */
1240 #ifdef TARGET_REGNAMES
1241 static const char alt_reg_names
[][8] =
1243 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1244 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1245 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1246 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1247 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1248 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1249 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1250 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1251 "mq", "lr", "ctr", "ap",
1252 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1254 /* AltiVec registers. */
1255 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1256 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1257 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1258 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1260 /* SPE registers. */
1261 "spe_acc", "spefscr",
1262 /* Soft frame pointer. */
1267 /* Table of valid machine attributes. */
1269 static const struct attribute_spec rs6000_attribute_table
[] =
1271 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1272 affects_type_identity } */
1273 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
,
1275 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
,
1277 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
,
1279 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
,
1281 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
,
1283 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1284 SUBTARGET_ATTRIBUTE_TABLE
,
1286 { NULL
, 0, 0, false, false, false, NULL
, false }
1289 #ifndef MASK_STRICT_ALIGN
1290 #define MASK_STRICT_ALIGN 0
1292 #ifndef TARGET_PROFILE_KERNEL
1293 #define TARGET_PROFILE_KERNEL 0
1296 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1297 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1299 /* Initialize the GCC target structure. */
1300 #undef TARGET_ATTRIBUTE_TABLE
1301 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1302 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1303 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1304 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1305 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1307 #undef TARGET_ASM_ALIGNED_DI_OP
1308 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1310 /* Default unaligned ops are only provided for ELF. Find the ops needed
1311 for non-ELF systems. */
1312 #ifndef OBJECT_FORMAT_ELF
1314 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1316 #undef TARGET_ASM_UNALIGNED_HI_OP
1317 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1318 #undef TARGET_ASM_UNALIGNED_SI_OP
1319 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1320 #undef TARGET_ASM_UNALIGNED_DI_OP
1321 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1324 #undef TARGET_ASM_UNALIGNED_HI_OP
1325 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1326 #undef TARGET_ASM_UNALIGNED_SI_OP
1327 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1328 #undef TARGET_ASM_UNALIGNED_DI_OP
1329 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1330 #undef TARGET_ASM_ALIGNED_DI_OP
1331 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1335 /* This hook deals with fixups for relocatable code and DI-mode objects
1337 #undef TARGET_ASM_INTEGER
1338 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1340 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
1341 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1342 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1345 #undef TARGET_HAVE_TLS
1346 #define TARGET_HAVE_TLS HAVE_AS_TLS
1348 #undef TARGET_CANNOT_FORCE_CONST_MEM
1349 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1351 #undef TARGET_DELEGITIMIZE_ADDRESS
1352 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1354 #undef TARGET_ASM_FUNCTION_PROLOGUE
1355 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1356 #undef TARGET_ASM_FUNCTION_EPILOGUE
1357 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1359 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1360 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1362 #undef TARGET_LEGITIMIZE_ADDRESS
1363 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1365 #undef TARGET_SCHED_VARIABLE_ISSUE
1366 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1368 #undef TARGET_SCHED_ISSUE_RATE
1369 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1370 #undef TARGET_SCHED_ADJUST_COST
1371 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1372 #undef TARGET_SCHED_ADJUST_PRIORITY
1373 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1374 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1375 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1376 #undef TARGET_SCHED_INIT
1377 #define TARGET_SCHED_INIT rs6000_sched_init
1378 #undef TARGET_SCHED_FINISH
1379 #define TARGET_SCHED_FINISH rs6000_sched_finish
1380 #undef TARGET_SCHED_REORDER
1381 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1382 #undef TARGET_SCHED_REORDER2
1383 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1385 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1386 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1388 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1389 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1391 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1392 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1393 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1394 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1395 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1396 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1397 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1398 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1400 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1401 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1402 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1403 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1404 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1405 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1406 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1407 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1408 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1409 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1410 rs6000_builtin_support_vector_misalignment
1411 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1412 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1413 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1414 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1415 rs6000_builtin_vectorization_cost
1416 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1417 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1418 rs6000_preferred_simd_mode
1420 #undef TARGET_INIT_BUILTINS
1421 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1422 #undef TARGET_BUILTIN_DECL
1423 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1425 #undef TARGET_EXPAND_BUILTIN
1426 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1428 #undef TARGET_MANGLE_TYPE
1429 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1431 #undef TARGET_INIT_LIBFUNCS
1432 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1435 #undef TARGET_BINDS_LOCAL_P
1436 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1439 #undef TARGET_MS_BITFIELD_LAYOUT_P
1440 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1442 #undef TARGET_ASM_OUTPUT_MI_THUNK
1443 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1445 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1446 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1448 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1449 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1451 #undef TARGET_INVALID_WITHIN_DOLOOP
1452 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1454 #undef TARGET_REGISTER_MOVE_COST
1455 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1456 #undef TARGET_MEMORY_MOVE_COST
1457 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1458 #undef TARGET_RTX_COSTS
1459 #define TARGET_RTX_COSTS rs6000_rtx_costs
1460 #undef TARGET_ADDRESS_COST
1461 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1463 #undef TARGET_DWARF_REGISTER_SPAN
1464 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1466 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1467 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1469 /* On rs6000, function arguments are promoted, as are function return
1471 #undef TARGET_PROMOTE_FUNCTION_MODE
1472 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1474 #undef TARGET_RETURN_IN_MEMORY
1475 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1477 #undef TARGET_SETUP_INCOMING_VARARGS
1478 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1480 /* Always strict argument naming on rs6000. */
1481 #undef TARGET_STRICT_ARGUMENT_NAMING
1482 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1483 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1484 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1485 #undef TARGET_SPLIT_COMPLEX_ARG
1486 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1487 #undef TARGET_MUST_PASS_IN_STACK
1488 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1489 #undef TARGET_PASS_BY_REFERENCE
1490 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1491 #undef TARGET_ARG_PARTIAL_BYTES
1492 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1493 #undef TARGET_FUNCTION_ARG_ADVANCE
1494 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1495 #undef TARGET_FUNCTION_ARG
1496 #define TARGET_FUNCTION_ARG rs6000_function_arg
1497 #undef TARGET_FUNCTION_ARG_BOUNDARY
1498 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1500 #undef TARGET_BUILD_BUILTIN_VA_LIST
1501 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1503 #undef TARGET_EXPAND_BUILTIN_VA_START
1504 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1506 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1507 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1509 #undef TARGET_EH_RETURN_FILTER_MODE
1510 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1512 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1513 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1515 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1516 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1518 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1519 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1521 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1522 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1524 #undef TARGET_OPTION_OVERRIDE
1525 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1527 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1528 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1529 rs6000_builtin_vectorized_function
1531 #ifndef TARGET_MACHO
1532 #undef TARGET_STACK_PROTECT_FAIL
1533 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1536 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1537 The PowerPC architecture requires only weak consistency among
1538 processors--that is, memory accesses between processors need not be
1539 sequentially consistent and memory accesses among processors can occur
1540 in any order. The ability to order memory accesses weakly provides
1541 opportunities for more efficient use of the system bus. Unless a
1542 dependency exists, the 604e allows read operations to precede store
1544 #undef TARGET_RELAXED_ORDERING
1545 #define TARGET_RELAXED_ORDERING true
1548 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1549 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1552 /* Use a 32-bit anchor range. This leads to sequences like:
1554 addis tmp,anchor,high
1557 where tmp itself acts as an anchor, and can be shared between
1558 accesses to the same 64k page. */
1559 #undef TARGET_MIN_ANCHOR_OFFSET
1560 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1561 #undef TARGET_MAX_ANCHOR_OFFSET
1562 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1563 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1564 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1566 #undef TARGET_BUILTIN_RECIPROCAL
1567 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1569 #undef TARGET_EXPAND_TO_RTL_HOOK
1570 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1572 #undef TARGET_INSTANTIATE_DECLS
1573 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1575 #undef TARGET_SECONDARY_RELOAD
1576 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1578 #undef TARGET_LEGITIMATE_ADDRESS_P
1579 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1581 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1582 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1584 #undef TARGET_CAN_ELIMINATE
1585 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1587 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1588 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1590 #undef TARGET_TRAMPOLINE_INIT
1591 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1593 #undef TARGET_FUNCTION_VALUE
1594 #define TARGET_FUNCTION_VALUE rs6000_function_value
1596 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1597 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1599 #undef TARGET_OPTION_SAVE
1600 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1602 #undef TARGET_OPTION_RESTORE
1603 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1605 #undef TARGET_OPTION_PRINT
1606 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1608 #undef TARGET_CAN_INLINE_P
1609 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1611 #undef TARGET_SET_CURRENT_FUNCTION
1612 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1614 #undef TARGET_LEGITIMATE_CONSTANT_P
1615 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1619 /* Simplifications for entries below. */
1622 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1623 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1626 /* Some OSs don't support saving the high part of 64-bit registers on context
1627 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1628 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1629 either, the user must explicitly specify them and we won't interfere with
1630 the user's specification. */
1633 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1634 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1635 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1636 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1637 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
1638 | MASK_POPCNTD
| MASK_VSX
| MASK_ISEL
| MASK_NO_UPDATE
1639 | MASK_RECIP_PRECISION
)
1642 /* Masks for instructions set at various powerpc ISAs. */
1644 ISA_2_1_MASKS
= MASK_MFCRF
,
1645 ISA_2_2_MASKS
= (ISA_2_1_MASKS
| MASK_POPCNTB
),
1646 ISA_2_4_MASKS
= (ISA_2_2_MASKS
| MASK_FPRND
),
1648 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1649 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1650 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1651 server and embedded. */
1652 ISA_2_5_MASKS_EMBEDDED
= (ISA_2_2_MASKS
| MASK_CMPB
| MASK_RECIP_PRECISION
1653 | MASK_PPC_GFXOPT
| MASK_PPC_GPOPT
),
1654 ISA_2_5_MASKS_SERVER
= (ISA_2_5_MASKS_EMBEDDED
| MASK_DFP
),
1656 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1657 altivec is a win so enable it. */
1658 ISA_2_6_MASKS_EMBEDDED
= (ISA_2_5_MASKS_EMBEDDED
| MASK_POPCNTD
),
1659 ISA_2_6_MASKS_SERVER
= (ISA_2_5_MASKS_SERVER
| MASK_POPCNTD
| MASK_ALTIVEC
1665 const char *const name
; /* Canonical processor name. */
1666 const enum processor_type processor
; /* Processor type enum value. */
1667 const int target_enable
; /* Target flags to enable. */
1670 static struct rs6000_ptt
const processor_target_table
[] =
1672 #define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
1673 #include "rs6000-cpus.def"
1677 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1681 rs6000_cpu_name_lookup (const char *name
)
1687 for (i
= 0; i
< ARRAY_SIZE (processor_target_table
); i
++)
1688 if (! strcmp (name
, processor_target_table
[i
].name
))
1696 /* Return number of consecutive hard regs needed starting at reg REGNO
1697 to hold something of mode MODE.
1698 This is ordinarily the length in words of a value of mode MODE
1699 but can be less for certain modes in special long registers.
1701 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1702 scalar instructions. The upper 32 bits are only available to the
1705 POWER and PowerPC GPRs hold 32 bits worth;
1706 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1709 rs6000_hard_regno_nregs_internal (int regno
, enum machine_mode mode
)
1711 unsigned HOST_WIDE_INT reg_size
;
1713 if (FP_REGNO_P (regno
))
1714 reg_size
= (VECTOR_MEM_VSX_P (mode
)
1715 ? UNITS_PER_VSX_WORD
1716 : UNITS_PER_FP_WORD
);
1718 else if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1719 reg_size
= UNITS_PER_SPE_WORD
;
1721 else if (ALTIVEC_REGNO_P (regno
))
1722 reg_size
= UNITS_PER_ALTIVEC_WORD
;
1724 /* The value returned for SCmode in the E500 double case is 2 for
1725 ABI compatibility; storing an SCmode value in a single register
1726 would require function_arg and rs6000_spe_function_arg to handle
1727 SCmode so as to pass the value correctly in a pair of
1729 else if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
1730 && !DECIMAL_FLOAT_MODE_P (mode
))
1731 reg_size
= UNITS_PER_FP_WORD
;
1734 reg_size
= UNITS_PER_WORD
;
1736 return (GET_MODE_SIZE (mode
) + reg_size
- 1) / reg_size
;
1739 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1742 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1744 int last_regno
= regno
+ rs6000_hard_regno_nregs
[mode
][regno
] - 1;
1746 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1747 implementations. Don't allow an item to be split between a FP register
1748 and an Altivec register. */
1749 if (VECTOR_MEM_VSX_P (mode
))
1751 if (FP_REGNO_P (regno
))
1752 return FP_REGNO_P (last_regno
);
1754 if (ALTIVEC_REGNO_P (regno
))
1755 return ALTIVEC_REGNO_P (last_regno
);
1758 /* The GPRs can hold any mode, but values bigger than one register
1759 cannot go past R31. */
1760 if (INT_REGNO_P (regno
))
1761 return INT_REGNO_P (last_regno
);
1763 /* The float registers (except for VSX vector modes) can only hold floating
1764 modes and DImode. This excludes the 32-bit decimal float mode for
1766 if (FP_REGNO_P (regno
))
1768 if (SCALAR_FLOAT_MODE_P (mode
)
1769 && (mode
!= TDmode
|| (regno
% 2) == 0)
1770 && FP_REGNO_P (last_regno
))
1773 if (GET_MODE_CLASS (mode
) == MODE_INT
1774 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1777 if (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1778 && PAIRED_VECTOR_MODE (mode
))
1784 /* The CR register can only hold CC modes. */
1785 if (CR_REGNO_P (regno
))
1786 return GET_MODE_CLASS (mode
) == MODE_CC
;
1788 if (CA_REGNO_P (regno
))
1789 return mode
== BImode
;
1791 /* AltiVec only in AldyVec registers. */
1792 if (ALTIVEC_REGNO_P (regno
))
1793 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
);
1795 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1796 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1799 /* We cannot put TImode anywhere except general register and it must be able
1800 to fit within the register set. In the future, allow TImode in the
1801 Altivec or VSX registers. */
1803 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1806 /* Print interesting facts about registers. */
1808 rs6000_debug_reg_print (int first_regno
, int last_regno
, const char *reg_name
)
1812 for (r
= first_regno
; r
<= last_regno
; ++r
)
1814 const char *comma
= "";
1817 if (first_regno
== last_regno
)
1818 fprintf (stderr
, "%s:\t", reg_name
);
1820 fprintf (stderr
, "%s%d:\t", reg_name
, r
- first_regno
);
1823 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1824 if (rs6000_hard_regno_mode_ok_p
[m
][r
] && rs6000_hard_regno_nregs
[m
][r
])
1828 fprintf (stderr
, ",\n\t");
1833 if (rs6000_hard_regno_nregs
[m
][r
] > 1)
1834 len
+= fprintf (stderr
, "%s%s/%d", comma
, GET_MODE_NAME (m
),
1835 rs6000_hard_regno_nregs
[m
][r
]);
1837 len
+= fprintf (stderr
, "%s%s", comma
, GET_MODE_NAME (m
));
1842 if (call_used_regs
[r
])
1846 fprintf (stderr
, ",\n\t");
1851 len
+= fprintf (stderr
, "%s%s", comma
, "call-used");
1859 fprintf (stderr
, ",\n\t");
1864 len
+= fprintf (stderr
, "%s%s", comma
, "fixed");
1870 fprintf (stderr
, ",\n\t");
1874 fprintf (stderr
, "%sregno = %d\n", comma
, r
);
1878 #define DEBUG_FMT_D "%-32s= %d\n"
1879 #define DEBUG_FMT_S "%-32s= %s\n"
1881 /* Print various interesting information with -mdebug=reg. */
1883 rs6000_debug_reg_global (void)
1885 static const char *const tf
[2] = { "false", "true" };
1886 const char *nl
= (const char *)0;
1888 char costly_num
[20];
1890 const char *costly_str
;
1891 const char *nop_str
;
1892 const char *trace_str
;
1893 const char *abi_str
;
1894 const char *cmodel_str
;
1896 /* Map enum rs6000_vector to string. */
1897 static const char *rs6000_debug_vector_unit
[] = {
1906 fprintf (stderr
, "Register information: (last virtual reg = %d)\n",
1907 LAST_VIRTUAL_REGISTER
);
1908 rs6000_debug_reg_print (0, 31, "gr");
1909 rs6000_debug_reg_print (32, 63, "fp");
1910 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO
,
1913 rs6000_debug_reg_print (LR_REGNO
, LR_REGNO
, "lr");
1914 rs6000_debug_reg_print (CTR_REGNO
, CTR_REGNO
, "ctr");
1915 rs6000_debug_reg_print (CR0_REGNO
, CR7_REGNO
, "cr");
1916 rs6000_debug_reg_print (MQ_REGNO
, MQ_REGNO
, "mq");
1917 rs6000_debug_reg_print (CA_REGNO
, CA_REGNO
, "ca");
1918 rs6000_debug_reg_print (VRSAVE_REGNO
, VRSAVE_REGNO
, "vrsave");
1919 rs6000_debug_reg_print (VSCR_REGNO
, VSCR_REGNO
, "vscr");
1920 rs6000_debug_reg_print (SPE_ACC_REGNO
, SPE_ACC_REGNO
, "spe_a");
1921 rs6000_debug_reg_print (SPEFSCR_REGNO
, SPEFSCR_REGNO
, "spe_f");
1925 "d reg_class = %s\n"
1926 "f reg_class = %s\n"
1927 "v reg_class = %s\n"
1928 "wa reg_class = %s\n"
1929 "wd reg_class = %s\n"
1930 "wf reg_class = %s\n"
1931 "ws reg_class = %s\n\n",
1932 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_d
]],
1933 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_f
]],
1934 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_v
]],
1935 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wa
]],
1936 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wd
]],
1937 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wf
]],
1938 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_ws
]]);
1940 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1941 if (rs6000_vector_unit
[m
] || rs6000_vector_mem
[m
])
1944 fprintf (stderr
, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1946 rs6000_debug_vector_unit
[ rs6000_vector_unit
[m
] ],
1947 rs6000_debug_vector_unit
[ rs6000_vector_mem
[m
] ]);
1953 if (rs6000_recip_control
)
1955 fprintf (stderr
, "\nReciprocal mask = 0x%x\n", rs6000_recip_control
);
1957 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1958 if (rs6000_recip_bits
[m
])
1961 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1963 (RS6000_RECIP_AUTO_RE_P (m
)
1965 : (RS6000_RECIP_HAVE_RE_P (m
) ? "have" : "none")),
1966 (RS6000_RECIP_AUTO_RSQRTE_P (m
)
1968 : (RS6000_RECIP_HAVE_RSQRTE_P (m
) ? "have" : "none")));
1971 fputs ("\n", stderr
);
1974 if (rs6000_cpu_index
>= 0)
1975 fprintf (stderr
, DEBUG_FMT_S
, "cpu",
1976 processor_target_table
[rs6000_cpu_index
].name
);
1978 if (rs6000_tune_index
>= 0)
1979 fprintf (stderr
, DEBUG_FMT_S
, "tune",
1980 processor_target_table
[rs6000_tune_index
].name
);
1982 switch (rs6000_sched_costly_dep
)
1984 case max_dep_latency
:
1985 costly_str
= "max_dep_latency";
1989 costly_str
= "no_dep_costly";
1992 case all_deps_costly
:
1993 costly_str
= "all_deps_costly";
1996 case true_store_to_load_dep_costly
:
1997 costly_str
= "true_store_to_load_dep_costly";
2000 case store_to_load_dep_costly
:
2001 costly_str
= "store_to_load_dep_costly";
2005 costly_str
= costly_num
;
2006 sprintf (costly_num
, "%d", (int)rs6000_sched_costly_dep
);
2010 fprintf (stderr
, DEBUG_FMT_S
, "sched_costly_dep", costly_str
);
2012 switch (rs6000_sched_insert_nops
)
2014 case sched_finish_regroup_exact
:
2015 nop_str
= "sched_finish_regroup_exact";
2018 case sched_finish_pad_groups
:
2019 nop_str
= "sched_finish_pad_groups";
2022 case sched_finish_none
:
2023 nop_str
= "sched_finish_none";
2028 sprintf (nop_num
, "%d", (int)rs6000_sched_insert_nops
);
2032 fprintf (stderr
, DEBUG_FMT_S
, "sched_insert_nops", nop_str
);
2034 switch (rs6000_sdata
)
2041 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "data");
2045 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "sysv");
2049 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "eabi");
2054 switch (rs6000_traceback
)
2056 case traceback_default
: trace_str
= "default"; break;
2057 case traceback_none
: trace_str
= "none"; break;
2058 case traceback_part
: trace_str
= "part"; break;
2059 case traceback_full
: trace_str
= "full"; break;
2060 default: trace_str
= "unknown"; break;
2063 fprintf (stderr
, DEBUG_FMT_S
, "traceback", trace_str
);
2065 switch (rs6000_current_cmodel
)
2067 case CMODEL_SMALL
: cmodel_str
= "small"; break;
2068 case CMODEL_MEDIUM
: cmodel_str
= "medium"; break;
2069 case CMODEL_LARGE
: cmodel_str
= "large"; break;
2070 default: cmodel_str
= "unknown"; break;
2073 fprintf (stderr
, DEBUG_FMT_S
, "cmodel", cmodel_str
);
2075 switch (rs6000_current_abi
)
2077 case ABI_NONE
: abi_str
= "none"; break;
2078 case ABI_AIX
: abi_str
= "aix"; break;
2079 case ABI_V4
: abi_str
= "V4"; break;
2080 case ABI_DARWIN
: abi_str
= "darwin"; break;
2081 default: abi_str
= "unknown"; break;
2084 fprintf (stderr
, DEBUG_FMT_S
, "abi", abi_str
);
2086 if (rs6000_altivec_abi
)
2087 fprintf (stderr
, DEBUG_FMT_S
, "altivec_abi", "true");
2090 fprintf (stderr
, DEBUG_FMT_S
, "spe_abi", "true");
2092 if (rs6000_darwin64_abi
)
2093 fprintf (stderr
, DEBUG_FMT_S
, "darwin64_abi", "true");
2095 if (rs6000_float_gprs
)
2096 fprintf (stderr
, DEBUG_FMT_S
, "float_gprs", "true");
2098 fprintf (stderr
, DEBUG_FMT_S
, "always_hint", tf
[!!rs6000_always_hint
]);
2099 fprintf (stderr
, DEBUG_FMT_S
, "align_branch",
2100 tf
[!!rs6000_align_branch_targets
]);
2101 fprintf (stderr
, DEBUG_FMT_D
, "tls_size", rs6000_tls_size
);
2102 fprintf (stderr
, DEBUG_FMT_D
, "long_double_size",
2103 rs6000_long_double_type_size
);
2104 fprintf (stderr
, DEBUG_FMT_D
, "sched_restricted_insns_priority",
2105 (int)rs6000_sched_restricted_insns_priority
);
2108 /* Initialize the various global tables that are based on register size. */
2110 rs6000_init_hard_regno_mode_ok (bool global_init_p
)
2116 /* Precalculate REGNO_REG_CLASS. */
2117 rs6000_regno_regclass
[0] = GENERAL_REGS
;
2118 for (r
= 1; r
< 32; ++r
)
2119 rs6000_regno_regclass
[r
] = BASE_REGS
;
2121 for (r
= 32; r
< 64; ++r
)
2122 rs6000_regno_regclass
[r
] = FLOAT_REGS
;
2124 for (r
= 64; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2125 rs6000_regno_regclass
[r
] = NO_REGS
;
2127 for (r
= FIRST_ALTIVEC_REGNO
; r
<= LAST_ALTIVEC_REGNO
; ++r
)
2128 rs6000_regno_regclass
[r
] = ALTIVEC_REGS
;
2130 rs6000_regno_regclass
[CR0_REGNO
] = CR0_REGS
;
2131 for (r
= CR1_REGNO
; r
<= CR7_REGNO
; ++r
)
2132 rs6000_regno_regclass
[r
] = CR_REGS
;
2134 rs6000_regno_regclass
[MQ_REGNO
] = MQ_REGS
;
2135 rs6000_regno_regclass
[LR_REGNO
] = LINK_REGS
;
2136 rs6000_regno_regclass
[CTR_REGNO
] = CTR_REGS
;
2137 rs6000_regno_regclass
[CA_REGNO
] = CA_REGS
;
2138 rs6000_regno_regclass
[VRSAVE_REGNO
] = VRSAVE_REGS
;
2139 rs6000_regno_regclass
[VSCR_REGNO
] = VRSAVE_REGS
;
2140 rs6000_regno_regclass
[SPE_ACC_REGNO
] = SPE_ACC_REGS
;
2141 rs6000_regno_regclass
[SPEFSCR_REGNO
] = SPEFSCR_REGS
;
2142 rs6000_regno_regclass
[ARG_POINTER_REGNUM
] = BASE_REGS
;
2143 rs6000_regno_regclass
[FRAME_POINTER_REGNUM
] = BASE_REGS
;
2145 /* Precalculate vector information, this must be set up before the
2146 rs6000_hard_regno_nregs_internal below. */
2147 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2149 rs6000_vector_unit
[m
] = rs6000_vector_mem
[m
] = VECTOR_NONE
;
2150 rs6000_vector_reload
[m
][0] = CODE_FOR_nothing
;
2151 rs6000_vector_reload
[m
][1] = CODE_FOR_nothing
;
2154 for (c
= 0; c
< (int)(int)RS6000_CONSTRAINT_MAX
; c
++)
2155 rs6000_constraints
[c
] = NO_REGS
;
2157 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2158 believes it can use native alignment or still uses 128-bit alignment. */
2159 if (TARGET_VSX
&& !TARGET_VSX_ALIGN_128
)
2170 /* V2DF mode, VSX only. */
2173 rs6000_vector_unit
[V2DFmode
] = VECTOR_VSX
;
2174 rs6000_vector_mem
[V2DFmode
] = VECTOR_VSX
;
2175 rs6000_vector_align
[V2DFmode
] = align64
;
2178 /* V4SF mode, either VSX or Altivec. */
2181 rs6000_vector_unit
[V4SFmode
] = VECTOR_VSX
;
2182 rs6000_vector_mem
[V4SFmode
] = VECTOR_VSX
;
2183 rs6000_vector_align
[V4SFmode
] = align32
;
2185 else if (TARGET_ALTIVEC
)
2187 rs6000_vector_unit
[V4SFmode
] = VECTOR_ALTIVEC
;
2188 rs6000_vector_mem
[V4SFmode
] = VECTOR_ALTIVEC
;
2189 rs6000_vector_align
[V4SFmode
] = align32
;
2192 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2196 rs6000_vector_unit
[V4SImode
] = VECTOR_ALTIVEC
;
2197 rs6000_vector_unit
[V8HImode
] = VECTOR_ALTIVEC
;
2198 rs6000_vector_unit
[V16QImode
] = VECTOR_ALTIVEC
;
2199 rs6000_vector_align
[V4SImode
] = align32
;
2200 rs6000_vector_align
[V8HImode
] = align32
;
2201 rs6000_vector_align
[V16QImode
] = align32
;
2205 rs6000_vector_mem
[V4SImode
] = VECTOR_VSX
;
2206 rs6000_vector_mem
[V8HImode
] = VECTOR_VSX
;
2207 rs6000_vector_mem
[V16QImode
] = VECTOR_VSX
;
2211 rs6000_vector_mem
[V4SImode
] = VECTOR_ALTIVEC
;
2212 rs6000_vector_mem
[V8HImode
] = VECTOR_ALTIVEC
;
2213 rs6000_vector_mem
[V16QImode
] = VECTOR_ALTIVEC
;
2217 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2218 Altivec doesn't have 64-bit support. */
2221 rs6000_vector_mem
[V2DImode
] = VECTOR_VSX
;
2222 rs6000_vector_unit
[V2DImode
] = VECTOR_NONE
;
2223 rs6000_vector_align
[V2DImode
] = align64
;
2226 /* DFmode, see if we want to use the VSX unit. */
2227 if (TARGET_VSX
&& TARGET_VSX_SCALAR_DOUBLE
)
2229 rs6000_vector_unit
[DFmode
] = VECTOR_VSX
;
2230 rs6000_vector_mem
[DFmode
]
2231 = (TARGET_VSX_SCALAR_MEMORY
? VECTOR_VSX
: VECTOR_NONE
);
2232 rs6000_vector_align
[DFmode
] = align64
;
2235 /* TODO add SPE and paired floating point vector support. */
2237 /* Register class constaints for the constraints that depend on compile
2239 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2240 rs6000_constraints
[RS6000_CONSTRAINT_f
] = FLOAT_REGS
;
2242 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
2243 rs6000_constraints
[RS6000_CONSTRAINT_d
] = FLOAT_REGS
;
2247 /* At present, we just use VSX_REGS, but we have different constraints
2248 based on the use, in case we want to fine tune the default register
2249 class used. wa = any VSX register, wf = register class to use for
2250 V4SF, wd = register class to use for V2DF, and ws = register classs to
2251 use for DF scalars. */
2252 rs6000_constraints
[RS6000_CONSTRAINT_wa
] = VSX_REGS
;
2253 rs6000_constraints
[RS6000_CONSTRAINT_wf
] = VSX_REGS
;
2254 rs6000_constraints
[RS6000_CONSTRAINT_wd
] = VSX_REGS
;
2255 rs6000_constraints
[RS6000_CONSTRAINT_ws
] = (TARGET_VSX_SCALAR_MEMORY
2261 rs6000_constraints
[RS6000_CONSTRAINT_v
] = ALTIVEC_REGS
;
2263 /* Set up the reload helper functions. */
2264 if (TARGET_VSX
|| TARGET_ALTIVEC
)
2268 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_di_store
;
2269 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_di_load
;
2270 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_di_store
;
2271 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_di_load
;
2272 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_di_store
;
2273 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_di_load
;
2274 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_di_store
;
2275 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_di_load
;
2276 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_di_store
;
2277 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_di_load
;
2278 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_di_store
;
2279 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_di_load
;
2283 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_si_store
;
2284 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_si_load
;
2285 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_si_store
;
2286 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_si_load
;
2287 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_si_store
;
2288 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_si_load
;
2289 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_si_store
;
2290 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_si_load
;
2291 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_si_store
;
2292 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_si_load
;
2293 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_si_store
;
2294 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_si_load
;
2298 /* Precalculate HARD_REGNO_NREGS. */
2299 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2300 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2301 rs6000_hard_regno_nregs
[m
][r
]
2302 = rs6000_hard_regno_nregs_internal (r
, (enum machine_mode
)m
);
2304 /* Precalculate HARD_REGNO_MODE_OK. */
2305 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2306 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2307 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
)m
))
2308 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
2310 /* Precalculate CLASS_MAX_NREGS sizes. */
2311 for (c
= 0; c
< LIM_REG_CLASSES
; ++c
)
2315 if (TARGET_VSX
&& VSX_REG_CLASS_P (c
))
2316 reg_size
= UNITS_PER_VSX_WORD
;
2318 else if (c
== ALTIVEC_REGS
)
2319 reg_size
= UNITS_PER_ALTIVEC_WORD
;
2321 else if (c
== FLOAT_REGS
)
2322 reg_size
= UNITS_PER_FP_WORD
;
2325 reg_size
= UNITS_PER_WORD
;
2327 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2328 rs6000_class_max_nregs
[m
][c
]
2329 = (GET_MODE_SIZE (m
) + reg_size
- 1) / reg_size
;
2332 if (TARGET_E500_DOUBLE
)
2333 rs6000_class_max_nregs
[DFmode
][GENERAL_REGS
] = 1;
2335 /* Calculate which modes to automatically generate code to use a the
2336 reciprocal divide and square root instructions. In the future, possibly
2337 automatically generate the instructions even if the user did not specify
2338 -mrecip. The older machines double precision reciprocal sqrt estimate is
2339 not accurate enough. */
2340 memset (rs6000_recip_bits
, 0, sizeof (rs6000_recip_bits
));
2342 rs6000_recip_bits
[SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2344 rs6000_recip_bits
[DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2345 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2346 rs6000_recip_bits
[V4SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2347 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2348 rs6000_recip_bits
[V2DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2350 if (TARGET_FRSQRTES
)
2351 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2353 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2354 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2355 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2356 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2357 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2359 if (rs6000_recip_control
)
2361 if (!flag_finite_math_only
)
2362 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2363 if (flag_trapping_math
)
2364 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2365 if (!flag_reciprocal_math
)
2366 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2367 if (flag_finite_math_only
&& !flag_trapping_math
&& flag_reciprocal_math
)
2369 if (RS6000_RECIP_HAVE_RE_P (SFmode
)
2370 && (rs6000_recip_control
& RECIP_SF_DIV
) != 0)
2371 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2373 if (RS6000_RECIP_HAVE_RE_P (DFmode
)
2374 && (rs6000_recip_control
& RECIP_DF_DIV
) != 0)
2375 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2377 if (RS6000_RECIP_HAVE_RE_P (V4SFmode
)
2378 && (rs6000_recip_control
& RECIP_V4SF_DIV
) != 0)
2379 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2381 if (RS6000_RECIP_HAVE_RE_P (V2DFmode
)
2382 && (rs6000_recip_control
& RECIP_V2DF_DIV
) != 0)
2383 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2385 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode
)
2386 && (rs6000_recip_control
& RECIP_SF_RSQRT
) != 0)
2387 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2389 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode
)
2390 && (rs6000_recip_control
& RECIP_DF_RSQRT
) != 0)
2391 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2393 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode
)
2394 && (rs6000_recip_control
& RECIP_V4SF_RSQRT
) != 0)
2395 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2397 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode
)
2398 && (rs6000_recip_control
& RECIP_V2DF_RSQRT
) != 0)
2399 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2403 if (global_init_p
|| TARGET_DEBUG_TARGET
)
2405 if (TARGET_DEBUG_REG
)
2406 rs6000_debug_reg_global ();
2408 if (TARGET_DEBUG_COST
|| TARGET_DEBUG_REG
)
2410 "SImode variable mult cost = %d\n"
2411 "SImode constant mult cost = %d\n"
2412 "SImode short constant mult cost = %d\n"
2413 "DImode multipliciation cost = %d\n"
2414 "SImode division cost = %d\n"
2415 "DImode division cost = %d\n"
2416 "Simple fp operation cost = %d\n"
2417 "DFmode multiplication cost = %d\n"
2418 "SFmode division cost = %d\n"
2419 "DFmode division cost = %d\n"
2420 "cache line size = %d\n"
2421 "l1 cache size = %d\n"
2422 "l2 cache size = %d\n"
2423 "simultaneous prefetches = %d\n"
2426 rs6000_cost
->mulsi_const
,
2427 rs6000_cost
->mulsi_const9
,
2435 rs6000_cost
->cache_line_size
,
2436 rs6000_cost
->l1_cache_size
,
2437 rs6000_cost
->l2_cache_size
,
2438 rs6000_cost
->simultaneous_prefetches
);
2443 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2446 darwin_rs6000_override_options (void)
2448 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2450 rs6000_altivec_abi
= 1;
2451 TARGET_ALTIVEC_VRSAVE
= 1;
2453 if (DEFAULT_ABI
== ABI_DARWIN
2455 darwin_one_byte_bool
= 1;
2457 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
2459 target_flags
|= MASK_POWERPC64
;
2460 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2464 rs6000_default_long_calls
= 1;
2465 target_flags
|= MASK_SOFT_FLOAT
;
2468 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2470 if (!flag_mkernel
&& !flag_apple_kext
2472 && ! (target_flags_explicit
& MASK_ALTIVEC
))
2473 target_flags
|= MASK_ALTIVEC
;
2475 /* Unless the user (not the configurer) has explicitly overridden
2476 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2477 G4 unless targetting the kernel. */
2480 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
2481 && ! (target_flags_explicit
& MASK_ALTIVEC
)
2482 && ! global_options_set
.x_rs6000_cpu_index
)
2484 target_flags
|= MASK_ALTIVEC
;
2489 /* If not otherwise specified by a target, make 'long double' equivalent to
2492 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2493 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2496 /* Override command line options. Mostly we process the processor type and
2497 sometimes adjust other TARGET_ options. */
2500 rs6000_option_override_internal (bool global_init_p
)
2503 const char *default_cpu
= OPTION_TARGET_CPU_DEFAULT
;
2507 struct cl_target_option
*main_target_opt
2508 = ((global_init_p
|| target_option_default_node
== NULL
)
2509 ? NULL
: TREE_TARGET_OPTION (target_option_default_node
));
2511 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2512 library functions, so warn about it. The flag may be useful for
2513 performance studies from time to time though, so don't disable it
2515 if (global_options_set
.x_rs6000_alignment_flags
2516 && rs6000_alignment_flags
== MASK_ALIGN_POWER
2517 && DEFAULT_ABI
== ABI_DARWIN
2519 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2520 " it is incompatible with the installed C and C++ libraries");
2522 if (global_options_set
.x_rs6000_spe_abi
2525 error ("not configured for SPE ABI");
2527 /* Numerous experiment shows that IRA based loop pressure
2528 calculation works better for RTL loop invariant motion on targets
2529 with enough (>= 32) registers. It is an expensive optimization.
2530 So it is on only for peak performance. */
2531 if (optimize
>= 3 && global_init_p
)
2532 flag_ira_loop_pressure
= 1;
2534 /* Set the pointer size. */
2537 rs6000_pmode
= (int)DImode
;
2538 rs6000_pointer_size
= 64;
2542 rs6000_pmode
= (int)SImode
;
2543 rs6000_pointer_size
= 32;
2546 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
2547 #ifdef OS_MISSING_POWERPC64
2548 if (OS_MISSING_POWERPC64
)
2549 set_masks
&= ~MASK_POWERPC64
;
2551 #ifdef OS_MISSING_ALTIVEC
2552 if (OS_MISSING_ALTIVEC
)
2553 set_masks
&= ~MASK_ALTIVEC
;
2556 /* Don't override by the processor default if given explicitly. */
2557 set_masks
&= ~target_flags_explicit
;
2559 /* Identify the processor type. */
2562 if (TARGET_POWERPC64
)
2563 default_cpu
= "powerpc64";
2564 else if (TARGET_POWERPC
)
2565 default_cpu
= "powerpc";
2568 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2569 the cpu in a target attribute or pragma, but did not specify a tuning
2570 option, use the cpu for the tuning option rather than the option specified
2571 with -mtune on the command line. */
2572 if (rs6000_cpu_index
> 0)
2573 cpu_index
= rs6000_cpu_index
;
2574 else if (main_target_opt
!= NULL
&& main_target_opt
->x_rs6000_cpu_index
> 0)
2575 rs6000_cpu_index
= cpu_index
= main_target_opt
->x_rs6000_cpu_index
;
2577 rs6000_cpu_index
= cpu_index
= rs6000_cpu_name_lookup (default_cpu
);
2579 if (rs6000_tune_index
> 0)
2580 tune_index
= rs6000_tune_index
;
2582 rs6000_tune_index
= tune_index
= cpu_index
;
2586 target_flags
&= ~set_masks
;
2587 target_flags
|= (processor_target_table
[cpu_index
].target_enable
2591 rs6000_cpu
= ((tune_index
>= 0)
2592 ? processor_target_table
[tune_index
].processor
2594 ? PROCESSOR_DEFAULT64
2595 : PROCESSOR_DEFAULT
));
2597 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
2598 || rs6000_cpu
== PROCESSOR_PPCE500MC
|| rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2601 error ("AltiVec not supported in this target");
2603 error ("SPE not supported in this target");
2606 /* Disable Cell microcode if we are optimizing for the Cell
2607 and not optimizing for size. */
2608 if (rs6000_gen_cell_microcode
== -1)
2609 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
2612 /* If we are optimizing big endian systems for space and it's OK to
2613 use instructions that would be microcoded on the Cell, use the
2614 load/store multiple and string instructions. */
2615 if (BYTES_BIG_ENDIAN
&& optimize_size
&& rs6000_gen_cell_microcode
)
2616 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
2618 /* Don't allow -mmultiple or -mstring on little endian systems
2619 unless the cpu is a 750, because the hardware doesn't support the
2620 instructions used in little endian mode, and causes an alignment
2621 trap. The 750 does not cause an alignment trap (except when the
2622 target is unaligned). */
2624 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
2626 if (TARGET_MULTIPLE
)
2628 target_flags
&= ~MASK_MULTIPLE
;
2629 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
2630 warning (0, "-mmultiple is not supported on little endian systems");
2635 target_flags
&= ~MASK_STRING
;
2636 if ((target_flags_explicit
& MASK_STRING
) != 0)
2637 warning (0, "-mstring is not supported on little endian systems");
2641 /* Add some warnings for VSX. */
2644 const char *msg
= NULL
;
2645 if (!TARGET_HARD_FLOAT
|| !TARGET_FPRS
2646 || !TARGET_SINGLE_FLOAT
|| !TARGET_DOUBLE_FLOAT
)
2648 if (target_flags_explicit
& MASK_VSX
)
2649 msg
= N_("-mvsx requires hardware floating point");
2651 target_flags
&= ~ MASK_VSX
;
2653 else if (TARGET_PAIRED_FLOAT
)
2654 msg
= N_("-mvsx and -mpaired are incompatible");
2655 /* The hardware will allow VSX and little endian, but until we make sure
2656 things like vector select, etc. work don't allow VSX on little endian
2657 systems at this point. */
2658 else if (!BYTES_BIG_ENDIAN
)
2659 msg
= N_("-mvsx used with little endian code");
2660 else if (TARGET_AVOID_XFORM
> 0)
2661 msg
= N_("-mvsx needs indexed addressing");
2662 else if (!TARGET_ALTIVEC
&& (target_flags_explicit
& MASK_ALTIVEC
))
2664 if (target_flags_explicit
& MASK_VSX
)
2665 msg
= N_("-mvsx and -mno-altivec are incompatible");
2667 msg
= N_("-mno-altivec disables vsx");
2673 target_flags
&= ~ MASK_VSX
;
2674 target_flags_explicit
|= MASK_VSX
;
2678 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2679 unless the user explicitly used the -mno-<option> to disable the code. */
2681 target_flags
|= (ISA_2_6_MASKS_SERVER
& ~target_flags_explicit
);
2682 else if (TARGET_POPCNTD
)
2683 target_flags
|= (ISA_2_6_MASKS_EMBEDDED
& ~target_flags_explicit
);
2684 else if (TARGET_DFP
)
2685 target_flags
|= (ISA_2_5_MASKS_SERVER
& ~target_flags_explicit
);
2686 else if (TARGET_CMPB
)
2687 target_flags
|= (ISA_2_5_MASKS_EMBEDDED
& ~target_flags_explicit
);
2688 else if (TARGET_FPRND
)
2689 target_flags
|= (ISA_2_4_MASKS
& ~target_flags_explicit
);
2690 else if (TARGET_POPCNTB
)
2691 target_flags
|= (ISA_2_2_MASKS
& ~target_flags_explicit
);
2692 else if (TARGET_ALTIVEC
)
2693 target_flags
|= (MASK_PPC_GFXOPT
& ~target_flags_explicit
);
2695 /* E500mc does "better" if we inline more aggressively. Respect the
2696 user's opinion, though. */
2697 if (rs6000_block_move_inline_limit
== 0
2698 && (rs6000_cpu
== PROCESSOR_PPCE500MC
2699 || rs6000_cpu
== PROCESSOR_PPCE500MC64
))
2700 rs6000_block_move_inline_limit
= 128;
2702 /* store_one_arg depends on expand_block_move to handle at least the
2703 size of reg_parm_stack_space. */
2704 if (rs6000_block_move_inline_limit
< (TARGET_POWERPC64
? 64 : 32))
2705 rs6000_block_move_inline_limit
= (TARGET_POWERPC64
? 64 : 32);
2709 /* If the appropriate debug option is enabled, replace the target hooks
2710 with debug versions that call the real version and then prints
2711 debugging information. */
2712 if (TARGET_DEBUG_COST
)
2714 targetm
.rtx_costs
= rs6000_debug_rtx_costs
;
2715 targetm
.address_cost
= rs6000_debug_address_cost
;
2716 targetm
.sched
.adjust_cost
= rs6000_debug_adjust_cost
;
2719 if (TARGET_DEBUG_ADDR
)
2721 targetm
.legitimate_address_p
= rs6000_debug_legitimate_address_p
;
2722 targetm
.legitimize_address
= rs6000_debug_legitimize_address
;
2723 rs6000_secondary_reload_class_ptr
2724 = rs6000_debug_secondary_reload_class
;
2725 rs6000_secondary_memory_needed_ptr
2726 = rs6000_debug_secondary_memory_needed
;
2727 rs6000_cannot_change_mode_class_ptr
2728 = rs6000_debug_cannot_change_mode_class
;
2729 rs6000_preferred_reload_class_ptr
2730 = rs6000_debug_preferred_reload_class
;
2731 rs6000_legitimize_reload_address_ptr
2732 = rs6000_debug_legitimize_reload_address
;
2733 rs6000_mode_dependent_address_ptr
2734 = rs6000_debug_mode_dependent_address
;
2737 if (rs6000_veclibabi_name
)
2739 if (strcmp (rs6000_veclibabi_name
, "mass") == 0)
2740 rs6000_veclib_handler
= rs6000_builtin_vectorized_libmass
;
2743 error ("unknown vectorization library ABI type (%s) for "
2744 "-mveclibabi= switch", rs6000_veclibabi_name
);
2750 if (!global_options_set
.x_rs6000_long_double_type_size
)
2752 if (main_target_opt
!= NULL
2753 && (main_target_opt
->x_rs6000_long_double_type_size
2754 != RS6000_DEFAULT_LONG_DOUBLE_SIZE
))
2755 error ("target attribute or pragma changes long double size");
2757 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2760 #ifndef POWERPC_LINUX
2761 if (!global_options_set
.x_rs6000_ieeequad
)
2762 rs6000_ieeequad
= 1;
2765 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2766 target attribute or pragma which automatically enables both options,
2767 unless the altivec ABI was set. This is set by default for 64-bit, but
2769 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_altivec_abi
)
2770 target_flags
&= ~((MASK_VSX
| MASK_ALTIVEC
) & ~target_flags_explicit
);
2772 /* Enable Altivec ABI for AIX -maltivec. */
2773 if (TARGET_XCOFF
&& (TARGET_ALTIVEC
|| TARGET_VSX
))
2775 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_altivec_abi
)
2776 error ("target attribute or pragma changes AltiVec ABI");
2778 rs6000_altivec_abi
= 1;
2781 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2782 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2783 be explicitly overridden in either case. */
2786 if (!global_options_set
.x_rs6000_altivec_abi
2787 && (TARGET_64BIT
|| TARGET_ALTIVEC
|| TARGET_VSX
))
2789 if (main_target_opt
!= NULL
&&
2790 !main_target_opt
->x_rs6000_altivec_abi
)
2791 error ("target attribute or pragma changes AltiVec ABI");
2793 rs6000_altivec_abi
= 1;
2796 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2797 if (!global_options_set
.x_TARGET_ALTIVEC_VRSAVE
)
2798 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
2801 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2802 So far, the only darwin64 targets are also MACH-O. */
2804 && DEFAULT_ABI
== ABI_DARWIN
2807 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_darwin64_abi
)
2808 error ("target attribute or pragma changes darwin64 ABI");
2811 rs6000_darwin64_abi
= 1;
2812 /* Default to natural alignment, for better performance. */
2813 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2817 /* Place FP constants in the constant pool instead of TOC
2818 if section anchors enabled. */
2819 if (flag_section_anchors
)
2820 TARGET_NO_FP_IN_TOC
= 1;
2822 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2823 SUBTARGET_OVERRIDE_OPTIONS
;
2825 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2826 SUBSUBTARGET_OVERRIDE_OPTIONS
;
2828 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2829 SUB3TARGET_OVERRIDE_OPTIONS
;
2832 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
2833 || rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2835 /* The e500 and e500mc do not have string instructions, and we set
2836 MASK_STRING above when optimizing for size. */
2837 if ((target_flags
& MASK_STRING
) != 0)
2838 target_flags
= target_flags
& ~MASK_STRING
;
2840 else if (global_options_set
.x_rs6000_cpu_index
)
2842 /* For the powerpc-eabispe configuration, we set all these by
2843 default, so let's unset them if we manually set another
2844 CPU that is not the E500. */
2845 if (main_target_opt
!= NULL
2846 && ((main_target_opt
->x_rs6000_spe_abi
!= rs6000_spe_abi
)
2847 || (main_target_opt
->x_rs6000_spe
!= rs6000_spe
)
2848 || (main_target_opt
->x_rs6000_float_gprs
!= rs6000_float_gprs
)))
2849 error ("target attribute or pragma changes SPE ABI");
2852 if (!global_options_set
.x_rs6000_spe_abi
)
2854 if (!global_options_set
.x_rs6000_spe
)
2856 if (!global_options_set
.x_rs6000_float_gprs
)
2857 rs6000_float_gprs
= 0;
2859 if (!(target_flags_explicit
& MASK_ISEL
))
2860 target_flags
&= ~MASK_ISEL
;
2863 /* Detect invalid option combinations with E500. */
2866 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
2867 && rs6000_cpu
!= PROCESSOR_POWER5
2868 && rs6000_cpu
!= PROCESSOR_POWER6
2869 && rs6000_cpu
!= PROCESSOR_POWER7
2870 && rs6000_cpu
!= PROCESSOR_PPCA2
2871 && rs6000_cpu
!= PROCESSOR_CELL
);
2872 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
2873 || rs6000_cpu
== PROCESSOR_POWER5
2874 || rs6000_cpu
== PROCESSOR_POWER7
);
2875 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
2876 || rs6000_cpu
== PROCESSOR_POWER5
2877 || rs6000_cpu
== PROCESSOR_POWER6
2878 || rs6000_cpu
== PROCESSOR_POWER7
2879 || rs6000_cpu
== PROCESSOR_PPCE500MC
2880 || rs6000_cpu
== PROCESSOR_PPCE500MC64
);
2882 /* Allow debug switches to override the above settings. These are set to -1
2883 in rs6000.opt to indicate the user hasn't directly set the switch. */
2884 if (TARGET_ALWAYS_HINT
>= 0)
2885 rs6000_always_hint
= TARGET_ALWAYS_HINT
;
2887 if (TARGET_SCHED_GROUPS
>= 0)
2888 rs6000_sched_groups
= TARGET_SCHED_GROUPS
;
2890 if (TARGET_ALIGN_BRANCH_TARGETS
>= 0)
2891 rs6000_align_branch_targets
= TARGET_ALIGN_BRANCH_TARGETS
;
2893 rs6000_sched_restricted_insns_priority
2894 = (rs6000_sched_groups
? 1 : 0);
2896 /* Handle -msched-costly-dep option. */
2897 rs6000_sched_costly_dep
2898 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
2900 if (rs6000_sched_costly_dep_str
)
2902 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
2903 rs6000_sched_costly_dep
= no_dep_costly
;
2904 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
2905 rs6000_sched_costly_dep
= all_deps_costly
;
2906 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
2907 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
2908 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
2909 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
2911 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
2912 atoi (rs6000_sched_costly_dep_str
));
2915 /* Handle -minsert-sched-nops option. */
2916 rs6000_sched_insert_nops
2917 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
2919 if (rs6000_sched_insert_nops_str
)
2921 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
2922 rs6000_sched_insert_nops
= sched_finish_none
;
2923 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
2924 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
2925 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
2926 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
2928 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
2929 atoi (rs6000_sched_insert_nops_str
));
2934 #ifdef TARGET_REGNAMES
2935 /* If the user desires alternate register names, copy in the
2936 alternate names now. */
2937 if (TARGET_REGNAMES
)
2938 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
2941 /* Set aix_struct_return last, after the ABI is determined.
2942 If -maix-struct-return or -msvr4-struct-return was explicitly
2943 used, don't override with the ABI default. */
2944 if (!global_options_set
.x_aix_struct_return
)
2945 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
2948 /* IBM XL compiler defaults to unsigned bitfields. */
2949 if (TARGET_XL_COMPAT
)
2950 flag_signed_bitfields
= 0;
2953 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
2954 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
2957 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
2959 /* We can only guarantee the availability of DI pseudo-ops when
2960 assembling for 64-bit targets. */
2963 targetm
.asm_out
.aligned_op
.di
= NULL
;
2964 targetm
.asm_out
.unaligned_op
.di
= NULL
;
2968 /* Set branch target alignment, if not optimizing for size. */
2971 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2972 aligned 8byte to avoid misprediction by the branch predictor. */
2973 if (rs6000_cpu
== PROCESSOR_TITAN
2974 || rs6000_cpu
== PROCESSOR_CELL
)
2976 if (align_functions
<= 0)
2977 align_functions
= 8;
2978 if (align_jumps
<= 0)
2980 if (align_loops
<= 0)
2983 if (rs6000_align_branch_targets
)
2985 if (align_functions
<= 0)
2986 align_functions
= 16;
2987 if (align_jumps
<= 0)
2989 if (align_loops
<= 0)
2991 can_override_loop_align
= 1;
2995 if (align_jumps_max_skip
<= 0)
2996 align_jumps_max_skip
= 15;
2997 if (align_loops_max_skip
<= 0)
2998 align_loops_max_skip
= 15;
3001 /* Arrange to save and restore machine status around nested functions. */
3002 init_machine_status
= rs6000_init_machine_status
;
3004 /* We should always be splitting complex arguments, but we can't break
3005 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3006 if (DEFAULT_ABI
!= ABI_AIX
)
3007 targetm
.calls
.split_complex_arg
= NULL
;
3010 /* Initialize rs6000_cost with the appropriate target costs. */
3012 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
3016 case PROCESSOR_RIOS1
:
3017 rs6000_cost
= &rios1_cost
;
3020 case PROCESSOR_RIOS2
:
3021 rs6000_cost
= &rios2_cost
;
3024 case PROCESSOR_RS64A
:
3025 rs6000_cost
= &rs64a_cost
;
3028 case PROCESSOR_MPCCORE
:
3029 rs6000_cost
= &mpccore_cost
;
3032 case PROCESSOR_PPC403
:
3033 rs6000_cost
= &ppc403_cost
;
3036 case PROCESSOR_PPC405
:
3037 rs6000_cost
= &ppc405_cost
;
3040 case PROCESSOR_PPC440
:
3041 rs6000_cost
= &ppc440_cost
;
3044 case PROCESSOR_PPC476
:
3045 rs6000_cost
= &ppc476_cost
;
3048 case PROCESSOR_PPC601
:
3049 rs6000_cost
= &ppc601_cost
;
3052 case PROCESSOR_PPC603
:
3053 rs6000_cost
= &ppc603_cost
;
3056 case PROCESSOR_PPC604
:
3057 rs6000_cost
= &ppc604_cost
;
3060 case PROCESSOR_PPC604e
:
3061 rs6000_cost
= &ppc604e_cost
;
3064 case PROCESSOR_PPC620
:
3065 rs6000_cost
= &ppc620_cost
;
3068 case PROCESSOR_PPC630
:
3069 rs6000_cost
= &ppc630_cost
;
3072 case PROCESSOR_CELL
:
3073 rs6000_cost
= &ppccell_cost
;
3076 case PROCESSOR_PPC750
:
3077 case PROCESSOR_PPC7400
:
3078 rs6000_cost
= &ppc750_cost
;
3081 case PROCESSOR_PPC7450
:
3082 rs6000_cost
= &ppc7450_cost
;
3085 case PROCESSOR_PPC8540
:
3086 rs6000_cost
= &ppc8540_cost
;
3089 case PROCESSOR_PPCE300C2
:
3090 case PROCESSOR_PPCE300C3
:
3091 rs6000_cost
= &ppce300c2c3_cost
;
3094 case PROCESSOR_PPCE500MC
:
3095 rs6000_cost
= &ppce500mc_cost
;
3098 case PROCESSOR_PPCE500MC64
:
3099 rs6000_cost
= &ppce500mc64_cost
;
3102 case PROCESSOR_TITAN
:
3103 rs6000_cost
= &titan_cost
;
3106 case PROCESSOR_POWER4
:
3107 case PROCESSOR_POWER5
:
3108 rs6000_cost
= &power4_cost
;
3111 case PROCESSOR_POWER6
:
3112 rs6000_cost
= &power6_cost
;
3115 case PROCESSOR_POWER7
:
3116 rs6000_cost
= &power7_cost
;
3119 case PROCESSOR_PPCA2
:
3120 rs6000_cost
= &ppca2_cost
;
3129 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES
,
3130 rs6000_cost
->simultaneous_prefetches
,
3131 global_options
.x_param_values
,
3132 global_options_set
.x_param_values
);
3133 maybe_set_param_value (PARAM_L1_CACHE_SIZE
, rs6000_cost
->l1_cache_size
,
3134 global_options
.x_param_values
,
3135 global_options_set
.x_param_values
);
3136 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE
,
3137 rs6000_cost
->cache_line_size
,
3138 global_options
.x_param_values
,
3139 global_options_set
.x_param_values
);
3140 maybe_set_param_value (PARAM_L2_CACHE_SIZE
, rs6000_cost
->l2_cache_size
,
3141 global_options
.x_param_values
,
3142 global_options_set
.x_param_values
);
3144 /* If using typedef char *va_list, signal that
3145 __builtin_va_start (&ap, 0) can be optimized to
3146 ap = __builtin_next_arg (0). */
3147 if (DEFAULT_ABI
!= ABI_V4
)
3148 targetm
.expand_builtin_va_start
= NULL
;
3151 /* Set up single/double float flags.
3152 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3153 then set both flags. */
3154 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
3155 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
3156 rs6000_single_float
= rs6000_double_float
= 1;
3158 /* Reset single and double FP flags if target is E500. */
3161 rs6000_single_float
= rs6000_double_float
= 0;
3162 if (TARGET_E500_SINGLE
)
3163 rs6000_single_float
= 1;
3164 if (TARGET_E500_DOUBLE
)
3165 rs6000_single_float
= rs6000_double_float
= 1;
3168 if (main_target_opt
)
3170 if (main_target_opt
->x_rs6000_single_float
!= rs6000_single_float
)
3171 error ("target attribute or pragma changes single precision floating "
3173 if (main_target_opt
->x_rs6000_double_float
!= rs6000_double_float
)
3174 error ("target attribute or pragma changes double precision floating "
3178 /* If not explicitly specified via option, decide whether to generate indexed
3179 load/store instructions. */
3180 if (TARGET_AVOID_XFORM
== -1)
3181 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3182 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3183 need indexed accesses and the type used is the scalar type of the element
3184 being loaded or stored. */
3185 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
3186 && !TARGET_ALTIVEC
);
3188 /* Set the -mrecip options. */
3189 if (rs6000_recip_name
)
3191 char *p
= ASTRDUP (rs6000_recip_name
);
3193 unsigned int mask
, i
;
3196 while ((q
= strtok (p
, ",")) != NULL
)
3207 if (!strcmp (q
, "default"))
3208 mask
= ((TARGET_RECIP_PRECISION
)
3209 ? RECIP_HIGH_PRECISION
: RECIP_LOW_PRECISION
);
3212 for (i
= 0; i
< ARRAY_SIZE (recip_options
); i
++)
3213 if (!strcmp (q
, recip_options
[i
].string
))
3215 mask
= recip_options
[i
].mask
;
3219 if (i
== ARRAY_SIZE (recip_options
))
3221 error ("unknown option for -mrecip=%s", q
);
3229 rs6000_recip_control
&= ~mask
;
3231 rs6000_recip_control
|= mask
;
3235 rs6000_init_hard_regno_mode_ok (global_init_p
);
3237 /* Save the initial options in case the user does function specific options */
3239 target_option_default_node
= target_option_current_node
3240 = build_target_option_node ();
3242 /* If not explicitly specified via option, decide whether to generate the
3243 extra blr's required to preserve the link stack on some cpus (eg, 476). */
3244 if (TARGET_LINK_STACK
== -1)
3245 SET_TARGET_LINK_STACK (rs6000_cpu
== PROCESSOR_PPC476
&& flag_pic
);
3250 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3251 define the target cpu type. */
3254 rs6000_option_override (void)
3256 (void) rs6000_option_override_internal (true);
3260 /* Implement targetm.vectorize.builtin_mask_for_load. */
3262 rs6000_builtin_mask_for_load (void)
3264 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3265 return altivec_builtin_mask_for_load
;
3270 /* Implement LOOP_ALIGN. */
3272 rs6000_loop_align (rtx label
)
3277 /* Don't override loop alignment if -falign-loops was specified. */
3278 if (!can_override_loop_align
)
3279 return align_loops_log
;
3281 bb
= BLOCK_FOR_INSN (label
);
3282 ninsns
= num_loop_insns(bb
->loop_father
);
3284 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3285 if (ninsns
> 4 && ninsns
<= 8
3286 && (rs6000_cpu
== PROCESSOR_POWER4
3287 || rs6000_cpu
== PROCESSOR_POWER5
3288 || rs6000_cpu
== PROCESSOR_POWER6
3289 || rs6000_cpu
== PROCESSOR_POWER7
))
3292 return align_loops_log
;
3295 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3297 rs6000_loop_align_max_skip (rtx label
)
3299 return (1 << rs6000_loop_align (label
)) - 1;
3302 /* Implement targetm.vectorize.builtin_conversion.
3303 Returns a decl of a function that implements conversion of an integer vector
3304 into a floating-point vector, or vice-versa. DEST_TYPE is the
3305 destination type and SRC_TYPE the source type of the conversion.
3306 Return NULL_TREE if it is not available. */
3308 rs6000_builtin_conversion (unsigned int tcode
, tree dest_type
, tree src_type
)
3310 enum tree_code code
= (enum tree_code
) tcode
;
3314 case FIX_TRUNC_EXPR
:
3315 switch (TYPE_MODE (dest_type
))
3318 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3321 return TYPE_UNSIGNED (dest_type
)
3322 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPUXDS_UNS
]
3323 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPSXDS
];
3326 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3329 return TYPE_UNSIGNED (dest_type
)
3330 ? rs6000_builtin_decls
[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
]
3331 : rs6000_builtin_decls
[VECTOR_BUILTIN_FIX_V4SF_V4SI
];
3338 switch (TYPE_MODE (src_type
))
3341 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3344 return TYPE_UNSIGNED (src_type
)
3345 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVUXDDP
]
3346 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVSXDDP
];
3349 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3352 return TYPE_UNSIGNED (src_type
)
3353 ? rs6000_builtin_decls
[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
]
3354 : rs6000_builtin_decls
[VECTOR_BUILTIN_FLOAT_V4SI_V4SF
];
3365 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3367 rs6000_builtin_mul_widen_even (tree type
)
3369 if (!TARGET_ALTIVEC
)
3372 switch (TYPE_MODE (type
))
3375 return TYPE_UNSIGNED (type
)
3376 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH_UNS
]
3377 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
3380 return TYPE_UNSIGNED (type
)
3381 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB_UNS
]
3382 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
3388 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3390 rs6000_builtin_mul_widen_odd (tree type
)
3392 if (!TARGET_ALTIVEC
)
3395 switch (TYPE_MODE (type
))
3398 return TYPE_UNSIGNED (type
)
3399 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH_UNS
]
3400 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
3403 return TYPE_UNSIGNED (type
)
3404 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB_UNS
]
3405 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
3412 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3413 after applying N number of iterations. This routine does not determine
3414 how may iterations are required to reach desired alignment. */
3417 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
3424 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
3427 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
3437 /* Assuming that all other types are naturally aligned. CHECKME! */
3442 /* Return true if the vector misalignment factor is supported by the
3445 rs6000_builtin_support_vector_misalignment (enum machine_mode mode
,
3452 /* Return if movmisalign pattern is not supported for this mode. */
3453 if (optab_handler (movmisalign_optab
, mode
) == CODE_FOR_nothing
)
3456 if (misalignment
== -1)
3458 /* Misalignment factor is unknown at compile time but we know
3459 it's word aligned. */
3460 if (rs6000_vector_alignment_reachable (type
, is_packed
))
3462 int element_size
= TREE_INT_CST_LOW (TYPE_SIZE (type
));
3464 if (element_size
== 64 || element_size
== 32)
3471 /* VSX supports word-aligned vector. */
3472 if (misalignment
% 4 == 0)
3478 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3480 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost
,
3481 tree vectype
, int misalign
)
3485 switch (type_of_cost
)
3495 case cond_branch_not_taken
:
3499 case cond_branch_taken
:
3502 case unaligned_load
:
3503 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3505 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3507 /* Double word aligned. */
3515 /* Double word aligned. */
3519 /* Unknown misalignment. */
3532 /* Misaligned loads are not supported. */
3537 case unaligned_store
:
3538 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3540 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3542 /* Double word aligned. */
3550 /* Double word aligned. */
3554 /* Unknown misalignment. */
3567 /* Misaligned stores are not supported. */
3577 /* Implement targetm.vectorize.preferred_simd_mode. */
3579 static enum machine_mode
3580 rs6000_preferred_simd_mode (enum machine_mode mode
)
3589 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3613 if (TARGET_PAIRED_FLOAT
3619 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3620 library with vectorized intrinsics. */
3623 rs6000_builtin_vectorized_libmass (tree fndecl
, tree type_out
, tree type_in
)
3626 const char *suffix
= NULL
;
3627 tree fntype
, new_fndecl
, bdecl
= NULL_TREE
;
3630 enum machine_mode el_mode
, in_mode
;
3633 /* Libmass is suitable for unsafe math only as it does not correctly support
3634 parts of IEEE with the required precision such as denormals. Only support
3635 it if we have VSX to use the simd d2 or f4 functions.
3636 XXX: Add variable length support. */
3637 if (!flag_unsafe_math_optimizations
|| !TARGET_VSX
)
3640 el_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3641 n
= TYPE_VECTOR_SUBPARTS (type_out
);
3642 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3643 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3644 if (el_mode
!= in_mode
3648 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3650 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3653 case BUILT_IN_ATAN2
:
3654 case BUILT_IN_HYPOT
:
3660 case BUILT_IN_ACOSH
:
3662 case BUILT_IN_ASINH
:
3664 case BUILT_IN_ATANH
:
3672 case BUILT_IN_EXPM1
:
3673 case BUILT_IN_LGAMMA
:
3674 case BUILT_IN_LOG10
:
3675 case BUILT_IN_LOG1P
:
3683 bdecl
= builtin_decl_implicit (fn
);
3684 suffix
= "d2"; /* pow -> powd2 */
3685 if (el_mode
!= DFmode
3690 case BUILT_IN_ATAN2F
:
3691 case BUILT_IN_HYPOTF
:
3696 case BUILT_IN_ACOSF
:
3697 case BUILT_IN_ACOSHF
:
3698 case BUILT_IN_ASINF
:
3699 case BUILT_IN_ASINHF
:
3700 case BUILT_IN_ATANF
:
3701 case BUILT_IN_ATANHF
:
3702 case BUILT_IN_CBRTF
:
3704 case BUILT_IN_COSHF
:
3706 case BUILT_IN_ERFCF
:
3707 case BUILT_IN_EXP2F
:
3709 case BUILT_IN_EXPM1F
:
3710 case BUILT_IN_LGAMMAF
:
3711 case BUILT_IN_LOG10F
:
3712 case BUILT_IN_LOG1PF
:
3713 case BUILT_IN_LOG2F
:
3716 case BUILT_IN_SINHF
:
3717 case BUILT_IN_SQRTF
:
3719 case BUILT_IN_TANHF
:
3720 bdecl
= builtin_decl_implicit (fn
);
3721 suffix
= "4"; /* powf -> powf4 */
3722 if (el_mode
!= SFmode
3734 gcc_assert (suffix
!= NULL
);
3735 bname
= IDENTIFIER_POINTER (DECL_NAME (bdecl
));
3736 strcpy (name
, bname
+ sizeof ("__builtin_") - 1);
3737 strcat (name
, suffix
);
3740 fntype
= build_function_type_list (type_out
, type_in
, NULL
);
3741 else if (n_args
== 2)
3742 fntype
= build_function_type_list (type_out
, type_in
, type_in
, NULL
);
3746 /* Build a function declaration for the vectorized function. */
3747 new_fndecl
= build_decl (BUILTINS_LOCATION
,
3748 FUNCTION_DECL
, get_identifier (name
), fntype
);
3749 TREE_PUBLIC (new_fndecl
) = 1;
3750 DECL_EXTERNAL (new_fndecl
) = 1;
3751 DECL_IS_NOVOPS (new_fndecl
) = 1;
3752 TREE_READONLY (new_fndecl
) = 1;
3757 /* Returns a function decl for a vectorized version of the builtin function
3758 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3759 if it is not available. */
3762 rs6000_builtin_vectorized_function (tree fndecl
, tree type_out
,
3765 enum machine_mode in_mode
, out_mode
;
3768 if (TREE_CODE (type_out
) != VECTOR_TYPE
3769 || TREE_CODE (type_in
) != VECTOR_TYPE
3770 || !TARGET_VECTORIZE_BUILTINS
)
3773 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3774 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
3775 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3776 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3778 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3780 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3783 case BUILT_IN_COPYSIGN
:
3784 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3785 && out_mode
== DFmode
&& out_n
== 2
3786 && in_mode
== DFmode
&& in_n
== 2)
3787 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNDP
];
3789 case BUILT_IN_COPYSIGNF
:
3790 if (out_mode
!= SFmode
|| out_n
!= 4
3791 || in_mode
!= SFmode
|| in_n
!= 4)
3793 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3794 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNSP
];
3795 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3796 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_COPYSIGN_V4SF
];
3799 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3800 && out_mode
== DFmode
&& out_n
== 2
3801 && in_mode
== DFmode
&& in_n
== 2)
3802 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTDP
];
3804 case BUILT_IN_SQRTF
:
3805 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3806 && out_mode
== SFmode
&& out_n
== 4
3807 && in_mode
== SFmode
&& in_n
== 4)
3808 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTSP
];
3811 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3812 && out_mode
== DFmode
&& out_n
== 2
3813 && in_mode
== DFmode
&& in_n
== 2)
3814 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIP
];
3816 case BUILT_IN_CEILF
:
3817 if (out_mode
!= SFmode
|| out_n
!= 4
3818 || in_mode
!= SFmode
|| in_n
!= 4)
3820 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3821 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIP
];
3822 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3823 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIP
];
3825 case BUILT_IN_FLOOR
:
3826 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3827 && out_mode
== DFmode
&& out_n
== 2
3828 && in_mode
== DFmode
&& in_n
== 2)
3829 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIM
];
3831 case BUILT_IN_FLOORF
:
3832 if (out_mode
!= SFmode
|| out_n
!= 4
3833 || in_mode
!= SFmode
|| in_n
!= 4)
3835 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3836 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIM
];
3837 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3838 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIM
];
3841 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3842 && out_mode
== DFmode
&& out_n
== 2
3843 && in_mode
== DFmode
&& in_n
== 2)
3844 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDDP
];
3847 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3848 && out_mode
== SFmode
&& out_n
== 4
3849 && in_mode
== SFmode
&& in_n
== 4)
3850 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDSP
];
3851 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
)
3852 && out_mode
== SFmode
&& out_n
== 4
3853 && in_mode
== SFmode
&& in_n
== 4)
3854 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMADDFP
];
3856 case BUILT_IN_TRUNC
:
3857 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3858 && out_mode
== DFmode
&& out_n
== 2
3859 && in_mode
== DFmode
&& in_n
== 2)
3860 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIZ
];
3862 case BUILT_IN_TRUNCF
:
3863 if (out_mode
!= SFmode
|| out_n
!= 4
3864 || in_mode
!= SFmode
|| in_n
!= 4)
3866 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3867 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIZ
];
3868 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3869 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIZ
];
3871 case BUILT_IN_NEARBYINT
:
3872 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3873 && flag_unsafe_math_optimizations
3874 && out_mode
== DFmode
&& out_n
== 2
3875 && in_mode
== DFmode
&& in_n
== 2)
3876 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPI
];
3878 case BUILT_IN_NEARBYINTF
:
3879 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3880 && flag_unsafe_math_optimizations
3881 && out_mode
== SFmode
&& out_n
== 4
3882 && in_mode
== SFmode
&& in_n
== 4)
3883 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPI
];
3886 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3887 && !flag_trapping_math
3888 && out_mode
== DFmode
&& out_n
== 2
3889 && in_mode
== DFmode
&& in_n
== 2)
3890 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIC
];
3892 case BUILT_IN_RINTF
:
3893 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3894 && !flag_trapping_math
3895 && out_mode
== SFmode
&& out_n
== 4
3896 && in_mode
== SFmode
&& in_n
== 4)
3897 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIC
];
3904 else if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
3906 enum rs6000_builtins fn
3907 = (enum rs6000_builtins
)DECL_FUNCTION_CODE (fndecl
);
3910 case RS6000_BUILTIN_RSQRTF
:
3911 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
3912 && out_mode
== SFmode
&& out_n
== 4
3913 && in_mode
== SFmode
&& in_n
== 4)
3914 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRSQRTFP
];
3916 case RS6000_BUILTIN_RSQRT
:
3917 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3918 && out_mode
== DFmode
&& out_n
== 2
3919 && in_mode
== DFmode
&& in_n
== 2)
3920 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
3922 case RS6000_BUILTIN_RECIPF
:
3923 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
3924 && out_mode
== SFmode
&& out_n
== 4
3925 && in_mode
== SFmode
&& in_n
== 4)
3926 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRECIPFP
];
3928 case RS6000_BUILTIN_RECIP
:
3929 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3930 && out_mode
== DFmode
&& out_n
== 2
3931 && in_mode
== DFmode
&& in_n
== 2)
3932 return rs6000_builtin_decls
[VSX_BUILTIN_RECIP_V2DF
];
3939 /* Generate calls to libmass if appropriate. */
3940 if (rs6000_veclib_handler
)
3941 return rs6000_veclib_handler (fndecl
, type_out
, type_in
);
3946 /* Default CPU string for rs6000*_file_start functions. */
3947 static const char *rs6000_default_cpu
;
3949 /* Do anything needed at the start of the asm file. */
3952 rs6000_file_start (void)
3955 const char *start
= buffer
;
3956 FILE *file
= asm_out_file
;
3958 rs6000_default_cpu
= TARGET_CPU_DEFAULT
;
3960 default_file_start ();
3962 #ifdef TARGET_BI_ARCH
3963 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
3964 rs6000_default_cpu
= 0;
3967 if (flag_verbose_asm
)
3969 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
3971 if (rs6000_default_cpu
!= 0 && rs6000_default_cpu
[0] != '\0')
3973 fprintf (file
, "%s --with-cpu=%s", start
, rs6000_default_cpu
);
3977 if (global_options_set
.x_rs6000_cpu_index
)
3979 fprintf (file
, "%s -mcpu=%s", start
,
3980 processor_target_table
[rs6000_cpu_index
].name
);
3984 if (global_options_set
.x_rs6000_tune_index
)
3986 fprintf (file
, "%s -mtune=%s", start
,
3987 processor_target_table
[rs6000_tune_index
].name
);
3991 if (PPC405_ERRATUM77
)
3993 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
3997 #ifdef USING_ELFOS_H
3998 switch (rs6000_sdata
)
4000 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
4001 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
4002 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
4003 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
4006 if (rs6000_sdata
&& g_switch_value
)
4008 fprintf (file
, "%s -G %d", start
,
4018 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
4020 switch_to_section (toc_section
);
4021 switch_to_section (text_section
);
4026 /* Return nonzero if this function is known to have a null epilogue. */
4029 direct_return (void)
4031 if (reload_completed
)
4033 rs6000_stack_t
*info
= rs6000_stack_info ();
4035 if (info
->first_gp_reg_save
== 32
4036 && info
->first_fp_reg_save
== 64
4037 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
4038 && ! info
->lr_save_p
4039 && ! info
->cr_save_p
4040 && info
->vrsave_mask
== 0
4048 /* Return the number of instructions it takes to form a constant in an
4049 integer register. */
4052 num_insns_constant_wide (HOST_WIDE_INT value
)
4054 /* signed constant loadable with {cal|addi} */
4055 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
4058 /* constant loadable with {cau|addis} */
4059 else if ((value
& 0xffff) == 0
4060 && (value
>> 31 == -1 || value
>> 31 == 0))
4063 #if HOST_BITS_PER_WIDE_INT == 64
4064 else if (TARGET_POWERPC64
)
4066 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
4067 HOST_WIDE_INT high
= value
>> 31;
4069 if (high
== 0 || high
== -1)
4075 return num_insns_constant_wide (high
) + 1;
4077 return num_insns_constant_wide (low
) + 1;
4079 return (num_insns_constant_wide (high
)
4080 + num_insns_constant_wide (low
) + 1);
4089 num_insns_constant (rtx op
, enum machine_mode mode
)
4091 HOST_WIDE_INT low
, high
;
4093 switch (GET_CODE (op
))
4096 #if HOST_BITS_PER_WIDE_INT == 64
4097 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
4098 && mask64_operand (op
, mode
))
4102 return num_insns_constant_wide (INTVAL (op
));
4105 if (mode
== SFmode
|| mode
== SDmode
)
4110 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4111 if (DECIMAL_FLOAT_MODE_P (mode
))
4112 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
4114 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
4115 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
4118 if (mode
== VOIDmode
|| mode
== DImode
)
4120 high
= CONST_DOUBLE_HIGH (op
);
4121 low
= CONST_DOUBLE_LOW (op
);
4128 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4129 if (DECIMAL_FLOAT_MODE_P (mode
))
4130 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
4132 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
4133 high
= l
[WORDS_BIG_ENDIAN
== 0];
4134 low
= l
[WORDS_BIG_ENDIAN
!= 0];
4138 return (num_insns_constant_wide (low
)
4139 + num_insns_constant_wide (high
));
4142 if ((high
== 0 && low
>= 0)
4143 || (high
== -1 && low
< 0))
4144 return num_insns_constant_wide (low
);
4146 else if (mask64_operand (op
, mode
))
4150 return num_insns_constant_wide (high
) + 1;
4153 return (num_insns_constant_wide (high
)
4154 + num_insns_constant_wide (low
) + 1);
4162 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4163 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4164 corresponding element of the vector, but for V4SFmode and V2SFmode,
4165 the corresponding "float" is interpreted as an SImode integer. */
4168 const_vector_elt_as_int (rtx op
, unsigned int elt
)
4172 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4173 gcc_assert (GET_MODE (op
) != V2DImode
4174 && GET_MODE (op
) != V2DFmode
);
4176 tmp
= CONST_VECTOR_ELT (op
, elt
);
4177 if (GET_MODE (op
) == V4SFmode
4178 || GET_MODE (op
) == V2SFmode
)
4179 tmp
= gen_lowpart (SImode
, tmp
);
4180 return INTVAL (tmp
);
4183 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4184 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4185 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4186 all items are set to the same value and contain COPIES replicas of the
4187 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4188 operand and the others are set to the value of the operand's msb. */
4191 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
4193 enum machine_mode mode
= GET_MODE (op
);
4194 enum machine_mode inner
= GET_MODE_INNER (mode
);
4202 HOST_WIDE_INT splat_val
;
4203 HOST_WIDE_INT msb_val
;
4205 if (mode
== V2DImode
|| mode
== V2DFmode
)
4208 nunits
= GET_MODE_NUNITS (mode
);
4209 bitsize
= GET_MODE_BITSIZE (inner
);
4210 mask
= GET_MODE_MASK (inner
);
4212 val
= const_vector_elt_as_int (op
, nunits
- 1);
4214 msb_val
= val
> 0 ? 0 : -1;
4216 /* Construct the value to be splatted, if possible. If not, return 0. */
4217 for (i
= 2; i
<= copies
; i
*= 2)
4219 HOST_WIDE_INT small_val
;
4221 small_val
= splat_val
>> bitsize
;
4223 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
4225 splat_val
= small_val
;
4228 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4229 if (EASY_VECTOR_15 (splat_val
))
4232 /* Also check if we can splat, and then add the result to itself. Do so if
4233 the value is positive, of if the splat instruction is using OP's mode;
4234 for splat_val < 0, the splat and the add should use the same mode. */
4235 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
4236 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
4239 /* Also check if are loading up the most significant bit which can be done by
4240 loading up -1 and shifting the value left by -1. */
4241 else if (EASY_VECTOR_MSB (splat_val
, inner
))
4247 /* Check if VAL is present in every STEP-th element, and the
4248 other elements are filled with its most significant bit. */
4249 for (i
= 0; i
< nunits
- 1; ++i
)
4251 HOST_WIDE_INT desired_val
;
4252 if (((i
+ 1) & (step
- 1)) == 0)
4255 desired_val
= msb_val
;
4257 if (desired_val
!= const_vector_elt_as_int (op
, i
))
4265 /* Return true if OP is of the given MODE and can be synthesized
4266 with a vspltisb, vspltish or vspltisw. */
4269 easy_altivec_constant (rtx op
, enum machine_mode mode
)
4271 unsigned step
, copies
;
4273 if (mode
== VOIDmode
)
4274 mode
= GET_MODE (op
);
4275 else if (mode
!= GET_MODE (op
))
4278 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4280 if (mode
== V2DFmode
)
4281 return zero_constant (op
, mode
);
4283 if (mode
== V2DImode
)
4285 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4287 if (GET_CODE (CONST_VECTOR_ELT (op
, 0)) != CONST_INT
4288 || GET_CODE (CONST_VECTOR_ELT (op
, 1)) != CONST_INT
)
4291 if (zero_constant (op
, mode
))
4294 if (INTVAL (CONST_VECTOR_ELT (op
, 0)) == -1
4295 && INTVAL (CONST_VECTOR_ELT (op
, 1)) == -1)
4301 /* Start with a vspltisw. */
4302 step
= GET_MODE_NUNITS (mode
) / 4;
4305 if (vspltis_constant (op
, step
, copies
))
4308 /* Then try with a vspltish. */
4314 if (vspltis_constant (op
, step
, copies
))
4317 /* And finally a vspltisb. */
4323 if (vspltis_constant (op
, step
, copies
))
4329 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4330 result is OP. Abort if it is not possible. */
4333 gen_easy_altivec_constant (rtx op
)
4335 enum machine_mode mode
= GET_MODE (op
);
4336 int nunits
= GET_MODE_NUNITS (mode
);
4337 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
4338 unsigned step
= nunits
/ 4;
4339 unsigned copies
= 1;
4341 /* Start with a vspltisw. */
4342 if (vspltis_constant (op
, step
, copies
))
4343 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
4345 /* Then try with a vspltish. */
4351 if (vspltis_constant (op
, step
, copies
))
4352 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
4354 /* And finally a vspltisb. */
4360 if (vspltis_constant (op
, step
, copies
))
4361 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
4367 output_vec_const_move (rtx
*operands
)
4370 enum machine_mode mode
;
4375 mode
= GET_MODE (dest
);
4379 if (zero_constant (vec
, mode
))
4380 return "xxlxor %x0,%x0,%x0";
4382 if (mode
== V2DImode
4383 && INTVAL (CONST_VECTOR_ELT (vec
, 0)) == -1
4384 && INTVAL (CONST_VECTOR_ELT (vec
, 1)) == -1)
4385 return "vspltisw %0,-1";
4391 if (zero_constant (vec
, mode
))
4392 return "vxor %0,%0,%0";
4394 splat_vec
= gen_easy_altivec_constant (vec
);
4395 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
4396 operands
[1] = XEXP (splat_vec
, 0);
4397 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
4400 switch (GET_MODE (splat_vec
))
4403 return "vspltisw %0,%1";
4406 return "vspltish %0,%1";
4409 return "vspltisb %0,%1";
4416 gcc_assert (TARGET_SPE
);
4418 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4419 pattern of V1DI, V4HI, and V2SF.
4421 FIXME: We should probably return # and add post reload
4422 splitters for these, but this way is so easy ;-). */
4423 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
4424 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
4425 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
4426 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
4428 return "li %0,%1\n\tevmergelo %0,%0,%0";
4430 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4433 /* Initialize TARGET of vector PAIRED to VALS. */
4436 paired_expand_vector_init (rtx target
, rtx vals
)
4438 enum machine_mode mode
= GET_MODE (target
);
4439 int n_elts
= GET_MODE_NUNITS (mode
);
4441 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
4444 for (i
= 0; i
< n_elts
; ++i
)
4446 x
= XVECEXP (vals
, 0, i
);
4447 if (!(CONST_INT_P (x
)
4448 || GET_CODE (x
) == CONST_DOUBLE
4449 || GET_CODE (x
) == CONST_FIXED
))
4454 /* Load from constant pool. */
4455 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
4461 /* The vector is initialized only with non-constants. */
4462 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
4463 XVECEXP (vals
, 0, 1));
4465 emit_move_insn (target
, new_rtx
);
4469 /* One field is non-constant and the other one is a constant. Load the
4470 constant from the constant pool and use ps_merge instruction to
4471 construct the whole vector. */
4472 op1
= XVECEXP (vals
, 0, 0);
4473 op2
= XVECEXP (vals
, 0, 1);
4475 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
4477 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
4478 emit_move_insn (tmp
, constant_op
);
4480 if (CONSTANT_P (op1
))
4481 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
4483 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
4485 emit_move_insn (target
, new_rtx
);
4489 paired_expand_vector_move (rtx operands
[])
4491 rtx op0
= operands
[0], op1
= operands
[1];
4493 emit_move_insn (op0
, op1
);
4496 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4497 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4498 operands for the relation operation COND. This is a recursive
4502 paired_emit_vector_compare (enum rtx_code rcode
,
4503 rtx dest
, rtx op0
, rtx op1
,
4504 rtx cc_op0
, rtx cc_op1
)
4506 rtx tmp
= gen_reg_rtx (V2SFmode
);
4509 gcc_assert (TARGET_PAIRED_FLOAT
);
4510 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
4516 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4520 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4521 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
4525 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
4528 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4531 tmp1
= gen_reg_rtx (V2SFmode
);
4532 max
= gen_reg_rtx (V2SFmode
);
4533 min
= gen_reg_rtx (V2SFmode
);
4534 gen_reg_rtx (V2SFmode
);
4536 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4537 emit_insn (gen_selv2sf4
4538 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4539 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
4540 emit_insn (gen_selv2sf4
4541 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4542 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
4543 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
4546 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4549 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4552 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4555 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4558 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4567 /* Emit vector conditional expression.
4568 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4569 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4572 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
4573 rtx cond
, rtx cc_op0
, rtx cc_op1
)
4575 enum rtx_code rcode
= GET_CODE (cond
);
4577 if (!TARGET_PAIRED_FLOAT
)
4580 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
4585 /* Initialize vector TARGET to VALS. */
4588 rs6000_expand_vector_init (rtx target
, rtx vals
)
4590 enum machine_mode mode
= GET_MODE (target
);
4591 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
4592 int n_elts
= GET_MODE_NUNITS (mode
);
4593 int n_var
= 0, one_var
= -1;
4594 bool all_same
= true, all_const_zero
= true;
4598 for (i
= 0; i
< n_elts
; ++i
)
4600 x
= XVECEXP (vals
, 0, i
);
4601 if (!(CONST_INT_P (x
)
4602 || GET_CODE (x
) == CONST_DOUBLE
4603 || GET_CODE (x
) == CONST_FIXED
))
4604 ++n_var
, one_var
= i
;
4605 else if (x
!= CONST0_RTX (inner_mode
))
4606 all_const_zero
= false;
4608 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
4614 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
4615 bool int_vector_p
= (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
4616 if ((int_vector_p
|| TARGET_VSX
) && all_const_zero
)
4618 /* Zero register. */
4619 emit_insn (gen_rtx_SET (VOIDmode
, target
,
4620 gen_rtx_XOR (mode
, target
, target
)));
4623 else if (int_vector_p
&& easy_vector_constant (const_vec
, mode
))
4625 /* Splat immediate. */
4626 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
4631 /* Load from constant pool. */
4632 emit_move_insn (target
, const_vec
);
4637 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4638 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
4642 rtx element
= XVECEXP (vals
, 0, 0);
4643 if (mode
== V2DFmode
)
4644 emit_insn (gen_vsx_splat_v2df (target
, element
));
4646 emit_insn (gen_vsx_splat_v2di (target
, element
));
4650 if (mode
== V2DFmode
)
4652 rtx op0
= copy_to_mode_reg (DFmode
, XVECEXP (vals
, 0, 0));
4653 rtx op1
= copy_to_mode_reg (DFmode
, XVECEXP (vals
, 0, 1));
4654 emit_insn (gen_vsx_concat_v2df (target
, op0
, op1
));
4658 rtx op0
= copy_to_mode_reg (DImode
, XVECEXP (vals
, 0, 0));
4659 rtx op1
= copy_to_mode_reg (DImode
, XVECEXP (vals
, 0, 1));
4660 emit_insn (gen_vsx_concat_v2di (target
, op0
, op1
));
4666 /* With single precision floating point on VSX, know that internally single
4667 precision is actually represented as a double, and either make 2 V2DF
4668 vectors, and convert these vectors to single precision, or do one
4669 conversion, and splat the result to the other elements. */
4670 if (mode
== V4SFmode
&& VECTOR_MEM_VSX_P (mode
))
4674 rtx freg
= gen_reg_rtx (V4SFmode
);
4675 rtx sreg
= copy_to_reg (XVECEXP (vals
, 0, 0));
4677 emit_insn (gen_vsx_xscvdpsp_scalar (freg
, sreg
));
4678 emit_insn (gen_vsx_xxspltw_v4sf (target
, freg
, const0_rtx
));
4682 rtx dbl_even
= gen_reg_rtx (V2DFmode
);
4683 rtx dbl_odd
= gen_reg_rtx (V2DFmode
);
4684 rtx flt_even
= gen_reg_rtx (V4SFmode
);
4685 rtx flt_odd
= gen_reg_rtx (V4SFmode
);
4687 emit_insn (gen_vsx_concat_v2sf (dbl_even
,
4688 copy_to_reg (XVECEXP (vals
, 0, 0)),
4689 copy_to_reg (XVECEXP (vals
, 0, 1))));
4690 emit_insn (gen_vsx_concat_v2sf (dbl_odd
,
4691 copy_to_reg (XVECEXP (vals
, 0, 2)),
4692 copy_to_reg (XVECEXP (vals
, 0, 3))));
4693 emit_insn (gen_vsx_xvcvdpsp (flt_even
, dbl_even
));
4694 emit_insn (gen_vsx_xvcvdpsp (flt_odd
, dbl_odd
));
4695 emit_insn (gen_vec_extract_evenv4sf (target
, flt_even
, flt_odd
));
4700 /* Store value to stack temp. Load vector element. Splat. However, splat
4701 of 64-bit items is not supported on Altivec. */
4702 if (all_same
&& GET_MODE_SIZE (inner_mode
) <= 4)
4704 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
4705 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
4706 XVECEXP (vals
, 0, 0));
4707 x
= gen_rtx_UNSPEC (VOIDmode
,
4708 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
4709 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4711 gen_rtx_SET (VOIDmode
,
4714 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
4715 gen_rtx_PARALLEL (VOIDmode
,
4716 gen_rtvec (1, const0_rtx
)));
4717 emit_insn (gen_rtx_SET (VOIDmode
, target
,
4718 gen_rtx_VEC_DUPLICATE (mode
, x
)));
4722 /* One field is non-constant. Load constant then overwrite
4726 rtx copy
= copy_rtx (vals
);
4728 /* Load constant part of vector, substitute neighboring value for
4730 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
4731 rs6000_expand_vector_init (target
, copy
);
4733 /* Insert variable. */
4734 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
4738 /* Construct the vector in memory one field at a time
4739 and load the whole vector. */
4740 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
4741 for (i
= 0; i
< n_elts
; i
++)
4742 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
4743 i
* GET_MODE_SIZE (inner_mode
)),
4744 XVECEXP (vals
, 0, i
));
4745 emit_move_insn (target
, mem
);
4748 /* Set field ELT of TARGET to VAL. */
4751 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
4753 enum machine_mode mode
= GET_MODE (target
);
4754 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
4755 rtx reg
= gen_reg_rtx (mode
);
4757 int width
= GET_MODE_SIZE (inner_mode
);
4760 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
4762 rtx (*set_func
) (rtx
, rtx
, rtx
, rtx
)
4763 = ((mode
== V2DFmode
) ? gen_vsx_set_v2df
: gen_vsx_set_v2di
);
4764 emit_insn (set_func (target
, target
, val
, GEN_INT (elt
)));
4768 /* Load single variable value. */
4769 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
4770 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
4771 x
= gen_rtx_UNSPEC (VOIDmode
,
4772 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
4773 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4775 gen_rtx_SET (VOIDmode
,
4779 /* Linear sequence. */
4780 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
4781 for (i
= 0; i
< 16; ++i
)
4782 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
4784 /* Set permute mask to insert element into target. */
4785 for (i
= 0; i
< width
; ++i
)
4786 XVECEXP (mask
, 0, elt
*width
+ i
)
4787 = GEN_INT (i
+ 0x10);
4788 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
4789 x
= gen_rtx_UNSPEC (mode
,
4790 gen_rtvec (3, target
, reg
,
4791 force_reg (V16QImode
, x
)),
4793 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
4796 /* Extract field ELT from VEC into TARGET. */
4799 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
4801 enum machine_mode mode
= GET_MODE (vec
);
4802 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
4805 if (VECTOR_MEM_VSX_P (mode
))
4812 emit_insn (gen_vsx_extract_v2df (target
, vec
, GEN_INT (elt
)));
4815 emit_insn (gen_vsx_extract_v2di (target
, vec
, GEN_INT (elt
)));
4818 emit_insn (gen_vsx_extract_v4sf (target
, vec
, GEN_INT (elt
)));
4823 /* Allocate mode-sized buffer. */
4824 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
4826 emit_move_insn (mem
, vec
);
4828 /* Add offset to field within buffer matching vector element. */
4829 mem
= adjust_address_nv (mem
, inner_mode
, elt
* GET_MODE_SIZE (inner_mode
));
4831 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
4834 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4835 implement ANDing by the mask IN. */
4837 build_mask64_2_operands (rtx in
, rtx
*out
)
4839 #if HOST_BITS_PER_WIDE_INT >= 64
4840 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
4843 gcc_assert (GET_CODE (in
) == CONST_INT
);
4848 /* Assume c initially something like 0x00fff000000fffff. The idea
4849 is to rotate the word so that the middle ^^^^^^ group of zeros
4850 is at the MS end and can be cleared with an rldicl mask. We then
4851 rotate back and clear off the MS ^^ group of zeros with a
4853 c
= ~c
; /* c == 0xff000ffffff00000 */
4854 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
4855 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
4856 c
= ~c
; /* c == 0x00fff000000fffff */
4857 c
&= -lsb
; /* c == 0x00fff00000000000 */
4858 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
4859 c
= ~c
; /* c == 0xff000fffffffffff */
4860 c
&= -lsb
; /* c == 0xff00000000000000 */
4862 while ((lsb
>>= 1) != 0)
4863 shift
++; /* shift == 44 on exit from loop */
4864 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
4865 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
4866 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
4870 /* Assume c initially something like 0xff000f0000000000. The idea
4871 is to rotate the word so that the ^^^ middle group of zeros
4872 is at the LS end and can be cleared with an rldicr mask. We then
4873 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4875 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
4876 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
4877 c
= ~c
; /* c == 0x00fff0ffffffffff */
4878 c
&= -lsb
; /* c == 0x00fff00000000000 */
4879 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
4880 c
= ~c
; /* c == 0xff000fffffffffff */
4881 c
&= -lsb
; /* c == 0xff00000000000000 */
4883 while ((lsb
>>= 1) != 0)
4884 shift
++; /* shift == 44 on exit from loop */
4885 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
4886 m1
>>= shift
; /* m1 == 0x0000000000000fff */
4887 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
4890 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4891 masks will be all 1's. We are guaranteed more than one transition. */
4892 out
[0] = GEN_INT (64 - shift
);
4893 out
[1] = GEN_INT (m1
);
4894 out
[2] = GEN_INT (shift
);
4895 out
[3] = GEN_INT (m2
);
4903 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4906 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
4908 if (TARGET_E500_DOUBLE
)
4910 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4911 subreg:TI and reg:TF. Decimal float modes are like integer
4912 modes (only low part of each register used) for this
4914 if (GET_CODE (op
) == SUBREG
4915 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
4916 || mode
== DDmode
|| mode
== TDmode
)
4917 && REG_P (SUBREG_REG (op
))
4918 && (GET_MODE (SUBREG_REG (op
)) == DFmode
4919 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
4922 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4924 if (GET_CODE (op
) == SUBREG
4925 && (mode
== DFmode
|| mode
== TFmode
)
4926 && REG_P (SUBREG_REG (op
))
4927 && (GET_MODE (SUBREG_REG (op
)) == DImode
4928 || GET_MODE (SUBREG_REG (op
)) == TImode
4929 || GET_MODE (SUBREG_REG (op
)) == DDmode
4930 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
4935 && GET_CODE (op
) == SUBREG
4937 && REG_P (SUBREG_REG (op
))
4938 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
4944 /* AIX increases natural record alignment to doubleword if the first
4945 field is an FP double while the FP fields remain word aligned. */
4948 rs6000_special_round_type_align (tree type
, unsigned int computed
,
4949 unsigned int specified
)
4951 unsigned int align
= MAX (computed
, specified
);
4952 tree field
= TYPE_FIELDS (type
);
4954 /* Skip all non field decls */
4955 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
4956 field
= DECL_CHAIN (field
);
4958 if (field
!= NULL
&& field
!= type
)
4960 type
= TREE_TYPE (field
);
4961 while (TREE_CODE (type
) == ARRAY_TYPE
)
4962 type
= TREE_TYPE (type
);
4964 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
4965 align
= MAX (align
, 64);
4971 /* Darwin increases record alignment to the natural alignment of
4975 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
4976 unsigned int specified
)
4978 unsigned int align
= MAX (computed
, specified
);
4980 if (TYPE_PACKED (type
))
4983 /* Find the first field, looking down into aggregates. */
4985 tree field
= TYPE_FIELDS (type
);
4986 /* Skip all non field decls */
4987 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
4988 field
= DECL_CHAIN (field
);
4991 /* A packed field does not contribute any extra alignment. */
4992 if (DECL_PACKED (field
))
4994 type
= TREE_TYPE (field
);
4995 while (TREE_CODE (type
) == ARRAY_TYPE
)
4996 type
= TREE_TYPE (type
);
4997 } while (AGGREGATE_TYPE_P (type
));
4999 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
5000 align
= MAX (align
, TYPE_ALIGN (type
));
5005 /* Return 1 for an operand in small memory on V.4/eabi. */
5008 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
5009 enum machine_mode mode ATTRIBUTE_UNUSED
)
5014 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
5017 if (DEFAULT_ABI
!= ABI_V4
)
5020 /* Vector and float memory instructions have a limited offset on the
5021 SPE, so using a vector or float variable directly as an operand is
5024 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
5027 if (GET_CODE (op
) == SYMBOL_REF
)
5030 else if (GET_CODE (op
) != CONST
5031 || GET_CODE (XEXP (op
, 0)) != PLUS
5032 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
5033 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
5038 rtx sum
= XEXP (op
, 0);
5039 HOST_WIDE_INT summand
;
5041 /* We have to be careful here, because it is the referenced address
5042 that must be 32k from _SDA_BASE_, not just the symbol. */
5043 summand
= INTVAL (XEXP (sum
, 1));
5044 if (summand
< 0 || summand
> g_switch_value
)
5047 sym_ref
= XEXP (sum
, 0);
5050 return SYMBOL_REF_SMALL_P (sym_ref
);
5056 /* Return true if either operand is a general purpose register. */
5059 gpr_or_gpr_p (rtx op0
, rtx op1
)
5061 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
5062 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
5066 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5069 reg_offset_addressing_ok_p (enum machine_mode mode
)
5079 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5080 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
5088 /* Paired vector modes. Only reg+reg addressing is valid. */
5089 if (TARGET_PAIRED_FLOAT
)
5101 virtual_stack_registers_memory_p (rtx op
)
5105 if (GET_CODE (op
) == REG
)
5106 regnum
= REGNO (op
);
5108 else if (GET_CODE (op
) == PLUS
5109 && GET_CODE (XEXP (op
, 0)) == REG
5110 && GET_CODE (XEXP (op
, 1)) == CONST_INT
)
5111 regnum
= REGNO (XEXP (op
, 0));
5116 return (regnum
>= FIRST_VIRTUAL_REGISTER
5117 && regnum
<= LAST_VIRTUAL_POINTER_REGISTER
);
5120 /* Return true if memory accesses to OP are known to never straddle
5124 offsettable_ok_by_alignment (rtx op
, HOST_WIDE_INT offset
,
5125 enum machine_mode mode
)
5128 unsigned HOST_WIDE_INT dsize
, dalign
;
5130 if (GET_CODE (op
) != SYMBOL_REF
)
5133 decl
= SYMBOL_REF_DECL (op
);
5136 if (GET_MODE_SIZE (mode
) == 0)
5139 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5140 replacing memory addresses with an anchor plus offset. We
5141 could find the decl by rummaging around in the block->objects
5142 VEC for the given offset but that seems like too much work. */
5144 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op
)
5145 && SYMBOL_REF_ANCHOR_P (op
)
5146 && SYMBOL_REF_BLOCK (op
) != NULL
)
5148 struct object_block
*block
= SYMBOL_REF_BLOCK (op
);
5149 HOST_WIDE_INT lsb
, mask
;
5151 /* Given the alignment of the block.. */
5152 dalign
= block
->alignment
;
5153 mask
= dalign
/ BITS_PER_UNIT
- 1;
5155 /* ..and the combined offset of the anchor and any offset
5156 to this block object.. */
5157 offset
+= SYMBOL_REF_BLOCK_OFFSET (op
);
5158 lsb
= offset
& -offset
;
5160 /* ..find how many bits of the alignment we know for the
5165 return dalign
>= GET_MODE_SIZE (mode
);
5170 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5173 if (!DECL_SIZE_UNIT (decl
))
5176 if (!host_integerp (DECL_SIZE_UNIT (decl
), 1))
5179 dsize
= tree_low_cst (DECL_SIZE_UNIT (decl
), 1);
5183 dalign
= DECL_ALIGN_UNIT (decl
);
5184 return dalign
>= dsize
;
5187 type
= TREE_TYPE (decl
);
5189 if (TREE_CODE (decl
) == STRING_CST
)
5190 dsize
= TREE_STRING_LENGTH (decl
);
5191 else if (TYPE_SIZE_UNIT (type
)
5192 && host_integerp (TYPE_SIZE_UNIT (type
), 1))
5193 dsize
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
5199 dalign
= TYPE_ALIGN (type
);
5200 if (CONSTANT_CLASS_P (decl
))
5201 dalign
= CONSTANT_ALIGNMENT (decl
, dalign
);
5203 dalign
= DATA_ALIGNMENT (decl
, dalign
);
5204 dalign
/= BITS_PER_UNIT
;
5205 return dalign
>= dsize
;
5209 constant_pool_expr_p (rtx op
)
5213 split_const (op
, &base
, &offset
);
5214 return (GET_CODE (base
) == SYMBOL_REF
5215 && CONSTANT_POOL_ADDRESS_P (base
)
5216 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
5219 static rtx tocrel_base
, tocrel_offset
;
5222 toc_relative_expr_p (rtx op
)
5224 if (GET_CODE (op
) != CONST
)
5227 split_const (op
, &tocrel_base
, &tocrel_offset
);
5228 return (GET_CODE (tocrel_base
) == UNSPEC
5229 && XINT (tocrel_base
, 1) == UNSPEC_TOCREL
);
5232 /* Return true if X is a constant pool address, and also for cmodel=medium
5233 if X is a toc-relative address known to be offsettable within MODE. */
5236 legitimate_constant_pool_address_p (const_rtx x
, enum machine_mode mode
,
5240 && (GET_CODE (x
) == PLUS
|| GET_CODE (x
) == LO_SUM
)
5241 && GET_CODE (XEXP (x
, 0)) == REG
5242 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
5243 || ((TARGET_MINIMAL_TOC
5244 || TARGET_CMODEL
!= CMODEL_SMALL
)
5245 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
)))
5246 && toc_relative_expr_p (XEXP (x
, 1))
5247 && (TARGET_CMODEL
!= CMODEL_MEDIUM
5248 || constant_pool_expr_p (XVECEXP (tocrel_base
, 0, 0))
5250 || offsettable_ok_by_alignment (XVECEXP (tocrel_base
, 0, 0),
5251 INTVAL (tocrel_offset
), mode
)));
5255 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
5257 return (DEFAULT_ABI
== ABI_V4
5258 && !flag_pic
&& !TARGET_TOC
5259 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
5260 && small_data_operand (x
, mode
));
5263 /* SPE offset addressing is limited to 5-bits worth of double words. */
5264 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5267 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
5269 unsigned HOST_WIDE_INT offset
, extra
;
5271 if (GET_CODE (x
) != PLUS
)
5273 if (GET_CODE (XEXP (x
, 0)) != REG
)
5275 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5277 if (!reg_offset_addressing_ok_p (mode
))
5278 return virtual_stack_registers_memory_p (x
);
5279 if (legitimate_constant_pool_address_p (x
, mode
, strict
))
5281 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5284 offset
= INTVAL (XEXP (x
, 1));
5292 /* SPE vector modes. */
5293 return SPE_CONST_OFFSET_OK (offset
);
5296 if (TARGET_E500_DOUBLE
)
5297 return SPE_CONST_OFFSET_OK (offset
);
5299 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5301 if (VECTOR_MEM_VSX_P (DFmode
))
5306 /* On e500v2, we may have:
5308 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5310 Which gets addressed with evldd instructions. */
5311 if (TARGET_E500_DOUBLE
)
5312 return SPE_CONST_OFFSET_OK (offset
);
5314 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
5316 else if (offset
& 3)
5321 if (TARGET_E500_DOUBLE
)
5322 return (SPE_CONST_OFFSET_OK (offset
)
5323 && SPE_CONST_OFFSET_OK (offset
+ 8));
5327 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
5329 else if (offset
& 3)
5340 return offset
< 0x10000 - extra
;
5344 legitimate_indexed_address_p (rtx x
, int strict
)
5348 if (GET_CODE (x
) != PLUS
)
5354 /* Recognize the rtl generated by reload which we know will later be
5355 replaced with proper base and index regs. */
5357 && reload_in_progress
5358 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
5362 return (REG_P (op0
) && REG_P (op1
)
5363 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
5364 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
5365 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
5366 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
5370 avoiding_indexed_address_p (enum machine_mode mode
)
5372 /* Avoid indexed addressing for modes that have non-indexed
5373 load/store instruction forms. */
5374 return (TARGET_AVOID_XFORM
&& VECTOR_MEM_NONE_P (mode
));
5378 legitimate_indirect_address_p (rtx x
, int strict
)
5380 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
5384 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
5386 if (!TARGET_MACHO
|| !flag_pic
5387 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
5391 if (GET_CODE (x
) != LO_SUM
)
5393 if (GET_CODE (XEXP (x
, 0)) != REG
)
5395 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
5399 return CONSTANT_P (x
);
5403 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
5405 if (GET_CODE (x
) != LO_SUM
)
5407 if (GET_CODE (XEXP (x
, 0)) != REG
)
5409 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5411 /* Restrict addressing for DI because of our SUBREG hackery. */
5412 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5413 || mode
== DDmode
|| mode
== TDmode
5418 if (TARGET_ELF
|| TARGET_MACHO
)
5420 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
5424 if (GET_MODE_NUNITS (mode
) != 1)
5426 if (GET_MODE_BITSIZE (mode
) > 64
5427 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
5428 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
5429 && (mode
== DFmode
|| mode
== DDmode
))))
5432 return CONSTANT_P (x
);
5439 /* Try machine-dependent ways of modifying an illegitimate address
5440 to be legitimate. If we find one, return the new, valid address.
5441 This is used from only one place: `memory_address' in explow.c.
5443 OLDX is the address as it was before break_out_memory_refs was
5444 called. In some cases it is useful to look at this to decide what
5447 It is always safe for this function to do nothing. It exists to
5448 recognize opportunities to optimize the output.
5450 On RS/6000, first check for the sum of a register with a constant
5451 integer that is out of range. If so, generate code to add the
5452 constant with the low-order 16 bits masked to the register and force
5453 this result into another register (this can be done with `cau').
5454 Then generate an address of REG+(CONST&0xffff), allowing for the
5455 possibility of bit 16 being a one.
5457 Then check for the sum of a register and something not constant, try to
5458 load the other things into a register and return the sum. */
5461 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
5462 enum machine_mode mode
)
5464 unsigned int extra
= 0;
5466 if (!reg_offset_addressing_ok_p (mode
))
5468 if (virtual_stack_registers_memory_p (x
))
5471 /* In theory we should not be seeing addresses of the form reg+0,
5472 but just in case it is generated, optimize it away. */
5473 if (GET_CODE (x
) == PLUS
&& XEXP (x
, 1) == const0_rtx
)
5474 return force_reg (Pmode
, XEXP (x
, 0));
5476 /* Make sure both operands are registers. */
5477 else if (GET_CODE (x
) == PLUS
)
5478 return gen_rtx_PLUS (Pmode
,
5479 force_reg (Pmode
, XEXP (x
, 0)),
5480 force_reg (Pmode
, XEXP (x
, 1)));
5482 return force_reg (Pmode
, x
);
5484 if (GET_CODE (x
) == SYMBOL_REF
)
5486 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
5488 return rs6000_legitimize_tls_address (x
, model
);
5498 if (!TARGET_POWERPC64
)
5506 extra
= TARGET_POWERPC64
? 8 : 12;
5512 if (GET_CODE (x
) == PLUS
5513 && GET_CODE (XEXP (x
, 0)) == REG
5514 && GET_CODE (XEXP (x
, 1)) == CONST_INT
5515 && ((unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000)
5517 && !((TARGET_POWERPC64
5518 && (mode
== DImode
|| mode
== TImode
)
5519 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
5520 || SPE_VECTOR_MODE (mode
)
5521 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5522 || mode
== DImode
|| mode
== DDmode
5523 || mode
== TDmode
))))
5525 HOST_WIDE_INT high_int
, low_int
;
5527 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5528 if (low_int
>= 0x8000 - extra
)
5530 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
5531 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
5532 GEN_INT (high_int
)), 0);
5533 return plus_constant (sum
, low_int
);
5535 else if (GET_CODE (x
) == PLUS
5536 && GET_CODE (XEXP (x
, 0)) == REG
5537 && GET_CODE (XEXP (x
, 1)) != CONST_INT
5538 && GET_MODE_NUNITS (mode
) == 1
5539 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5541 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
5542 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
5543 && (TARGET_POWERPC64
|| mode
!= DImode
)
5544 && !avoiding_indexed_address_p (mode
)
5549 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
5550 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
5552 else if (SPE_VECTOR_MODE (mode
)
5553 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5554 || mode
== DDmode
|| mode
== TDmode
5555 || mode
== DImode
)))
5559 /* We accept [reg + reg] and [reg + OFFSET]. */
5561 if (GET_CODE (x
) == PLUS
)
5563 rtx op1
= XEXP (x
, 0);
5564 rtx op2
= XEXP (x
, 1);
5567 op1
= force_reg (Pmode
, op1
);
5569 if (GET_CODE (op2
) != REG
5570 && (GET_CODE (op2
) != CONST_INT
5571 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
5572 || (GET_MODE_SIZE (mode
) > 8
5573 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
5574 op2
= force_reg (Pmode
, op2
);
5576 /* We can't always do [reg + reg] for these, because [reg +
5577 reg + offset] is not a legitimate addressing mode. */
5578 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
5580 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
5581 return force_reg (Pmode
, y
);
5586 return force_reg (Pmode
, x
);
5592 && GET_CODE (x
) != CONST_INT
5593 && GET_CODE (x
) != CONST_DOUBLE
5595 && GET_MODE_NUNITS (mode
) == 1
5596 && (GET_MODE_BITSIZE (mode
) <= 32
5597 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5598 && (mode
== DFmode
|| mode
== DDmode
))))
5600 rtx reg
= gen_reg_rtx (Pmode
);
5601 emit_insn (gen_elf_high (reg
, x
));
5602 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5604 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
5607 && ! MACHO_DYNAMIC_NO_PIC_P
5609 && GET_CODE (x
) != CONST_INT
5610 && GET_CODE (x
) != CONST_DOUBLE
5612 && GET_MODE_NUNITS (mode
) == 1
5613 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5614 || (mode
!= DFmode
&& mode
!= DDmode
))
5618 rtx reg
= gen_reg_rtx (Pmode
);
5619 emit_insn (gen_macho_high (reg
, x
));
5620 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5623 && GET_CODE (x
) == SYMBOL_REF
5624 && constant_pool_expr_p (x
)
5625 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
5627 rtx reg
= TARGET_CMODEL
!= CMODEL_SMALL
? gen_reg_rtx (Pmode
) : NULL_RTX
;
5628 return create_TOC_reference (x
, reg
);
5634 /* Debug version of rs6000_legitimize_address. */
5636 rs6000_debug_legitimize_address (rtx x
, rtx oldx
, enum machine_mode mode
)
5642 ret
= rs6000_legitimize_address (x
, oldx
, mode
);
5643 insns
= get_insns ();
5649 "\nrs6000_legitimize_address: mode %s, old code %s, "
5650 "new code %s, modified\n",
5651 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)),
5652 GET_RTX_NAME (GET_CODE (ret
)));
5654 fprintf (stderr
, "Original address:\n");
5657 fprintf (stderr
, "oldx:\n");
5660 fprintf (stderr
, "New address:\n");
5665 fprintf (stderr
, "Insns added:\n");
5666 debug_rtx_list (insns
, 20);
5672 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5673 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)));
5684 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5685 We need to emit DTP-relative relocations. */
5688 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
5693 fputs ("\t.long\t", file
);
5696 fputs (DOUBLE_INT_ASM_OP
, file
);
5701 output_addr_const (file
, x
);
5702 fputs ("@dtprel+0x8000", file
);
5705 /* In the name of slightly smaller debug output, and to cater to
5706 general assembler lossage, recognize various UNSPEC sequences
5707 and turn them back into a direct symbol reference. */
5710 rs6000_delegitimize_address (rtx orig_x
)
5714 orig_x
= delegitimize_mem_from_attrs (orig_x
);
5719 if (GET_CODE (x
) == (TARGET_CMODEL
!= CMODEL_SMALL
? LO_SUM
: PLUS
)
5720 && GET_CODE (XEXP (x
, 1)) == CONST
)
5722 rtx offset
= NULL_RTX
;
5724 y
= XEXP (XEXP (x
, 1), 0);
5725 if (GET_CODE (y
) == PLUS
5726 && GET_MODE (y
) == Pmode
5727 && CONST_INT_P (XEXP (y
, 1)))
5729 offset
= XEXP (y
, 1);
5732 if (GET_CODE (y
) == UNSPEC
5733 && XINT (y
, 1) == UNSPEC_TOCREL
5734 && ((GET_CODE (XEXP (x
, 0)) == REG
5735 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
5736 || TARGET_MINIMAL_TOC
5737 || TARGET_CMODEL
!= CMODEL_SMALL
))
5738 || (TARGET_CMODEL
!= CMODEL_SMALL
5739 && GET_CODE (XEXP (x
, 0)) == CONST
5740 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == PLUS
5741 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == REG
5742 && REGNO (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == TOC_REGISTER
5743 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 1)) == HIGH
5744 && rtx_equal_p (XEXP (x
, 1),
5745 XEXP (XEXP (XEXP (XEXP (x
, 0), 0), 1), 0)))))
5747 y
= XVECEXP (y
, 0, 0);
5748 if (offset
!= NULL_RTX
)
5749 y
= gen_rtx_PLUS (Pmode
, y
, offset
);
5750 if (!MEM_P (orig_x
))
5753 return replace_equiv_address_nv (orig_x
, y
);
5758 && GET_CODE (orig_x
) == LO_SUM
5759 && GET_CODE (XEXP (orig_x
, 1)) == CONST
)
5761 y
= XEXP (XEXP (orig_x
, 1), 0);
5762 if (GET_CODE (y
) == UNSPEC
5763 && XINT (y
, 1) == UNSPEC_MACHOPIC_OFFSET
)
5764 return XVECEXP (y
, 0, 0);
5770 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5772 static GTY(()) rtx rs6000_tls_symbol
;
5774 rs6000_tls_get_addr (void)
5776 if (!rs6000_tls_symbol
)
5777 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
5779 return rs6000_tls_symbol
;
5782 /* Construct the SYMBOL_REF for TLS GOT references. */
5784 static GTY(()) rtx rs6000_got_symbol
;
5786 rs6000_got_sym (void)
5788 if (!rs6000_got_symbol
)
5790 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
5791 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
5792 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
5795 return rs6000_got_symbol
;
5798 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5799 this (thread-local) address. */
5802 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
5806 dest
= gen_reg_rtx (Pmode
);
5807 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
5813 tlsreg
= gen_rtx_REG (Pmode
, 13);
5814 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
5818 tlsreg
= gen_rtx_REG (Pmode
, 2);
5819 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
5823 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
5827 tmp
= gen_reg_rtx (Pmode
);
5830 tlsreg
= gen_rtx_REG (Pmode
, 13);
5831 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
5835 tlsreg
= gen_rtx_REG (Pmode
, 2);
5836 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
5840 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
5842 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
5847 rtx r3
, got
, tga
, tmp1
, tmp2
, call_insn
;
5849 /* We currently use relocations like @got@tlsgd for tls, which
5850 means the linker will handle allocation of tls entries, placing
5851 them in the .got section. So use a pointer to the .got section,
5852 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5853 or to secondary GOT sections used by 32-bit -fPIC. */
5855 got
= gen_rtx_REG (Pmode
, 2);
5859 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
5862 rtx gsym
= rs6000_got_sym ();
5863 got
= gen_reg_rtx (Pmode
);
5865 rs6000_emit_move (got
, gsym
, Pmode
);
5870 tmp1
= gen_reg_rtx (Pmode
);
5871 tmp2
= gen_reg_rtx (Pmode
);
5872 mem
= gen_const_mem (Pmode
, tmp1
);
5873 lab
= gen_label_rtx ();
5874 emit_insn (gen_load_toc_v4_PIC_1b (gsym
, lab
));
5875 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
5876 if (TARGET_LINK_STACK
)
5877 emit_insn (gen_addsi3 (tmp1
, tmp1
, GEN_INT (4)));
5878 emit_move_insn (tmp2
, mem
);
5879 last
= emit_insn (gen_addsi3 (got
, tmp1
, tmp2
));
5880 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
5885 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
5887 tga
= rs6000_tls_get_addr ();
5888 emit_library_call_value (tga
, dest
, LCT_CONST
, Pmode
,
5889 1, const0_rtx
, Pmode
);
5891 r3
= gen_rtx_REG (Pmode
, 3);
5892 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5893 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
5894 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
5895 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
5896 else if (DEFAULT_ABI
== ABI_V4
)
5897 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
5900 call_insn
= last_call_insn ();
5901 PATTERN (call_insn
) = insn
;
5902 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
5903 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
5904 pic_offset_table_rtx
);
5906 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
5908 tga
= rs6000_tls_get_addr ();
5909 tmp1
= gen_reg_rtx (Pmode
);
5910 emit_library_call_value (tga
, tmp1
, LCT_CONST
, Pmode
,
5911 1, const0_rtx
, Pmode
);
5913 r3
= gen_rtx_REG (Pmode
, 3);
5914 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5915 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
5916 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
5917 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
5918 else if (DEFAULT_ABI
== ABI_V4
)
5919 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
5922 call_insn
= last_call_insn ();
5923 PATTERN (call_insn
) = insn
;
5924 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
5925 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
5926 pic_offset_table_rtx
);
5928 if (rs6000_tls_size
== 16)
5931 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
5933 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
5935 else if (rs6000_tls_size
== 32)
5937 tmp2
= gen_reg_rtx (Pmode
);
5939 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
5941 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
5944 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
5946 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
5950 tmp2
= gen_reg_rtx (Pmode
);
5952 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
5954 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
5956 insn
= gen_rtx_SET (Pmode
, dest
,
5957 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
5963 /* IE, or 64-bit offset LE. */
5964 tmp2
= gen_reg_rtx (Pmode
);
5966 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
5968 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
5971 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
5973 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
5981 /* Return 1 if X contains a thread-local symbol. */
5984 rs6000_tls_referenced_p (rtx x
)
5986 if (! TARGET_HAVE_TLS
)
5989 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
5992 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
5995 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
5997 if (GET_CODE (x
) == CONST
5998 && GET_CODE (XEXP (x
, 0)) == PLUS
5999 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
)
6002 return rs6000_tls_referenced_p (x
);
6005 /* Return 1 if *X is a thread-local symbol. This is the same as
6006 rs6000_tls_symbol_ref except for the type of the unused argument. */
6009 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
6011 return RS6000_SYMBOL_REF_TLS_P (*x
);
6014 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6015 replace the input X, or the original X if no replacement is called for.
6016 The output parameter *WIN is 1 if the calling macro should goto WIN,
6019 For RS/6000, we wish to handle large displacements off a base
6020 register by splitting the addend across an addiu/addis and the mem insn.
6021 This cuts number of extra insns needed from 3 to 1.
6023 On Darwin, we use this to generate code for floating point constants.
6024 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6025 The Darwin code is inside #if TARGET_MACHO because only then are the
6026 machopic_* functions defined. */
6028 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6029 int opnum
, int type
,
6030 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
6032 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6034 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6035 DFmode/DImode MEM. */
6038 && ((mode
== DFmode
&& recog_data
.operand_mode
[0] == V2DFmode
)
6039 || (mode
== DImode
&& recog_data
.operand_mode
[0] == V2DImode
)))
6040 reg_offset_p
= false;
6042 /* We must recognize output that we have already generated ourselves. */
6043 if (GET_CODE (x
) == PLUS
6044 && GET_CODE (XEXP (x
, 0)) == PLUS
6045 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6046 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6047 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6049 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6050 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6051 opnum
, (enum reload_type
)type
);
6056 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6057 if (GET_CODE (x
) == LO_SUM
6058 && GET_CODE (XEXP (x
, 0)) == HIGH
)
6060 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6061 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6062 opnum
, (enum reload_type
)type
);
6068 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
6069 && GET_CODE (x
) == LO_SUM
6070 && GET_CODE (XEXP (x
, 0)) == PLUS
6071 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
6072 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6073 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
6074 && machopic_operand_p (XEXP (x
, 1)))
6076 /* Result of previous invocation of this function on Darwin
6077 floating point constant. */
6078 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6079 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6080 opnum
, (enum reload_type
)type
);
6086 if (TARGET_CMODEL
!= CMODEL_SMALL
6087 && GET_CODE (x
) == LO_SUM
6088 && GET_CODE (XEXP (x
, 0)) == PLUS
6089 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6090 && REGNO (XEXP (XEXP (x
, 0), 0)) == TOC_REGISTER
6091 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST
6092 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == HIGH
6093 && GET_CODE (XEXP (x
, 1)) == CONST
6094 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == UNSPEC
6095 && XINT (XEXP (XEXP (x
, 1), 0), 1) == UNSPEC_TOCREL
6096 && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x
, 0), 1), 0), 0), XEXP (x
, 1)))
6098 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6099 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6100 opnum
, (enum reload_type
) type
);
6105 /* Force ld/std non-word aligned offset into base register by wrapping
6107 if (GET_CODE (x
) == PLUS
6108 && GET_CODE (XEXP (x
, 0)) == REG
6109 && REGNO (XEXP (x
, 0)) < 32
6110 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6111 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6113 && (INTVAL (XEXP (x
, 1)) & 3) != 0
6114 && VECTOR_MEM_NONE_P (mode
)
6115 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
6116 && TARGET_POWERPC64
)
6118 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
6119 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6120 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6121 opnum
, (enum reload_type
) type
);
6126 if (GET_CODE (x
) == PLUS
6127 && GET_CODE (XEXP (x
, 0)) == REG
6128 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
6129 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6130 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6132 && !SPE_VECTOR_MODE (mode
)
6133 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6134 || mode
== DDmode
|| mode
== TDmode
6136 && VECTOR_MEM_NONE_P (mode
))
6138 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
6139 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
6141 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6143 /* Check for 32-bit overflow. */
6144 if (high
+ low
!= val
)
6150 /* Reload the high part into a base reg; leave the low part
6151 in the mem directly. */
6153 x
= gen_rtx_PLUS (GET_MODE (x
),
6154 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
6158 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6159 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6160 opnum
, (enum reload_type
)type
);
6165 if (GET_CODE (x
) == SYMBOL_REF
6167 && VECTOR_MEM_NONE_P (mode
)
6168 && !SPE_VECTOR_MODE (mode
)
6170 && DEFAULT_ABI
== ABI_DARWIN
6171 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
6172 && machopic_symbol_defined_p (x
)
6174 && DEFAULT_ABI
== ABI_V4
6177 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6178 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6182 && (mode
!= DImode
|| TARGET_POWERPC64
)
6183 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
6184 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
6189 rtx offset
= machopic_gen_offset (x
);
6190 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6191 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
6192 gen_rtx_HIGH (Pmode
, offset
)), offset
);
6196 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6197 gen_rtx_HIGH (Pmode
, x
), x
);
6199 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6200 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6201 opnum
, (enum reload_type
)type
);
6206 /* Reload an offset address wrapped by an AND that represents the
6207 masking of the lower bits. Strip the outer AND and let reload
6208 convert the offset address into an indirect address. For VSX,
6209 force reload to create the address with an AND in a separate
6210 register, because we can't guarantee an altivec register will
6212 if (VECTOR_MEM_ALTIVEC_P (mode
)
6213 && GET_CODE (x
) == AND
6214 && GET_CODE (XEXP (x
, 0)) == PLUS
6215 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6216 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6217 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6218 && INTVAL (XEXP (x
, 1)) == -16)
6227 && GET_CODE (x
) == SYMBOL_REF
6228 && constant_pool_expr_p (x
)
6229 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
6231 x
= create_TOC_reference (x
, NULL_RTX
);
6232 if (TARGET_CMODEL
!= CMODEL_SMALL
)
6233 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6234 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6235 opnum
, (enum reload_type
) type
);
6243 /* Debug version of rs6000_legitimize_reload_address. */
6245 rs6000_debug_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6246 int opnum
, int type
,
6247 int ind_levels
, int *win
)
6249 rtx ret
= rs6000_legitimize_reload_address (x
, mode
, opnum
, type
,
6252 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6253 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6254 GET_MODE_NAME (mode
), opnum
, type
, ind_levels
, *win
);
6258 fprintf (stderr
, "Same address returned\n");
6260 fprintf (stderr
, "NULL returned\n");
6263 fprintf (stderr
, "New address:\n");
6270 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6271 that is a valid memory address for an instruction.
6272 The MODE argument is the machine mode for the MEM expression
6273 that wants to use this address.
6275 On the RS/6000, there are four valid address: a SYMBOL_REF that
6276 refers to a constant pool entry of an address (or the sum of it
6277 plus a constant), a short (16-bit signed) constant plus a register,
6278 the sum of two registers, or a register indirect, possibly with an
6279 auto-increment. For DFmode, DDmode and DImode with a constant plus
6280 register, we must ensure that both words are addressable or PowerPC64
6281 with offset word aligned.
6283 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6284 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6285 because adjacent memory cells are accessed by adding word-sized offsets
6286 during assembly output. */
6288 rs6000_legitimate_address_p (enum machine_mode mode
, rtx x
, bool reg_ok_strict
)
6290 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6292 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6293 if (VECTOR_MEM_ALTIVEC_P (mode
)
6294 && GET_CODE (x
) == AND
6295 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6296 && INTVAL (XEXP (x
, 1)) == -16)
6299 if (RS6000_SYMBOL_REF_TLS_P (x
))
6301 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
6303 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
6304 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6305 && !SPE_VECTOR_MODE (mode
)
6308 /* Restrict addressing for DI because of our SUBREG hackery. */
6309 && !(TARGET_E500_DOUBLE
6310 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6312 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
6314 if (virtual_stack_registers_memory_p (x
))
6316 if (reg_offset_p
&& legitimate_small_data_p (mode
, x
))
6319 && legitimate_constant_pool_address_p (x
, mode
, reg_ok_strict
))
6321 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6324 && GET_CODE (x
) == PLUS
6325 && GET_CODE (XEXP (x
, 0)) == REG
6326 && (XEXP (x
, 0) == virtual_stack_vars_rtx
6327 || XEXP (x
, 0) == arg_pointer_rtx
)
6328 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6330 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
6335 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6337 || (mode
!= DFmode
&& mode
!= DDmode
)
6338 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
6339 && (TARGET_POWERPC64
|| mode
!= DImode
)
6340 && !avoiding_indexed_address_p (mode
)
6341 && legitimate_indexed_address_p (x
, reg_ok_strict
))
6343 if (GET_CODE (x
) == PRE_MODIFY
6347 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6349 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
6350 && (TARGET_POWERPC64
|| mode
!= DImode
)
6351 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6352 && !SPE_VECTOR_MODE (mode
)
6353 /* Restrict addressing for DI because of our SUBREG hackery. */
6354 && !(TARGET_E500_DOUBLE
6355 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6357 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
6358 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
6359 || (!avoiding_indexed_address_p (mode
)
6360 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
6361 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
6363 if (reg_offset_p
&& legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
6368 /* Debug version of rs6000_legitimate_address_p. */
6370 rs6000_debug_legitimate_address_p (enum machine_mode mode
, rtx x
,
6373 bool ret
= rs6000_legitimate_address_p (mode
, x
, reg_ok_strict
);
6375 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6376 "strict = %d, code = %s\n",
6377 ret
? "true" : "false",
6378 GET_MODE_NAME (mode
),
6380 GET_RTX_NAME (GET_CODE (x
)));
6386 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6389 rs6000_mode_dependent_address_p (const_rtx addr
)
6391 return rs6000_mode_dependent_address_ptr (addr
);
6394 /* Go to LABEL if ADDR (a legitimate address expression)
6395 has an effect that depends on the machine mode it is used for.
6397 On the RS/6000 this is true of all integral offsets (since AltiVec
6398 and VSX modes don't allow them) or is a pre-increment or decrement.
6400 ??? Except that due to conceptual problems in offsettable_address_p
6401 we can't really report the problems of integral offsets. So leave
6402 this assuming that the adjustable offset must be valid for the
6403 sub-words of a TFmode operand, which is what we had before. */
6406 rs6000_mode_dependent_address (const_rtx addr
)
6408 switch (GET_CODE (addr
))
6411 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6412 is considered a legitimate address before reload, so there
6413 are no offset restrictions in that case. Note that this
6414 condition is safe in strict mode because any address involving
6415 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6416 been rejected as illegitimate. */
6417 if (XEXP (addr
, 0) != virtual_stack_vars_rtx
6418 && XEXP (addr
, 0) != arg_pointer_rtx
6419 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
6421 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
6422 return val
+ 12 + 0x8000 >= 0x10000;
6427 /* Anything in the constant pool is sufficiently aligned that
6428 all bytes have the same high part address. */
6429 return !legitimate_constant_pool_address_p (addr
, QImode
, false);
6431 /* Auto-increment cases are now treated generically in recog.c. */
6433 return TARGET_UPDATE
;
6435 /* AND is only allowed in Altivec loads. */
6446 /* Debug version of rs6000_mode_dependent_address. */
6448 rs6000_debug_mode_dependent_address (const_rtx addr
)
6450 bool ret
= rs6000_mode_dependent_address (addr
);
6452 fprintf (stderr
, "\nrs6000_mode_dependent_address: ret = %s\n",
6453 ret
? "true" : "false");
6459 /* Implement FIND_BASE_TERM. */
6462 rs6000_find_base_term (rtx op
)
6466 split_const (op
, &base
, &offset
);
6467 if (GET_CODE (base
) == UNSPEC
)
6468 switch (XINT (base
, 1))
6471 case UNSPEC_MACHOPIC_OFFSET
:
6472 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6473 for aliasing purposes. */
6474 return XVECEXP (base
, 0, 0);
6480 /* More elaborate version of recog's offsettable_memref_p predicate
6481 that works around the ??? note of rs6000_mode_dependent_address.
6482 In particular it accepts
6484 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6486 in 32-bit mode, that the recog predicate rejects. */
6489 rs6000_offsettable_memref_p (rtx op
)
6494 /* First mimic offsettable_memref_p. */
6495 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
6498 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6499 the latter predicate knows nothing about the mode of the memory
6500 reference and, therefore, assumes that it is the largest supported
6501 mode (TFmode). As a consequence, legitimate offsettable memory
6502 references are rejected. rs6000_legitimate_offset_address_p contains
6503 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6504 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
6507 /* Change register usage conditional on target flags. */
6509 rs6000_conditional_register_usage (void)
6513 if (TARGET_DEBUG_TARGET
)
6514 fprintf (stderr
, "rs6000_conditional_register_usage called\n");
6516 /* Set MQ register fixed (already call_used) if not POWER
6517 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6522 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6524 fixed_regs
[13] = call_used_regs
[13]
6525 = call_really_used_regs
[13] = 1;
6527 /* Conditionally disable FPRs. */
6528 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
6529 for (i
= 32; i
< 64; i
++)
6530 fixed_regs
[i
] = call_used_regs
[i
]
6531 = call_really_used_regs
[i
] = 1;
6533 /* The TOC register is not killed across calls in a way that is
6534 visible to the compiler. */
6535 if (DEFAULT_ABI
== ABI_AIX
)
6536 call_really_used_regs
[2] = 0;
6538 if (DEFAULT_ABI
== ABI_V4
6539 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
6541 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6543 if (DEFAULT_ABI
== ABI_V4
6544 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
6546 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6547 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6548 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6550 if (DEFAULT_ABI
== ABI_DARWIN
6551 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
6552 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6553 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6554 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6556 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
6557 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6558 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6562 global_regs
[SPEFSCR_REGNO
] = 1;
6563 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6564 registers in prologues and epilogues. We no longer use r14
6565 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6566 pool for link-compatibility with older versions of GCC. Once
6567 "old" code has died out, we can return r14 to the allocation
6570 = call_used_regs
[14]
6571 = call_really_used_regs
[14] = 1;
6574 if (!TARGET_ALTIVEC
&& !TARGET_VSX
)
6576 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
6577 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6578 call_really_used_regs
[VRSAVE_REGNO
] = 1;
6581 if (TARGET_ALTIVEC
|| TARGET_VSX
)
6582 global_regs
[VSCR_REGNO
] = 1;
6584 if (TARGET_ALTIVEC_ABI
)
6586 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
6587 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6589 /* AIX reserves VR20:31 in non-extended ABI mode. */
6591 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
6592 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6596 /* Try to output insns to set TARGET equal to the constant C if it can
6597 be done in less than N insns. Do all computations in MODE.
6598 Returns the place where the output has been placed if it can be
6599 done and the insns have been emitted. If it would take more than N
6600 insns, zero is returned and no insns and emitted. */
6603 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
6604 rtx source
, int n ATTRIBUTE_UNUSED
)
6606 rtx result
, insn
, set
;
6607 HOST_WIDE_INT c0
, c1
;
6614 dest
= gen_reg_rtx (mode
);
6615 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
6619 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
6621 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
6622 GEN_INT (INTVAL (source
)
6623 & (~ (HOST_WIDE_INT
) 0xffff))));
6624 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
6625 gen_rtx_IOR (SImode
, copy_rtx (result
),
6626 GEN_INT (INTVAL (source
) & 0xffff))));
6631 switch (GET_CODE (source
))
6634 c0
= INTVAL (source
);
6639 #if HOST_BITS_PER_WIDE_INT >= 64
6640 c0
= CONST_DOUBLE_LOW (source
);
6643 c0
= CONST_DOUBLE_LOW (source
);
6644 c1
= CONST_DOUBLE_HIGH (source
);
6652 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
6659 insn
= get_last_insn ();
6660 set
= single_set (insn
);
6661 if (! CONSTANT_P (SET_SRC (set
)))
6662 set_unique_reg_note (insn
, REG_EQUAL
, source
);
6667 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6668 fall back to a straight forward decomposition. We do this to avoid
6669 exponential run times encountered when looking for longer sequences
6670 with rs6000_emit_set_const. */
6672 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
6674 if (!TARGET_POWERPC64
)
6676 rtx operand1
, operand2
;
6678 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
6680 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
6682 emit_move_insn (operand1
, GEN_INT (c1
));
6683 emit_move_insn (operand2
, GEN_INT (c2
));
6687 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
6690 ud2
= (c1
& 0xffff0000) >> 16;
6691 #if HOST_BITS_PER_WIDE_INT >= 64
6695 ud4
= (c2
& 0xffff0000) >> 16;
6697 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
6698 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
6701 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
6703 emit_move_insn (dest
, GEN_INT (ud1
));
6706 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
6707 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
6710 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
6713 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
6715 emit_move_insn (copy_rtx (dest
),
6716 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6719 else if (ud3
== 0 && ud4
== 0)
6721 gcc_assert (ud2
& 0x8000);
6722 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
6725 emit_move_insn (copy_rtx (dest
),
6726 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6728 emit_move_insn (copy_rtx (dest
),
6729 gen_rtx_ZERO_EXTEND (DImode
,
6730 gen_lowpart (SImode
,
6733 else if ((ud4
== 0xffff && (ud3
& 0x8000))
6734 || (ud4
== 0 && ! (ud3
& 0x8000)))
6737 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
6740 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
6743 emit_move_insn (copy_rtx (dest
),
6744 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6746 emit_move_insn (copy_rtx (dest
),
6747 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
6750 emit_move_insn (copy_rtx (dest
),
6751 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6757 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
6760 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
6763 emit_move_insn (copy_rtx (dest
),
6764 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6767 emit_move_insn (copy_rtx (dest
),
6768 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
6771 emit_move_insn (copy_rtx (dest
),
6772 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6773 GEN_INT (ud2
<< 16)));
6775 emit_move_insn (copy_rtx (dest
),
6776 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
6782 /* Helper for the following. Get rid of [r+r] memory refs
6783 in cases where it won't work (TImode, TFmode, TDmode). */
6786 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
6788 if (reload_in_progress
)
6791 if (GET_CODE (operands
[0]) == MEM
6792 && GET_CODE (XEXP (operands
[0], 0)) != REG
6793 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0),
6794 GET_MODE (operands
[0]), false))
6796 = replace_equiv_address (operands
[0],
6797 copy_addr_to_reg (XEXP (operands
[0], 0)));
6799 if (GET_CODE (operands
[1]) == MEM
6800 && GET_CODE (XEXP (operands
[1], 0)) != REG
6801 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0),
6802 GET_MODE (operands
[1]), false))
6804 = replace_equiv_address (operands
[1],
6805 copy_addr_to_reg (XEXP (operands
[1], 0)));
6808 /* Emit a move from SOURCE to DEST in mode MODE. */
6810 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
6814 operands
[1] = source
;
6816 if (TARGET_DEBUG_ADDR
)
6819 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6820 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6821 GET_MODE_NAME (mode
),
6824 can_create_pseudo_p ());
6826 fprintf (stderr
, "source:\n");
6830 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6831 if (GET_CODE (operands
[1]) == CONST_DOUBLE
6832 && ! FLOAT_MODE_P (mode
)
6833 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
6835 /* FIXME. This should never happen. */
6836 /* Since it seems that it does, do the safe thing and convert
6838 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
6840 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
6841 || FLOAT_MODE_P (mode
)
6842 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
6843 || CONST_DOUBLE_LOW (operands
[1]) < 0)
6844 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
6845 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
6847 /* Check if GCC is setting up a block move that will end up using FP
6848 registers as temporaries. We must make sure this is acceptable. */
6849 if (GET_CODE (operands
[0]) == MEM
6850 && GET_CODE (operands
[1]) == MEM
6852 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
6853 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
6854 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
6855 ? 32 : MEM_ALIGN (operands
[0])))
6856 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
6858 : MEM_ALIGN (operands
[1]))))
6859 && ! MEM_VOLATILE_P (operands
[0])
6860 && ! MEM_VOLATILE_P (operands
[1]))
6862 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
6863 adjust_address (operands
[1], SImode
, 0));
6864 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
6865 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
6869 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
6870 && !gpc_reg_operand (operands
[1], mode
))
6871 operands
[1] = force_reg (mode
, operands
[1]);
6873 if (mode
== SFmode
&& ! TARGET_POWERPC
6874 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
6875 && GET_CODE (operands
[0]) == MEM
)
6879 if (reload_in_progress
|| reload_completed
)
6880 regnum
= true_regnum (operands
[1]);
6881 else if (GET_CODE (operands
[1]) == REG
)
6882 regnum
= REGNO (operands
[1]);
6886 /* If operands[1] is a register, on POWER it may have
6887 double-precision data in it, so truncate it to single
6889 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
6892 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
6893 : gen_reg_rtx (mode
));
6894 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
6895 operands
[1] = newreg
;
6899 /* Recognize the case where operand[1] is a reference to thread-local
6900 data and load its address to a register. */
6901 if (rs6000_tls_referenced_p (operands
[1]))
6903 enum tls_model model
;
6904 rtx tmp
= operands
[1];
6907 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
6909 addend
= XEXP (XEXP (tmp
, 0), 1);
6910 tmp
= XEXP (XEXP (tmp
, 0), 0);
6913 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
6914 model
= SYMBOL_REF_TLS_MODEL (tmp
);
6915 gcc_assert (model
!= 0);
6917 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
6920 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
6921 tmp
= force_operand (tmp
, operands
[0]);
6926 /* Handle the case where reload calls us with an invalid address. */
6927 if (reload_in_progress
&& mode
== Pmode
6928 && (! general_operand (operands
[1], mode
)
6929 || ! nonimmediate_operand (operands
[0], mode
)))
6932 /* 128-bit constant floating-point values on Darwin should really be
6933 loaded as two parts. */
6934 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
6935 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
6937 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6938 know how to get a DFmode SUBREG of a TFmode. */
6939 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
6940 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
6941 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
6943 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
6944 GET_MODE_SIZE (imode
)),
6945 simplify_gen_subreg (imode
, operands
[1], mode
,
6946 GET_MODE_SIZE (imode
)),
6951 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
6952 cfun
->machine
->sdmode_stack_slot
=
6953 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
6955 if (reload_in_progress
6957 && MEM_P (operands
[0])
6958 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
6959 && REG_P (operands
[1]))
6961 if (FP_REGNO_P (REGNO (operands
[1])))
6963 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
6964 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6965 emit_insn (gen_movsd_store (mem
, operands
[1]));
6967 else if (INT_REGNO_P (REGNO (operands
[1])))
6969 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
6970 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6971 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
6977 if (reload_in_progress
6979 && REG_P (operands
[0])
6980 && MEM_P (operands
[1])
6981 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
6983 if (FP_REGNO_P (REGNO (operands
[0])))
6985 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
6986 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6987 emit_insn (gen_movsd_load (operands
[0], mem
));
6989 else if (INT_REGNO_P (REGNO (operands
[0])))
6991 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
6992 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6993 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
7000 /* FIXME: In the long term, this switch statement should go away
7001 and be replaced by a sequence of tests based on things like
7007 if (CONSTANT_P (operands
[1])
7008 && GET_CODE (operands
[1]) != CONST_INT
)
7009 operands
[1] = force_const_mem (mode
, operands
[1]);
7014 rs6000_eliminate_indexed_memrefs (operands
);
7021 if (CONSTANT_P (operands
[1])
7022 && ! easy_fp_constant (operands
[1], mode
))
7023 operands
[1] = force_const_mem (mode
, operands
[1]);
7036 if (CONSTANT_P (operands
[1])
7037 && !easy_vector_constant (operands
[1], mode
))
7038 operands
[1] = force_const_mem (mode
, operands
[1]);
7043 /* Use default pattern for address of ELF small data */
7046 && DEFAULT_ABI
== ABI_V4
7047 && (GET_CODE (operands
[1]) == SYMBOL_REF
7048 || GET_CODE (operands
[1]) == CONST
)
7049 && small_data_operand (operands
[1], mode
))
7051 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7055 if (DEFAULT_ABI
== ABI_V4
7056 && mode
== Pmode
&& mode
== SImode
7057 && flag_pic
== 1 && got_operand (operands
[1], mode
))
7059 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
7063 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
7067 && CONSTANT_P (operands
[1])
7068 && GET_CODE (operands
[1]) != HIGH
7069 && GET_CODE (operands
[1]) != CONST_INT
)
7071 rtx target
= (!can_create_pseudo_p ()
7073 : gen_reg_rtx (mode
));
7075 /* If this is a function address on -mcall-aixdesc,
7076 convert it to the address of the descriptor. */
7077 if (DEFAULT_ABI
== ABI_AIX
7078 && GET_CODE (operands
[1]) == SYMBOL_REF
7079 && XSTR (operands
[1], 0)[0] == '.')
7081 const char *name
= XSTR (operands
[1], 0);
7083 while (*name
== '.')
7085 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
7086 CONSTANT_POOL_ADDRESS_P (new_ref
)
7087 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
7088 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
7089 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
7090 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
7091 operands
[1] = new_ref
;
7094 if (DEFAULT_ABI
== ABI_DARWIN
)
7097 if (MACHO_DYNAMIC_NO_PIC_P
)
7099 /* Take care of any required data indirection. */
7100 operands
[1] = rs6000_machopic_legitimize_pic_address (
7101 operands
[1], mode
, operands
[0]);
7102 if (operands
[0] != operands
[1])
7103 emit_insn (gen_rtx_SET (VOIDmode
,
7104 operands
[0], operands
[1]));
7108 emit_insn (gen_macho_high (target
, operands
[1]));
7109 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
7113 emit_insn (gen_elf_high (target
, operands
[1]));
7114 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
7118 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7119 and we have put it in the TOC, we just need to make a TOC-relative
7122 && GET_CODE (operands
[1]) == SYMBOL_REF
7123 && constant_pool_expr_p (operands
[1])
7124 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
7125 get_pool_mode (operands
[1])))
7126 || (TARGET_CMODEL
== CMODEL_MEDIUM
7127 && GET_CODE (operands
[1]) == SYMBOL_REF
7128 && !CONSTANT_POOL_ADDRESS_P (operands
[1])
7129 && SYMBOL_REF_LOCAL_P (operands
[1])))
7132 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7134 if (can_create_pseudo_p ())
7135 reg
= gen_reg_rtx (Pmode
);
7139 operands
[1] = create_TOC_reference (operands
[1], reg
);
7141 else if (mode
== Pmode
7142 && CONSTANT_P (operands
[1])
7143 && GET_CODE (operands
[1]) != HIGH
7144 && !(TARGET_CMODEL
!= CMODEL_SMALL
7145 && GET_CODE (operands
[1]) == CONST
7146 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
7147 && GET_CODE (XEXP (XEXP (operands
[1], 0), 1)) == HIGH
)
7148 && ((GET_CODE (operands
[1]) != CONST_INT
7149 && ! easy_fp_constant (operands
[1], mode
))
7150 || (GET_CODE (operands
[1]) == CONST_INT
7151 && (num_insns_constant (operands
[1], mode
)
7152 > (TARGET_CMODEL
!= CMODEL_SMALL
? 3 : 2)))
7153 || (GET_CODE (operands
[0]) == REG
7154 && FP_REGNO_P (REGNO (operands
[0]))))
7155 && ! legitimate_constant_pool_address_p (operands
[1], mode
,
7157 && ! toc_relative_expr_p (operands
[1])
7158 && (TARGET_CMODEL
== CMODEL_SMALL
7159 || can_create_pseudo_p ()
7160 || (REG_P (operands
[0])
7161 && INT_REG_OK_FOR_BASE_P (operands
[0], true))))
7165 /* Darwin uses a special PIC legitimizer. */
7166 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
7169 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
7171 if (operands
[0] != operands
[1])
7172 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7177 /* If we are to limit the number of things we put in the TOC and
7178 this is a symbol plus a constant we can add in one insn,
7179 just put the symbol in the TOC and add the constant. Don't do
7180 this if reload is in progress. */
7181 if (GET_CODE (operands
[1]) == CONST
7182 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
7183 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
7184 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
7185 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
7186 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
7187 && ! side_effects_p (operands
[0]))
7190 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
7191 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
7193 sym
= force_reg (mode
, sym
);
7194 emit_insn (gen_add3_insn (operands
[0], sym
, other
));
7198 operands
[1] = force_const_mem (mode
, operands
[1]);
7201 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
7202 && constant_pool_expr_p (XEXP (operands
[1], 0))
7203 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7204 get_pool_constant (XEXP (operands
[1], 0)),
7205 get_pool_mode (XEXP (operands
[1], 0))))
7209 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7211 if (can_create_pseudo_p ())
7212 reg
= gen_reg_rtx (Pmode
);
7216 tocref
= create_TOC_reference (XEXP (operands
[1], 0), reg
);
7217 operands
[1] = gen_const_mem (mode
, tocref
);
7218 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
7224 rs6000_eliminate_indexed_memrefs (operands
);
7228 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
7230 gen_rtx_SET (VOIDmode
,
7231 operands
[0], operands
[1]),
7232 gen_rtx_CLOBBER (VOIDmode
,
7233 gen_rtx_SCRATCH (SImode
)))));
7239 fatal_insn ("bad move", gen_rtx_SET (VOIDmode
, dest
, source
));
7242 /* Above, we may have called force_const_mem which may have returned
7243 an invalid address. If we can, fix this up; otherwise, reload will
7244 have to deal with it. */
7245 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
7246 operands
[1] = validize_mem (operands
[1]);
7249 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7252 /* Nonzero if we can use a floating-point register to pass this arg. */
7253 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7254 (SCALAR_FLOAT_MODE_P (MODE) \
7255 && (CUM)->fregno <= FP_ARG_MAX_REG \
7256 && TARGET_HARD_FLOAT && TARGET_FPRS)
7258 /* Nonzero if we can use an AltiVec register to pass this arg. */
7259 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7260 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
7261 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7262 && TARGET_ALTIVEC_ABI \
7265 /* Return a nonzero value to say to return the function value in
7266 memory, just as large structures are always returned. TYPE will be
7267 the data type of the value, and FNTYPE will be the type of the
7268 function doing the returning, or @code{NULL} for libcalls.
7270 The AIX ABI for the RS/6000 specifies that all structures are
7271 returned in memory. The Darwin ABI does the same.
7273 For the Darwin 64 Bit ABI, a function result can be returned in
7274 registers or in memory, depending on the size of the return data
7275 type. If it is returned in registers, the value occupies the same
7276 registers as it would if it were the first and only function
7277 argument. Otherwise, the function places its result in memory at
7278 the location pointed to by GPR3.
7280 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7281 but a draft put them in memory, and GCC used to implement the draft
7282 instead of the final standard. Therefore, aix_struct_return
7283 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7284 compatibility can change DRAFT_V4_STRUCT_RET to override the
7285 default, and -m switches get the final word. See
7286 rs6000_option_override_internal for more details.
7288 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7289 long double support is enabled. These values are returned in memory.
7291 int_size_in_bytes returns -1 for variable size objects, which go in
7292 memory always. The cast to unsigned makes -1 > 8. */
7295 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7297 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7299 && rs6000_darwin64_abi
7300 && TREE_CODE (type
) == RECORD_TYPE
7301 && int_size_in_bytes (type
) > 0)
7303 CUMULATIVE_ARGS valcum
;
7307 valcum
.fregno
= FP_ARG_MIN_REG
;
7308 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
7309 /* Do a trial code generation as if this were going to be passed
7310 as an argument; if any part goes in memory, we return NULL. */
7311 valret
= rs6000_darwin64_record_arg (&valcum
, type
, true, true);
7314 /* Otherwise fall through to more conventional ABI rules. */
7317 if (AGGREGATE_TYPE_P (type
)
7318 && (aix_struct_return
7319 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
7322 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7323 modes only exist for GCC vector types if -maltivec. */
7324 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
7325 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7328 /* Return synthetic vectors in memory. */
7329 if (TREE_CODE (type
) == VECTOR_TYPE
7330 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
7332 static bool warned_for_return_big_vectors
= false;
7333 if (!warned_for_return_big_vectors
)
7335 warning (0, "GCC vector returned by reference: "
7336 "non-standard ABI extension with no compatibility guarantee");
7337 warned_for_return_big_vectors
= true;
7342 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
7348 #ifdef HAVE_AS_GNU_ATTRIBUTE
7349 /* Return TRUE if a call to function FNDECL may be one that
7350 potentially affects the function calling ABI of the object file. */
7353 call_ABI_of_interest (tree fndecl
)
7355 if (cgraph_state
== CGRAPH_STATE_EXPANSION
)
7357 struct cgraph_node
*c_node
;
7359 /* Libcalls are always interesting. */
7360 if (fndecl
== NULL_TREE
)
7363 /* Any call to an external function is interesting. */
7364 if (DECL_EXTERNAL (fndecl
))
7367 /* Interesting functions that we are emitting in this object file. */
7368 c_node
= cgraph_get_node (fndecl
);
7369 c_node
= cgraph_function_or_thunk_node (c_node
, NULL
);
7370 return !cgraph_only_called_directly_p (c_node
);
7376 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7377 for a call to a function whose data type is FNTYPE.
7378 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7380 For incoming args we set the number of arguments in the prototype large
7381 so we never return a PARALLEL. */
7384 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
7385 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
7386 int libcall
, int n_named_args
,
7387 tree fndecl ATTRIBUTE_UNUSED
,
7388 enum machine_mode return_mode ATTRIBUTE_UNUSED
)
7390 static CUMULATIVE_ARGS zero_cumulative
;
7392 *cum
= zero_cumulative
;
7394 cum
->fregno
= FP_ARG_MIN_REG
;
7395 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
7396 cum
->prototype
= (fntype
&& prototype_p (fntype
));
7397 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
7398 ? CALL_LIBCALL
: CALL_NORMAL
);
7399 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
7400 cum
->stdarg
= stdarg_p (fntype
);
7402 cum
->nargs_prototype
= 0;
7403 if (incoming
|| cum
->prototype
)
7404 cum
->nargs_prototype
= n_named_args
;
7406 /* Check for a longcall attribute. */
7407 if ((!fntype
&& rs6000_default_long_calls
)
7409 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
7410 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
7411 cum
->call_cookie
|= CALL_LONG
;
7413 if (TARGET_DEBUG_ARG
)
7415 fprintf (stderr
, "\ninit_cumulative_args:");
7418 tree ret_type
= TREE_TYPE (fntype
);
7419 fprintf (stderr
, " ret code = %s,",
7420 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
7423 if (cum
->call_cookie
& CALL_LONG
)
7424 fprintf (stderr
, " longcall,");
7426 fprintf (stderr
, " proto = %d, nargs = %d\n",
7427 cum
->prototype
, cum
->nargs_prototype
);
7430 #ifdef HAVE_AS_GNU_ATTRIBUTE
7431 if (DEFAULT_ABI
== ABI_V4
)
7433 cum
->escapes
= call_ABI_of_interest (fndecl
);
7440 return_type
= TREE_TYPE (fntype
);
7441 return_mode
= TYPE_MODE (return_type
);
7444 return_type
= lang_hooks
.types
.type_for_mode (return_mode
, 0);
7446 if (return_type
!= NULL
)
7448 if (TREE_CODE (return_type
) == RECORD_TYPE
7449 && TYPE_TRANSPARENT_AGGR (return_type
))
7451 return_type
= TREE_TYPE (first_field (return_type
));
7452 return_mode
= TYPE_MODE (return_type
);
7454 if (AGGREGATE_TYPE_P (return_type
)
7455 && ((unsigned HOST_WIDE_INT
) int_size_in_bytes (return_type
)
7457 rs6000_returns_struct
= true;
7459 if (SCALAR_FLOAT_MODE_P (return_mode
))
7460 rs6000_passes_float
= true;
7461 else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode
)
7462 || SPE_VECTOR_MODE (return_mode
))
7463 rs6000_passes_vector
= true;
7470 && TARGET_ALTIVEC_ABI
7471 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
7473 error ("cannot return value in vector register because"
7474 " altivec instructions are disabled, use -maltivec"
7479 /* Return true if TYPE must be passed on the stack and not in registers. */
7482 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
7484 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
7485 return must_pass_in_stack_var_size (mode
, type
);
7487 return must_pass_in_stack_var_size_or_pad (mode
, type
);
7490 /* If defined, a C expression which determines whether, and in which
7491 direction, to pad out an argument with extra space. The value
7492 should be of type `enum direction': either `upward' to pad above
7493 the argument, `downward' to pad below, or `none' to inhibit
7496 For the AIX ABI structs are always stored left shifted in their
7500 function_arg_padding (enum machine_mode mode
, const_tree type
)
7502 #ifndef AGGREGATE_PADDING_FIXED
7503 #define AGGREGATE_PADDING_FIXED 0
7505 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7506 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7509 if (!AGGREGATE_PADDING_FIXED
)
7511 /* GCC used to pass structures of the same size as integer types as
7512 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7513 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7514 passed padded downward, except that -mstrict-align further
7515 muddied the water in that multi-component structures of 2 and 4
7516 bytes in size were passed padded upward.
7518 The following arranges for best compatibility with previous
7519 versions of gcc, but removes the -mstrict-align dependency. */
7520 if (BYTES_BIG_ENDIAN
)
7522 HOST_WIDE_INT size
= 0;
7524 if (mode
== BLKmode
)
7526 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
7527 size
= int_size_in_bytes (type
);
7530 size
= GET_MODE_SIZE (mode
);
7532 if (size
== 1 || size
== 2 || size
== 4)
7538 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
7540 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
7544 /* Fall back to the default. */
7545 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
7548 /* If defined, a C expression that gives the alignment boundary, in bits,
7549 of an argument with the specified mode and type. If it is not defined,
7550 PARM_BOUNDARY is used for all arguments.
7552 V.4 wants long longs and doubles to be double word aligned. Just
7553 testing the mode size is a boneheaded way to do this as it means
7554 that other types such as complex int are also double word aligned.
7555 However, we're stuck with this because changing the ABI might break
7556 existing library interfaces.
7558 Doubleword align SPE vectors.
7559 Quadword align Altivec/VSX vectors.
7560 Quadword align large synthetic vector types. */
7563 rs6000_function_arg_boundary (enum machine_mode mode
, const_tree type
)
7565 if (DEFAULT_ABI
== ABI_V4
7566 && (GET_MODE_SIZE (mode
) == 8
7567 || (TARGET_HARD_FLOAT
7569 && (mode
== TFmode
|| mode
== TDmode
))))
7571 else if (SPE_VECTOR_MODE (mode
)
7572 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7573 && int_size_in_bytes (type
) >= 8
7574 && int_size_in_bytes (type
) < 16))
7576 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode
)
7577 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7578 && int_size_in_bytes (type
) >= 16))
7580 else if (TARGET_MACHO
7581 && rs6000_darwin64_abi
7583 && type
&& TYPE_ALIGN (type
) > 64)
7586 return PARM_BOUNDARY
;
7589 /* For a function parm of MODE and TYPE, return the starting word in
7590 the parameter area. NWORDS of the parameter area are already used. */
7593 rs6000_parm_start (enum machine_mode mode
, const_tree type
,
7594 unsigned int nwords
)
7597 unsigned int parm_offset
;
7599 align
= rs6000_function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
7600 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
7601 return nwords
+ (-(parm_offset
+ nwords
) & align
);
7604 /* Compute the size (in words) of a function argument. */
7606 static unsigned long
7607 rs6000_arg_size (enum machine_mode mode
, const_tree type
)
7611 if (mode
!= BLKmode
)
7612 size
= GET_MODE_SIZE (mode
);
7614 size
= int_size_in_bytes (type
);
7617 return (size
+ 3) >> 2;
7619 return (size
+ 7) >> 3;
7622 /* Use this to flush pending int fields. */
7625 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
7626 HOST_WIDE_INT bitpos
, int final
)
7628 unsigned int startbit
, endbit
;
7629 int intregs
, intoffset
;
7630 enum machine_mode mode
;
7632 /* Handle the situations where a float is taking up the first half
7633 of the GPR, and the other half is empty (typically due to
7634 alignment restrictions). We can detect this by a 8-byte-aligned
7635 int field, or by seeing that this is the final flush for this
7636 argument. Count the word and continue on. */
7637 if (cum
->floats_in_gpr
== 1
7638 && (cum
->intoffset
% 64 == 0
7639 || (cum
->intoffset
== -1 && final
)))
7642 cum
->floats_in_gpr
= 0;
7645 if (cum
->intoffset
== -1)
7648 intoffset
= cum
->intoffset
;
7649 cum
->intoffset
= -1;
7650 cum
->floats_in_gpr
= 0;
7652 if (intoffset
% BITS_PER_WORD
!= 0)
7654 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
7656 if (mode
== BLKmode
)
7658 /* We couldn't find an appropriate mode, which happens,
7659 e.g., in packed structs when there are 3 bytes to load.
7660 Back intoffset back to the beginning of the word in this
7662 intoffset
= intoffset
& -BITS_PER_WORD
;
7666 startbit
= intoffset
& -BITS_PER_WORD
;
7667 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
7668 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
7669 cum
->words
+= intregs
;
7670 /* words should be unsigned. */
7671 if ((unsigned)cum
->words
< (endbit
/BITS_PER_WORD
))
7673 int pad
= (endbit
/BITS_PER_WORD
) - cum
->words
;
7678 /* The darwin64 ABI calls for us to recurse down through structs,
7679 looking for elements passed in registers. Unfortunately, we have
7680 to track int register count here also because of misalignments
7681 in powerpc alignment mode. */
7684 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
7686 HOST_WIDE_INT startbitpos
)
7690 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
7691 if (TREE_CODE (f
) == FIELD_DECL
)
7693 HOST_WIDE_INT bitpos
= startbitpos
;
7694 tree ftype
= TREE_TYPE (f
);
7695 enum machine_mode mode
;
7696 if (ftype
== error_mark_node
)
7698 mode
= TYPE_MODE (ftype
);
7700 if (DECL_SIZE (f
) != 0
7701 && host_integerp (bit_position (f
), 1))
7702 bitpos
+= int_bit_position (f
);
7704 /* ??? FIXME: else assume zero offset. */
7706 if (TREE_CODE (ftype
) == RECORD_TYPE
)
7707 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
7708 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
7710 unsigned n_fpregs
= (GET_MODE_SIZE (mode
) + 7) >> 3;
7711 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
7712 cum
->fregno
+= n_fpregs
;
7713 /* Single-precision floats present a special problem for
7714 us, because they are smaller than an 8-byte GPR, and so
7715 the structure-packing rules combined with the standard
7716 varargs behavior mean that we want to pack float/float
7717 and float/int combinations into a single register's
7718 space. This is complicated by the arg advance flushing,
7719 which works on arbitrarily large groups of int-type
7723 if (cum
->floats_in_gpr
== 1)
7725 /* Two floats in a word; count the word and reset
7728 cum
->floats_in_gpr
= 0;
7730 else if (bitpos
% 64 == 0)
7732 /* A float at the beginning of an 8-byte word;
7733 count it and put off adjusting cum->words until
7734 we see if a arg advance flush is going to do it
7736 cum
->floats_in_gpr
++;
7740 /* The float is at the end of a word, preceded
7741 by integer fields, so the arg advance flush
7742 just above has already set cum->words and
7743 everything is taken care of. */
7747 cum
->words
+= n_fpregs
;
7749 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
7751 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
7755 else if (cum
->intoffset
== -1)
7756 cum
->intoffset
= bitpos
;
7760 /* Check for an item that needs to be considered specially under the darwin 64
7761 bit ABI. These are record types where the mode is BLK or the structure is
7764 rs6000_darwin64_struct_check_p (enum machine_mode mode
, const_tree type
)
7766 return rs6000_darwin64_abi
7767 && ((mode
== BLKmode
7768 && TREE_CODE (type
) == RECORD_TYPE
7769 && int_size_in_bytes (type
) > 0)
7770 || (type
&& TREE_CODE (type
) == RECORD_TYPE
7771 && int_size_in_bytes (type
) == 8)) ? 1 : 0;
7774 /* Update the data in CUM to advance over an argument
7775 of mode MODE and data type TYPE.
7776 (TYPE is null for libcalls where that information may not be available.)
7778 Note that for args passed by reference, function_arg will be called
7779 with MODE and TYPE set to that of the pointer to the arg, not the arg
7783 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7784 const_tree type
, bool named
, int depth
)
7786 /* Only tick off an argument if we're not recursing. */
7788 cum
->nargs_prototype
--;
7790 #ifdef HAVE_AS_GNU_ATTRIBUTE
7791 if (DEFAULT_ABI
== ABI_V4
7794 if (SCALAR_FLOAT_MODE_P (mode
))
7795 rs6000_passes_float
= true;
7796 else if (named
&& ALTIVEC_OR_VSX_VECTOR_MODE (mode
))
7797 rs6000_passes_vector
= true;
7798 else if (SPE_VECTOR_MODE (mode
)
7800 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
7801 rs6000_passes_vector
= true;
7805 if (TARGET_ALTIVEC_ABI
7806 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode
)
7807 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7808 && int_size_in_bytes (type
) == 16)))
7812 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
7815 if (!TARGET_ALTIVEC
)
7816 error ("cannot pass argument in vector register because"
7817 " altivec instructions are disabled, use -maltivec"
7820 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7821 even if it is going to be passed in a vector register.
7822 Darwin does the same for variable-argument functions. */
7823 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
7824 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
7834 /* Vector parameters must be 16-byte aligned. This places
7835 them at 2 mod 4 in terms of words in 32-bit mode, since
7836 the parameter save area starts at offset 24 from the
7837 stack. In 64-bit mode, they just have to start on an
7838 even word, since the parameter save area is 16-byte
7839 aligned. Space for GPRs is reserved even if the argument
7840 will be passed in memory. */
7842 align
= (2 - cum
->words
) & 3;
7844 align
= cum
->words
& 1;
7845 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
7847 if (TARGET_DEBUG_ARG
)
7849 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
7851 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
7852 cum
->nargs_prototype
, cum
->prototype
,
7853 GET_MODE_NAME (mode
));
7857 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
7859 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
7862 else if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
7864 int size
= int_size_in_bytes (type
);
7865 /* Variable sized types have size == -1 and are
7866 treated as if consisting entirely of ints.
7867 Pad to 16 byte boundary if needed. */
7868 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
7869 && (cum
->words
% 2) != 0)
7871 /* For varargs, we can just go up by the size of the struct. */
7873 cum
->words
+= (size
+ 7) / 8;
7876 /* It is tempting to say int register count just goes up by
7877 sizeof(type)/8, but this is wrong in a case such as
7878 { int; double; int; } [powerpc alignment]. We have to
7879 grovel through the fields for these too. */
7881 cum
->floats_in_gpr
= 0;
7882 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
7883 rs6000_darwin64_record_arg_advance_flush (cum
,
7884 size
* BITS_PER_UNIT
, 1);
7886 if (TARGET_DEBUG_ARG
)
7888 fprintf (stderr
, "function_adv: words = %2d, align=%d, size=%d",
7889 cum
->words
, TYPE_ALIGN (type
), size
);
7891 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7892 cum
->nargs_prototype
, cum
->prototype
,
7893 GET_MODE_NAME (mode
));
7896 else if (DEFAULT_ABI
== ABI_V4
)
7898 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
7899 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
7900 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
7901 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
7902 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
7904 /* _Decimal128 must use an even/odd register pair. This assumes
7905 that the register number is odd when fregno is odd. */
7906 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
7909 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
7910 <= FP_ARG_V4_MAX_REG
)
7911 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7914 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
7915 if (mode
== DFmode
|| mode
== TFmode
7916 || mode
== DDmode
|| mode
== TDmode
)
7917 cum
->words
+= cum
->words
& 1;
7918 cum
->words
+= rs6000_arg_size (mode
, type
);
7923 int n_words
= rs6000_arg_size (mode
, type
);
7924 int gregno
= cum
->sysv_gregno
;
7926 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7927 (r7,r8) or (r9,r10). As does any other 2 word item such
7928 as complex int due to a historical mistake. */
7930 gregno
+= (1 - gregno
) & 1;
7932 /* Multi-reg args are not split between registers and stack. */
7933 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
7935 /* Long long and SPE vectors are aligned on the stack.
7936 So are other 2 word items such as complex int due to
7937 a historical mistake. */
7939 cum
->words
+= cum
->words
& 1;
7940 cum
->words
+= n_words
;
7943 /* Note: continuing to accumulate gregno past when we've started
7944 spilling to the stack indicates the fact that we've started
7945 spilling to the stack to expand_builtin_saveregs. */
7946 cum
->sysv_gregno
= gregno
+ n_words
;
7949 if (TARGET_DEBUG_ARG
)
7951 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
7952 cum
->words
, cum
->fregno
);
7953 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
7954 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
7955 fprintf (stderr
, "mode = %4s, named = %d\n",
7956 GET_MODE_NAME (mode
), named
);
7961 int n_words
= rs6000_arg_size (mode
, type
);
7962 int start_words
= cum
->words
;
7963 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
7965 cum
->words
= align_words
+ n_words
;
7967 if (SCALAR_FLOAT_MODE_P (mode
)
7968 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
7970 /* _Decimal128 must be passed in an even/odd float register pair.
7971 This assumes that the register number is odd when fregno is
7973 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
7975 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7978 if (TARGET_DEBUG_ARG
)
7980 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
7981 cum
->words
, cum
->fregno
);
7982 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
7983 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
7984 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
7985 named
, align_words
- start_words
, depth
);
7991 rs6000_function_arg_advance (cumulative_args_t cum
, enum machine_mode mode
,
7992 const_tree type
, bool named
)
7994 rs6000_function_arg_advance_1 (get_cumulative_args (cum
), mode
, type
, named
,
7999 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
8006 r1
= gen_rtx_REG (DImode
, gregno
);
8007 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8008 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
8012 r1
= gen_rtx_REG (DImode
, gregno
);
8013 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8014 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8015 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8016 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
8019 r1
= gen_rtx_REG (DImode
, gregno
);
8020 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8021 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8022 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8023 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
8024 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
8025 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
8026 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
8027 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
8034 /* Determine where to put a SIMD argument on the SPE. */
8036 rs6000_spe_function_arg (const CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8039 int gregno
= cum
->sysv_gregno
;
8041 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8042 are passed and returned in a pair of GPRs for ABI compatibility. */
8043 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
8044 || mode
== DCmode
|| mode
== TCmode
))
8046 int n_words
= rs6000_arg_size (mode
, type
);
8048 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8050 gregno
+= (1 - gregno
) & 1;
8052 /* Multi-reg args are not split between registers and stack. */
8053 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8056 return spe_build_register_parallel (mode
, gregno
);
8060 int n_words
= rs6000_arg_size (mode
, type
);
8062 /* SPE vectors are put in odd registers. */
8063 if (n_words
== 2 && (gregno
& 1) == 0)
8066 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
8069 enum machine_mode m
= SImode
;
8071 r1
= gen_rtx_REG (m
, gregno
);
8072 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
8073 r2
= gen_rtx_REG (m
, gregno
+ 1);
8074 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
8075 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
8082 if (gregno
<= GP_ARG_MAX_REG
)
8083 return gen_rtx_REG (mode
, gregno
);
8089 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8090 structure between cum->intoffset and bitpos to integer registers. */
8093 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
8094 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
8096 enum machine_mode mode
;
8098 unsigned int startbit
, endbit
;
8099 int this_regno
, intregs
, intoffset
;
8102 if (cum
->intoffset
== -1)
8105 intoffset
= cum
->intoffset
;
8106 cum
->intoffset
= -1;
8108 /* If this is the trailing part of a word, try to only load that
8109 much into the register. Otherwise load the whole register. Note
8110 that in the latter case we may pick up unwanted bits. It's not a
8111 problem at the moment but may wish to revisit. */
8113 if (intoffset
% BITS_PER_WORD
!= 0)
8115 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
8117 if (mode
== BLKmode
)
8119 /* We couldn't find an appropriate mode, which happens,
8120 e.g., in packed structs when there are 3 bytes to load.
8121 Back intoffset back to the beginning of the word in this
8123 intoffset
= intoffset
& -BITS_PER_WORD
;
8130 startbit
= intoffset
& -BITS_PER_WORD
;
8131 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
8132 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
8133 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
8135 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
8138 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
8142 intoffset
/= BITS_PER_UNIT
;
8145 regno
= GP_ARG_MIN_REG
+ this_regno
;
8146 reg
= gen_rtx_REG (mode
, regno
);
8148 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
8151 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
8155 while (intregs
> 0);
8158 /* Recursive workhorse for the following. */
8161 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
8162 HOST_WIDE_INT startbitpos
, rtx rvec
[],
8167 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
8168 if (TREE_CODE (f
) == FIELD_DECL
)
8170 HOST_WIDE_INT bitpos
= startbitpos
;
8171 tree ftype
= TREE_TYPE (f
);
8172 enum machine_mode mode
;
8173 if (ftype
== error_mark_node
)
8175 mode
= TYPE_MODE (ftype
);
8177 if (DECL_SIZE (f
) != 0
8178 && host_integerp (bit_position (f
), 1))
8179 bitpos
+= int_bit_position (f
);
8181 /* ??? FIXME: else assume zero offset. */
8183 if (TREE_CODE (ftype
) == RECORD_TYPE
)
8184 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
8185 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
8187 unsigned n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8191 case SCmode
: mode
= SFmode
; break;
8192 case DCmode
: mode
= DFmode
; break;
8193 case TCmode
: mode
= TFmode
; break;
8197 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8198 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
8200 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
8201 && (mode
== TFmode
|| mode
== TDmode
));
8202 /* Long double or _Decimal128 split over regs and memory. */
8203 mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
8207 = gen_rtx_EXPR_LIST (VOIDmode
,
8208 gen_rtx_REG (mode
, cum
->fregno
++),
8209 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8210 if (mode
== TFmode
|| mode
== TDmode
)
8213 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
8215 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8217 = gen_rtx_EXPR_LIST (VOIDmode
,
8218 gen_rtx_REG (mode
, cum
->vregno
++),
8219 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8221 else if (cum
->intoffset
== -1)
8222 cum
->intoffset
= bitpos
;
8226 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8227 the register(s) to be used for each field and subfield of a struct
8228 being passed by value, along with the offset of where the
8229 register's value may be found in the block. FP fields go in FP
8230 register, vector fields go in vector registers, and everything
8231 else goes in int registers, packed as in memory.
8233 This code is also used for function return values. RETVAL indicates
8234 whether this is the case.
8236 Much of this is taken from the SPARC V9 port, which has a similar
8237 calling convention. */
8240 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
8241 bool named
, bool retval
)
8243 rtx rvec
[FIRST_PSEUDO_REGISTER
];
8244 int k
= 1, kbase
= 1;
8245 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
8246 /* This is a copy; modifications are not visible to our caller. */
8247 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
8248 CUMULATIVE_ARGS
*cum
= ©_cum
;
8250 /* Pad to 16 byte boundary if needed. */
8251 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8252 && (cum
->words
% 2) != 0)
8259 /* Put entries into rvec[] for individual FP and vector fields, and
8260 for the chunks of memory that go in int regs. Note we start at
8261 element 1; 0 is reserved for an indication of using memory, and
8262 may or may not be filled in below. */
8263 rs6000_darwin64_record_arg_recurse (cum
, type
, /* startbit pos= */ 0, rvec
, &k
);
8264 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
8266 /* If any part of the struct went on the stack put all of it there.
8267 This hack is because the generic code for
8268 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8269 parts of the struct are not at the beginning. */
8273 return NULL_RTX
; /* doesn't go in registers at all */
8275 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8277 if (k
> 1 || cum
->use_stack
)
8278 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
8283 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8286 rs6000_mixed_function_arg (enum machine_mode mode
, const_tree type
,
8291 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8293 if (align_words
>= GP_ARG_NUM_REG
)
8296 n_units
= rs6000_arg_size (mode
, type
);
8298 /* Optimize the simple case where the arg fits in one gpr, except in
8299 the case of BLKmode due to assign_parms assuming that registers are
8300 BITS_PER_WORD wide. */
8302 || (n_units
== 1 && mode
!= BLKmode
))
8303 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8306 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
8307 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8308 using a magic NULL_RTX component.
8309 This is not strictly correct. Only some of the arg belongs in
8310 memory, not all of it. However, the normal scheme using
8311 function_arg_partial_nregs can result in unusual subregs, eg.
8312 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8313 store the whole arg to memory is often more efficient than code
8314 to store pieces, and we know that space is available in the right
8315 place for the whole arg. */
8316 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8321 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
8322 rtx off
= GEN_INT (i
++ * 4);
8323 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8325 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
8327 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8330 /* Determine where to put an argument to a function.
8331 Value is zero to push the argument on the stack,
8332 or a hard register in which to store the argument.
8334 MODE is the argument's machine mode.
8335 TYPE is the data type of the argument (as a tree).
8336 This is null for libcalls where that information may
8338 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8339 the preceding args and about the function being called. It is
8340 not modified in this routine.
8341 NAMED is nonzero if this argument is a named parameter
8342 (otherwise it is an extra parameter matching an ellipsis).
8344 On RS/6000 the first eight words of non-FP are normally in registers
8345 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8346 Under V.4, the first 8 FP args are in registers.
8348 If this is floating-point and no prototype is specified, we use
8349 both an FP and integer register (or possibly FP reg and stack). Library
8350 functions (when CALL_LIBCALL is set) always have the proper types for args,
8351 so we can pass the FP value just in one register. emit_library_function
8352 doesn't support PARALLEL anyway.
8354 Note that for args passed by reference, function_arg will be called
8355 with MODE and TYPE set to that of the pointer to the arg, not the arg
8359 rs6000_function_arg (cumulative_args_t cum_v
, enum machine_mode mode
,
8360 const_tree type
, bool named
)
8362 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
8363 enum rs6000_abi abi
= DEFAULT_ABI
;
8365 /* Return a marker to indicate whether CR1 needs to set or clear the
8366 bit that V.4 uses to say fp args were passed in registers.
8367 Assume that we don't need the marker for software floating point,
8368 or compiler generated library calls. */
8369 if (mode
== VOIDmode
)
8372 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
8374 || (cum
->nargs_prototype
< 0
8375 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
8377 /* For the SPE, we need to crxor CR6 always. */
8379 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
8380 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8381 return GEN_INT (cum
->call_cookie
8382 | ((cum
->fregno
== FP_ARG_MIN_REG
)
8383 ? CALL_V4_SET_FP_ARGS
8384 : CALL_V4_CLEAR_FP_ARGS
));
8387 return GEN_INT (cum
->call_cookie
& ~CALL_LIBCALL
);
8390 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8392 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, /*retval= */false);
8393 if (rslt
!= NULL_RTX
)
8395 /* Else fall through to usual handling. */
8398 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
8399 if (TARGET_64BIT
&& ! cum
->prototype
)
8401 /* Vector parameters get passed in vector register
8402 and also in GPRs or memory, in absence of prototype. */
8405 align_words
= (cum
->words
+ 1) & ~1;
8407 if (align_words
>= GP_ARG_NUM_REG
)
8413 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8415 return gen_rtx_PARALLEL (mode
,
8417 gen_rtx_EXPR_LIST (VOIDmode
,
8419 gen_rtx_EXPR_LIST (VOIDmode
,
8420 gen_rtx_REG (mode
, cum
->vregno
),
8424 return gen_rtx_REG (mode
, cum
->vregno
);
8425 else if (TARGET_ALTIVEC_ABI
8426 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode
)
8427 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8428 && int_size_in_bytes (type
) == 16)))
8430 if (named
|| abi
== ABI_V4
)
8434 /* Vector parameters to varargs functions under AIX or Darwin
8435 get passed in memory and possibly also in GPRs. */
8436 int align
, align_words
, n_words
;
8437 enum machine_mode part_mode
;
8439 /* Vector parameters must be 16-byte aligned. This places them at
8440 2 mod 4 in terms of words in 32-bit mode, since the parameter
8441 save area starts at offset 24 from the stack. In 64-bit mode,
8442 they just have to start on an even word, since the parameter
8443 save area is 16-byte aligned. */
8445 align
= (2 - cum
->words
) & 3;
8447 align
= cum
->words
& 1;
8448 align_words
= cum
->words
+ align
;
8450 /* Out of registers? Memory, then. */
8451 if (align_words
>= GP_ARG_NUM_REG
)
8454 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8455 return rs6000_mixed_function_arg (mode
, type
, align_words
);
8457 /* The vector value goes in GPRs. Only the part of the
8458 value in GPRs is reported here. */
8460 n_words
= rs6000_arg_size (mode
, type
);
8461 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
8462 /* Fortunately, there are only two possibilities, the value
8463 is either wholly in GPRs or half in GPRs and half not. */
8466 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
8469 else if (TARGET_SPE_ABI
&& TARGET_SPE
8470 && (SPE_VECTOR_MODE (mode
)
8471 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
8474 || mode
== TCmode
))))
8475 return rs6000_spe_function_arg (cum
, mode
, type
);
8477 else if (abi
== ABI_V4
)
8479 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8480 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
8481 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
8482 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
8483 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8485 /* _Decimal128 must use an even/odd register pair. This assumes
8486 that the register number is odd when fregno is odd. */
8487 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8490 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
8491 <= FP_ARG_V4_MAX_REG
)
8492 return gen_rtx_REG (mode
, cum
->fregno
);
8498 int n_words
= rs6000_arg_size (mode
, type
);
8499 int gregno
= cum
->sysv_gregno
;
8501 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8502 (r7,r8) or (r9,r10). As does any other 2 word item such
8503 as complex int due to a historical mistake. */
8505 gregno
+= (1 - gregno
) & 1;
8507 /* Multi-reg args are not split between registers and stack. */
8508 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8511 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8512 return rs6000_mixed_function_arg (mode
, type
,
8513 gregno
- GP_ARG_MIN_REG
);
8514 return gen_rtx_REG (mode
, gregno
);
8519 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
8521 /* _Decimal128 must be passed in an even/odd float register pair.
8522 This assumes that the register number is odd when fregno is odd. */
8523 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8526 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
8528 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8532 enum machine_mode fmode
= mode
;
8533 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8535 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
8537 /* Currently, we only ever need one reg here because complex
8538 doubles are split. */
8539 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
8540 && (fmode
== TFmode
|| fmode
== TDmode
));
8542 /* Long double or _Decimal128 split over regs and memory. */
8543 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
8546 /* Do we also need to pass this arg in the parameter save
8549 && (cum
->nargs_prototype
<= 0
8550 || (DEFAULT_ABI
== ABI_AIX
8552 && align_words
>= GP_ARG_NUM_REG
)));
8554 if (!needs_psave
&& mode
== fmode
)
8555 return gen_rtx_REG (fmode
, cum
->fregno
);
8560 /* Describe the part that goes in gprs or the stack.
8561 This piece must come first, before the fprs. */
8562 if (align_words
< GP_ARG_NUM_REG
)
8564 unsigned long n_words
= rs6000_arg_size (mode
, type
);
8566 if (align_words
+ n_words
> GP_ARG_NUM_REG
8567 || (TARGET_32BIT
&& TARGET_POWERPC64
))
8569 /* If this is partially on the stack, then we only
8570 include the portion actually in registers here. */
8571 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
8574 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
8575 /* Not all of the arg fits in gprs. Say that it
8576 goes in memory too, using a magic NULL_RTX
8577 component. Also see comment in
8578 rs6000_mixed_function_arg for why the normal
8579 function_arg_partial_nregs scheme doesn't work
8581 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
8585 r
= gen_rtx_REG (rmode
,
8586 GP_ARG_MIN_REG
+ align_words
);
8587 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
8588 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8590 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
8594 /* The whole arg fits in gprs. */
8595 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8596 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
8600 /* It's entirely in memory. */
8601 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8604 /* Describe where this piece goes in the fprs. */
8605 r
= gen_rtx_REG (fmode
, cum
->fregno
);
8606 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
8608 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8610 else if (align_words
< GP_ARG_NUM_REG
)
8612 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8613 return rs6000_mixed_function_arg (mode
, type
, align_words
);
8615 if (mode
== BLKmode
)
8618 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8625 /* For an arg passed partly in registers and partly in memory, this is
8626 the number of bytes passed in registers. For args passed entirely in
8627 registers or entirely in memory, zero. When an arg is described by a
8628 PARALLEL, perhaps using more than one register type, this function
8629 returns the number of bytes used by the first element of the PARALLEL. */
8632 rs6000_arg_partial_bytes (cumulative_args_t cum_v
, enum machine_mode mode
,
8633 tree type
, bool named
)
8635 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
8639 if (DEFAULT_ABI
== ABI_V4
)
8642 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
8643 && cum
->nargs_prototype
>= 0)
8646 /* In this complicated case we just disable the partial_nregs code. */
8647 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8650 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
8652 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
8654 /* If we are passing this arg in the fixed parameter save area
8655 (gprs or memory) as well as fprs, then this function should
8656 return the number of partial bytes passed in the parameter
8657 save area rather than partial bytes passed in fprs. */
8659 && (cum
->nargs_prototype
<= 0
8660 || (DEFAULT_ABI
== ABI_AIX
8662 && align_words
>= GP_ARG_NUM_REG
)))
8664 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
8665 > FP_ARG_MAX_REG
+ 1)
8666 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
8667 else if (cum
->nargs_prototype
>= 0)
8671 if (align_words
< GP_ARG_NUM_REG
8672 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
8673 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
8675 if (ret
!= 0 && TARGET_DEBUG_ARG
)
8676 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
8681 /* A C expression that indicates when an argument must be passed by
8682 reference. If nonzero for an argument, a copy of that argument is
8683 made in memory and a pointer to the argument is passed instead of
8684 the argument itself. The pointer is passed in whatever way is
8685 appropriate for passing a pointer to that type.
8687 Under V.4, aggregates and long double are passed by reference.
8689 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8690 reference unless the AltiVec vector extension ABI is in force.
8692 As an extension to all ABIs, variable sized types are passed by
8696 rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED
,
8697 enum machine_mode mode
, const_tree type
,
8698 bool named ATTRIBUTE_UNUSED
)
8700 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
8702 if (TARGET_DEBUG_ARG
)
8703 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
8710 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
8712 if (TARGET_DEBUG_ARG
)
8713 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
8717 if (int_size_in_bytes (type
) < 0)
8719 if (TARGET_DEBUG_ARG
)
8720 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
8724 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8725 modes only exist for GCC vector types if -maltivec. */
8726 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
8728 if (TARGET_DEBUG_ARG
)
8729 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
8733 /* Pass synthetic vectors in memory. */
8734 if (TREE_CODE (type
) == VECTOR_TYPE
8735 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
8737 static bool warned_for_pass_big_vectors
= false;
8738 if (TARGET_DEBUG_ARG
)
8739 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
8740 if (!warned_for_pass_big_vectors
)
8742 warning (0, "GCC vector passed by reference: "
8743 "non-standard ABI extension with no compatibility guarantee");
8744 warned_for_pass_big_vectors
= true;
8753 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
8756 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
8761 for (i
= 0; i
< nregs
; i
++)
8763 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
8764 if (reload_completed
)
8766 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
8769 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
8770 i
* GET_MODE_SIZE (reg_mode
));
8773 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
8777 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
8781 /* Perform any needed actions needed for a function that is receiving a
8782 variable number of arguments.
8786 MODE and TYPE are the mode and type of the current parameter.
8788 PRETEND_SIZE is a variable that should be set to the amount of stack
8789 that must be pushed by the prolog to pretend that our caller pushed
8792 Normally, this macro will push all remaining incoming registers on the
8793 stack and set PRETEND_SIZE to the length of the registers pushed. */
8796 setup_incoming_varargs (cumulative_args_t cum
, enum machine_mode mode
,
8797 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
8800 CUMULATIVE_ARGS next_cum
;
8801 int reg_size
= TARGET_32BIT
? 4 : 8;
8802 rtx save_area
= NULL_RTX
, mem
;
8803 int first_reg_offset
;
8806 /* Skip the last named argument. */
8807 next_cum
= *get_cumulative_args (cum
);
8808 rs6000_function_arg_advance_1 (&next_cum
, mode
, type
, true, 0);
8810 if (DEFAULT_ABI
== ABI_V4
)
8812 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
8816 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
8817 HOST_WIDE_INT offset
= 0;
8819 /* Try to optimize the size of the varargs save area.
8820 The ABI requires that ap.reg_save_area is doubleword
8821 aligned, but we don't need to allocate space for all
8822 the bytes, only those to which we actually will save
8824 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
8825 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
8826 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8827 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
8828 && cfun
->va_list_fpr_size
)
8831 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
8832 * UNITS_PER_FP_WORD
;
8833 if (cfun
->va_list_fpr_size
8834 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
8835 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
8837 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
8838 * UNITS_PER_FP_WORD
;
8842 offset
= -((first_reg_offset
* reg_size
) & ~7);
8843 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
8845 gpr_reg_num
= cfun
->va_list_gpr_size
;
8846 if (reg_size
== 4 && (first_reg_offset
& 1))
8849 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
8852 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
8854 - (int) (GP_ARG_NUM_REG
* reg_size
);
8856 if (gpr_size
+ fpr_size
)
8859 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
8860 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
8861 reg_save_area
= XEXP (reg_save_area
, 0);
8862 if (GET_CODE (reg_save_area
) == PLUS
)
8864 gcc_assert (XEXP (reg_save_area
, 0)
8865 == virtual_stack_vars_rtx
);
8866 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
8867 offset
+= INTVAL (XEXP (reg_save_area
, 1));
8870 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
8873 cfun
->machine
->varargs_save_offset
= offset
;
8874 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
8879 first_reg_offset
= next_cum
.words
;
8880 save_area
= virtual_incoming_args_rtx
;
8882 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
8883 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
8886 set
= get_varargs_alias_set ();
8887 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
8888 && cfun
->va_list_gpr_size
)
8890 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
8892 if (va_list_gpr_counter_field
)
8894 /* V4 va_list_gpr_size counts number of registers needed. */
8895 if (nregs
> cfun
->va_list_gpr_size
)
8896 nregs
= cfun
->va_list_gpr_size
;
8900 /* char * va_list instead counts number of bytes needed. */
8901 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
8902 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
8905 mem
= gen_rtx_MEM (BLKmode
,
8906 plus_constant (save_area
,
8907 first_reg_offset
* reg_size
));
8908 MEM_NOTRAP_P (mem
) = 1;
8909 set_mem_alias_set (mem
, set
);
8910 set_mem_align (mem
, BITS_PER_WORD
);
8912 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
8916 /* Save FP registers if needed. */
8917 if (DEFAULT_ABI
== ABI_V4
8918 && TARGET_HARD_FLOAT
&& TARGET_FPRS
8920 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
8921 && cfun
->va_list_fpr_size
)
8923 int fregno
= next_cum
.fregno
, nregs
;
8924 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
8925 rtx lab
= gen_label_rtx ();
8926 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
8927 * UNITS_PER_FP_WORD
);
8930 (gen_rtx_SET (VOIDmode
,
8932 gen_rtx_IF_THEN_ELSE (VOIDmode
,
8933 gen_rtx_NE (VOIDmode
, cr1
,
8935 gen_rtx_LABEL_REF (VOIDmode
, lab
),
8939 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
8940 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
8942 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
8944 plus_constant (save_area
, off
));
8945 MEM_NOTRAP_P (mem
) = 1;
8946 set_mem_alias_set (mem
, set
);
8947 set_mem_align (mem
, GET_MODE_ALIGNMENT (
8948 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
8949 ? DFmode
: SFmode
));
8950 emit_move_insn (mem
, gen_rtx_REG (
8951 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
8952 ? DFmode
: SFmode
, fregno
));
8959 /* Create the va_list data type. */
8962 rs6000_build_builtin_va_list (void)
8964 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
8966 /* For AIX, prefer 'char *' because that's what the system
8967 header files like. */
8968 if (DEFAULT_ABI
!= ABI_V4
)
8969 return build_pointer_type (char_type_node
);
8971 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
8972 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
8973 get_identifier ("__va_list_tag"), record
);
8975 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
8976 unsigned_char_type_node
);
8977 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
8978 unsigned_char_type_node
);
8979 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8981 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
8982 get_identifier ("reserved"), short_unsigned_type_node
);
8983 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
8984 get_identifier ("overflow_arg_area"),
8986 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
8987 get_identifier ("reg_save_area"),
8990 va_list_gpr_counter_field
= f_gpr
;
8991 va_list_fpr_counter_field
= f_fpr
;
8993 DECL_FIELD_CONTEXT (f_gpr
) = record
;
8994 DECL_FIELD_CONTEXT (f_fpr
) = record
;
8995 DECL_FIELD_CONTEXT (f_res
) = record
;
8996 DECL_FIELD_CONTEXT (f_ovf
) = record
;
8997 DECL_FIELD_CONTEXT (f_sav
) = record
;
8999 TYPE_STUB_DECL (record
) = type_decl
;
9000 TYPE_NAME (record
) = type_decl
;
9001 TYPE_FIELDS (record
) = f_gpr
;
9002 DECL_CHAIN (f_gpr
) = f_fpr
;
9003 DECL_CHAIN (f_fpr
) = f_res
;
9004 DECL_CHAIN (f_res
) = f_ovf
;
9005 DECL_CHAIN (f_ovf
) = f_sav
;
9007 layout_type (record
);
9009 /* The correct type is an array type of one element. */
9010 return build_array_type (record
, build_index_type (size_zero_node
));
9013 /* Implement va_start. */
9016 rs6000_va_start (tree valist
, rtx nextarg
)
9018 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
9019 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9020 tree gpr
, fpr
, ovf
, sav
, t
;
9022 /* Only SVR4 needs something special. */
9023 if (DEFAULT_ABI
!= ABI_V4
)
9025 std_expand_builtin_va_start (valist
, nextarg
);
9029 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9030 f_fpr
= DECL_CHAIN (f_gpr
);
9031 f_res
= DECL_CHAIN (f_fpr
);
9032 f_ovf
= DECL_CHAIN (f_res
);
9033 f_sav
= DECL_CHAIN (f_ovf
);
9035 valist
= build_simple_mem_ref (valist
);
9036 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9037 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9039 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9041 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9044 /* Count number of gp and fp argument registers used. */
9045 words
= crtl
->args
.info
.words
;
9046 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
9048 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
9051 if (TARGET_DEBUG_ARG
)
9052 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
9053 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
9054 words
, n_gpr
, n_fpr
);
9056 if (cfun
->va_list_gpr_size
)
9058 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
9059 build_int_cst (NULL_TREE
, n_gpr
));
9060 TREE_SIDE_EFFECTS (t
) = 1;
9061 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9064 if (cfun
->va_list_fpr_size
)
9066 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
9067 build_int_cst (NULL_TREE
, n_fpr
));
9068 TREE_SIDE_EFFECTS (t
) = 1;
9069 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9071 #ifdef HAVE_AS_GNU_ATTRIBUTE
9072 if (call_ABI_of_interest (cfun
->decl
))
9073 rs6000_passes_float
= true;
9077 /* Find the overflow area. */
9078 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
9080 t
= fold_build_pointer_plus_hwi (t
, words
* UNITS_PER_WORD
);
9081 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
9082 TREE_SIDE_EFFECTS (t
) = 1;
9083 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9085 /* If there were no va_arg invocations, don't set up the register
9087 if (!cfun
->va_list_gpr_size
9088 && !cfun
->va_list_fpr_size
9089 && n_gpr
< GP_ARG_NUM_REG
9090 && n_fpr
< FP_ARG_V4_MAX_REG
)
9093 /* Find the register save area. */
9094 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
9095 if (cfun
->machine
->varargs_save_offset
)
9096 t
= fold_build_pointer_plus_hwi (t
, cfun
->machine
->varargs_save_offset
);
9097 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
9098 TREE_SIDE_EFFECTS (t
) = 1;
9099 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9102 /* Implement va_arg. */
9105 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
9108 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9109 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
9110 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
9111 tree lab_false
, lab_over
, addr
;
9113 tree ptrtype
= build_pointer_type_for_mode (type
, ptr_mode
, true);
9117 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
9119 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
9120 return build_va_arg_indirect_ref (t
);
9123 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9124 earlier version of gcc, with the property that it always applied alignment
9125 adjustments to the va-args (even for zero-sized types). The cheapest way
9126 to deal with this is to replicate the effect of the part of
9127 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9129 We don't need to check for pass-by-reference because of the test above.
9130 We can return a simplifed answer, since we know there's no offset to add. */
9133 && rs6000_darwin64_abi
9134 && integer_zerop (TYPE_SIZE (type
)))
9136 unsigned HOST_WIDE_INT align
, boundary
;
9137 tree valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
9138 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
9139 boundary
= rs6000_function_arg_boundary (TYPE_MODE (type
), type
);
9140 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
9141 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
9142 boundary
/= BITS_PER_UNIT
;
9143 if (boundary
> align
)
9146 /* This updates arg ptr by the amount that would be necessary
9147 to align the zero-sized (but not zero-alignment) item. */
9148 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9149 fold_build_pointer_plus_hwi (valist_tmp
, boundary
- 1));
9150 gimplify_and_add (t
, pre_p
);
9152 t
= fold_convert (sizetype
, valist_tmp
);
9153 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9154 fold_convert (TREE_TYPE (valist
),
9155 fold_build2 (BIT_AND_EXPR
, sizetype
, t
,
9156 size_int (-boundary
))));
9157 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
9158 gimplify_and_add (t
, pre_p
);
9160 /* Since it is zero-sized there's no increment for the item itself. */
9161 valist_tmp
= fold_convert (build_pointer_type (type
), valist_tmp
);
9162 return build_va_arg_indirect_ref (valist_tmp
);
9165 if (DEFAULT_ABI
!= ABI_V4
)
9167 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
9169 tree elem_type
= TREE_TYPE (type
);
9170 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
9171 int elem_size
= GET_MODE_SIZE (elem_mode
);
9173 if (elem_size
< UNITS_PER_WORD
)
9175 tree real_part
, imag_part
;
9176 gimple_seq post
= NULL
;
9178 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9180 /* Copy the value into a temporary, lest the formal temporary
9181 be reused out from under us. */
9182 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
9183 gimple_seq_add_seq (pre_p
, post
);
9185 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9188 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
9192 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
9195 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9196 f_fpr
= DECL_CHAIN (f_gpr
);
9197 f_res
= DECL_CHAIN (f_fpr
);
9198 f_ovf
= DECL_CHAIN (f_res
);
9199 f_sav
= DECL_CHAIN (f_ovf
);
9201 valist
= build_va_arg_indirect_ref (valist
);
9202 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9203 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9205 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9207 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9210 size
= int_size_in_bytes (type
);
9211 rsize
= (size
+ 3) / 4;
9214 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9215 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
9216 || (TARGET_DOUBLE_FLOAT
9217 && (TYPE_MODE (type
) == DFmode
9218 || TYPE_MODE (type
) == TFmode
9219 || TYPE_MODE (type
) == SDmode
9220 || TYPE_MODE (type
) == DDmode
9221 || TYPE_MODE (type
) == TDmode
))))
9223 /* FP args go in FP registers, if present. */
9225 n_reg
= (size
+ 7) / 8;
9226 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
9227 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
9228 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
9233 /* Otherwise into GP registers. */
9242 /* Pull the value out of the saved registers.... */
9245 addr
= create_tmp_var (ptr_type_node
, "addr");
9247 /* AltiVec vectors never go in registers when -mabi=altivec. */
9248 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
9252 lab_false
= create_artificial_label (input_location
);
9253 lab_over
= create_artificial_label (input_location
);
9255 /* Long long and SPE vectors are aligned in the registers.
9256 As are any other 2 gpr item such as complex int due to a
9257 historical mistake. */
9259 if (n_reg
== 2 && reg
== gpr
)
9262 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9263 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
9264 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
9265 unshare_expr (reg
), u
);
9267 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9268 reg number is 0 for f1, so we want to make it odd. */
9269 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
9271 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9272 build_int_cst (TREE_TYPE (reg
), 1));
9273 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
9276 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
9277 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
9278 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
9279 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
9280 gimplify_and_add (t
, pre_p
);
9284 t
= fold_build_pointer_plus_hwi (sav
, sav_ofs
);
9286 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9287 build_int_cst (TREE_TYPE (reg
), n_reg
));
9288 u
= fold_convert (sizetype
, u
);
9289 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
9290 t
= fold_build_pointer_plus (t
, u
);
9292 /* _Decimal32 varargs are located in the second word of the 64-bit
9293 FP register for 32-bit binaries. */
9294 if (!TARGET_POWERPC64
9295 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9296 && TYPE_MODE (type
) == SDmode
)
9297 t
= fold_build_pointer_plus_hwi (t
, size
);
9299 gimplify_assign (addr
, t
, pre_p
);
9301 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
9303 stmt
= gimple_build_label (lab_false
);
9304 gimple_seq_add_stmt (pre_p
, stmt
);
9306 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
9308 /* Ensure that we don't find any more args in regs.
9309 Alignment has taken care of for special cases. */
9310 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
9314 /* ... otherwise out of the overflow area. */
9316 /* Care for on-stack alignment if needed. */
9320 t
= fold_build_pointer_plus_hwi (t
, align
- 1);
9321 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
9322 build_int_cst (TREE_TYPE (t
), -align
));
9324 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9326 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
9328 t
= fold_build_pointer_plus_hwi (t
, size
);
9329 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
9333 stmt
= gimple_build_label (lab_over
);
9334 gimple_seq_add_stmt (pre_p
, stmt
);
9337 if (STRICT_ALIGNMENT
9338 && (TYPE_ALIGN (type
)
9339 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
9341 /* The value (of type complex double, for example) may not be
9342 aligned in memory in the saved registers, so copy via a
9343 temporary. (This is the same code as used for SPARC.) */
9344 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
9345 tree dest_addr
= build_fold_addr_expr (tmp
);
9347 tree copy
= build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY
),
9348 3, dest_addr
, addr
, size_int (rsize
* 4));
9350 gimplify_and_add (copy
, pre_p
);
9354 addr
= fold_convert (ptrtype
, addr
);
9355 return build_va_arg_indirect_ref (addr
);
9361 def_builtin (int mask
, const char *name
, tree type
, int code
)
9363 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
9366 if (rs6000_builtin_decls
[code
])
9367 fatal_error ("internal error: builtin function to %s already processed",
9370 rs6000_builtin_decls
[code
] = t
=
9371 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
9374 gcc_assert (code
>= 0 && code
< (int)RS6000_BUILTIN_COUNT
);
9375 switch (builtin_classify
[code
])
9380 /* assume builtin can do anything. */
9381 case RS6000_BTC_MISC
:
9384 /* const function, function only depends on the inputs. */
9385 case RS6000_BTC_CONST
:
9386 TREE_READONLY (t
) = 1;
9387 TREE_NOTHROW (t
) = 1;
9390 /* pure function, function can read global memory. */
9391 case RS6000_BTC_PURE
:
9392 DECL_PURE_P (t
) = 1;
9393 TREE_NOTHROW (t
) = 1;
9396 /* Function is a math function. If rounding mode is on, then treat
9397 the function as not reading global memory, but it can have
9398 arbitrary side effects. If it is off, then assume the function is
9399 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9400 attribute in builtin-attribute.def that is used for the math
9402 case RS6000_BTC_FP_PURE
:
9403 TREE_NOTHROW (t
) = 1;
9404 if (flag_rounding_math
)
9406 DECL_PURE_P (t
) = 1;
9407 DECL_IS_NOVOPS (t
) = 1;
9410 TREE_READONLY (t
) = 1;
9416 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9418 static const struct builtin_description bdesc_3arg
[] =
9420 { MASK_ALTIVEC
, CODE_FOR_fmav4sf4
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
9421 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
9422 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
9423 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
9424 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
9425 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
9426 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
9427 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
9428 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
9429 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
9430 { MASK_ALTIVEC
, CODE_FOR_nfmsv4sf4
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
9431 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2df
, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF
},
9432 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di
, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI
},
9433 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
9434 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
9435 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
9436 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
9437 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS
},
9438 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS
},
9439 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS
},
9440 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS
},
9441 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
9442 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
9443 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
9444 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
9445 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2df
, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF
},
9446 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di
, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI
},
9447 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si_uns
, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS
},
9448 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS
},
9449 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS
},
9450 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di_uns
, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS
},
9451 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
9452 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
9453 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
9454 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
9456 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
9457 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
9458 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
9459 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
9460 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
9461 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
9462 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
9463 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
9464 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
9465 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
9466 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
9467 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
9468 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
9469 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
9470 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
9472 { MASK_VSX
, CODE_FOR_fmav2df4
, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP
},
9473 { MASK_VSX
, CODE_FOR_fmsv2df4
, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP
},
9474 { MASK_VSX
, CODE_FOR_nfmav2df4
, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP
},
9475 { MASK_VSX
, CODE_FOR_nfmsv2df4
, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP
},
9477 { MASK_VSX
, CODE_FOR_fmav4sf4
, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP
},
9478 { MASK_VSX
, CODE_FOR_fmsv4sf4
, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP
},
9479 { MASK_VSX
, CODE_FOR_nfmav4sf4
, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP
},
9480 { MASK_VSX
, CODE_FOR_nfmsv4sf4
, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP
},
9482 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB
},
9483 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD
},
9485 { MASK_VSX
, CODE_FOR_vector_select_v2di
, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI
},
9486 { MASK_VSX
, CODE_FOR_vector_select_v2df
, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF
},
9487 { MASK_VSX
, CODE_FOR_vector_select_v4sf
, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF
},
9488 { MASK_VSX
, CODE_FOR_vector_select_v4si
, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI
},
9489 { MASK_VSX
, CODE_FOR_vector_select_v8hi
, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI
},
9490 { MASK_VSX
, CODE_FOR_vector_select_v16qi
, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI
},
9491 { MASK_VSX
, CODE_FOR_vector_select_v2di_uns
, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS
},
9492 { MASK_VSX
, CODE_FOR_vector_select_v4si_uns
, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS
},
9493 { MASK_VSX
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS
},
9494 { MASK_VSX
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS
},
9496 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di
, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI
},
9497 { MASK_VSX
, CODE_FOR_altivec_vperm_v2df
, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF
},
9498 { MASK_VSX
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF
},
9499 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si
, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI
},
9500 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI
},
9501 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI
},
9502 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS
},
9503 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS
},
9504 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS
},
9505 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS
},
9507 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2df
, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF
},
9508 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2di
, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI
},
9509 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4sf
, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF
},
9510 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4si
, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI
},
9511 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v8hi
, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI
},
9512 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v16qi
, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI
},
9513 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI
},
9514 { MASK_VSX
, CODE_FOR_vsx_set_v2df
, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF
},
9515 { MASK_VSX
, CODE_FOR_vsx_set_v2di
, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI
},
9517 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2di
, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI
},
9518 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2df
, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF
},
9519 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4sf
, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF
},
9520 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4si
, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI
},
9521 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v8hi
, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI
},
9522 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v16qi
, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI
},
9523 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI
},
9525 { 0, CODE_FOR_fmsv2sf4
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
9526 { 0, CODE_FOR_fmav2sf4
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
9527 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
9528 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
9529 { 0, CODE_FOR_nfmsv2sf4
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
9530 { 0, CODE_FOR_nfmav2sf4
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
9531 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
9532 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
9533 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
9536 /* DST operations: void foo (void *, const int, const char). */
9538 static const struct builtin_description bdesc_dst
[] =
9540 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
9541 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
9542 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
9543 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
9545 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
9546 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
9547 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
9548 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
9551 /* Simple binary operations: VECc = foo (VECa, VECb). */
9553 static struct builtin_description bdesc_2arg
[] =
9555 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
9556 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
9557 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
9558 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
9559 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
9560 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
9561 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
9562 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
9563 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
9564 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
9565 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
9566 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
9567 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
9568 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
9569 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
9570 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
9571 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
9572 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
9573 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
9574 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
9575 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
9576 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
9577 { MASK_ALTIVEC
, CODE_FOR_vector_eqv16qi
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
9578 { MASK_ALTIVEC
, CODE_FOR_vector_eqv8hi
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
9579 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4si
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
9580 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4sf
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
9581 { MASK_ALTIVEC
, CODE_FOR_vector_gev4sf
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
9582 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv16qi
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
9583 { MASK_ALTIVEC
, CODE_FOR_vector_gtv16qi
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
9584 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv8hi
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
9585 { MASK_ALTIVEC
, CODE_FOR_vector_gtv8hi
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
9586 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv4si
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
9587 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4si
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
9588 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4sf
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
9589 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
9590 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
9591 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
9592 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
9593 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
9594 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
9595 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
9596 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
9597 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
9598 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
9599 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
9600 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
9601 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
9602 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
9603 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
9604 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
9605 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
9606 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
9607 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
9608 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
9609 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
9610 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
9611 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
9612 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS
},
9613 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
9614 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
9615 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS
},
9616 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
9617 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
9618 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS
},
9619 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
9620 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
9621 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS
},
9622 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
9623 { MASK_ALTIVEC
, CODE_FOR_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
9624 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
9625 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
9626 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
9627 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
9628 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
9629 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
9630 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
9631 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
9632 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
9633 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
9634 { MASK_ALTIVEC
, CODE_FOR_recipv4sf3
, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP
},
9635 { MASK_ALTIVEC
, CODE_FOR_vrotlv16qi3
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
9636 { MASK_ALTIVEC
, CODE_FOR_vrotlv8hi3
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
9637 { MASK_ALTIVEC
, CODE_FOR_vrotlv4si3
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
9638 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
9639 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
9640 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
9641 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
9642 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
9643 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
9644 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
9645 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
9646 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
9647 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
9648 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
9649 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
9650 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
9651 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
9652 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
9653 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
9654 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
9655 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
9656 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
9657 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
9658 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
9659 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
9660 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
9661 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
9662 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
9663 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
9664 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
9665 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
9666 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
9667 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
9668 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
9669 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
9670 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
9671 { MASK_ALTIVEC
, CODE_FOR_vector_copysignv4sf3
, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF
},
9673 { MASK_VSX
, CODE_FOR_addv2df3
, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP
},
9674 { MASK_VSX
, CODE_FOR_subv2df3
, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP
},
9675 { MASK_VSX
, CODE_FOR_mulv2df3
, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP
},
9676 { MASK_VSX
, CODE_FOR_divv2df3
, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP
},
9677 { MASK_VSX
, CODE_FOR_recipv2df3
, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF
},
9678 { MASK_VSX
, CODE_FOR_sminv2df3
, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP
},
9679 { MASK_VSX
, CODE_FOR_smaxv2df3
, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP
},
9680 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fe
, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE
},
9681 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fg
, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG
},
9682 { MASK_VSX
, CODE_FOR_vector_eqv2df
, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP
},
9683 { MASK_VSX
, CODE_FOR_vector_gtv2df
, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP
},
9684 { MASK_VSX
, CODE_FOR_vector_gev2df
, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP
},
9686 { MASK_VSX
, CODE_FOR_addv4sf3
, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP
},
9687 { MASK_VSX
, CODE_FOR_subv4sf3
, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP
},
9688 { MASK_VSX
, CODE_FOR_mulv4sf3
, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP
},
9689 { MASK_VSX
, CODE_FOR_divv4sf3
, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP
},
9690 { MASK_VSX
, CODE_FOR_recipv4sf3
, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF
},
9691 { MASK_VSX
, CODE_FOR_sminv4sf3
, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP
},
9692 { MASK_VSX
, CODE_FOR_smaxv4sf3
, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP
},
9693 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fe
, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE
},
9694 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fg
, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG
},
9695 { MASK_VSX
, CODE_FOR_vector_eqv4sf
, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP
},
9696 { MASK_VSX
, CODE_FOR_vector_gtv4sf
, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP
},
9697 { MASK_VSX
, CODE_FOR_vector_gev4sf
, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP
},
9699 { MASK_VSX
, CODE_FOR_smindf3
, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP
},
9700 { MASK_VSX
, CODE_FOR_smaxdf3
, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP
},
9701 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fe
, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE
},
9702 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fg
, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG
},
9703 { MASK_VSX
, CODE_FOR_vector_copysignv2df3
, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP
},
9704 { MASK_VSX
, CODE_FOR_vector_copysignv4sf3
, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP
},
9706 { MASK_VSX
, CODE_FOR_vsx_concat_v2df
, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF
},
9707 { MASK_VSX
, CODE_FOR_vsx_concat_v2di
, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI
},
9708 { MASK_VSX
, CODE_FOR_vsx_splat_v2df
, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF
},
9709 { MASK_VSX
, CODE_FOR_vsx_splat_v2di
, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI
},
9710 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4sf
, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF
},
9711 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4si
, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI
},
9712 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4sf
, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF
},
9713 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4si
, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI
},
9714 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2df
, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF
},
9715 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2di
, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI
},
9716 { MASK_VSX
, CODE_FOR_vec_interleave_highv2df
, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF
},
9717 { MASK_VSX
, CODE_FOR_vec_interleave_highv2di
, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI
},
9719 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
9720 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
9721 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
9722 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
9723 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
9724 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
9725 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
9726 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
9727 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
9728 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
9729 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
9730 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
9731 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
9732 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
9733 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
9734 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
9735 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
9736 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
9737 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
9738 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
9739 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
9740 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
9741 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
9742 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
9743 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
9744 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
9745 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
9746 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
9747 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
9748 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
9749 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
9750 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
9751 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
9752 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
9753 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
9754 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
9755 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
9756 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
9757 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
9758 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN
},
9759 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
9760 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
9761 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
9762 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
9763 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
9764 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
9765 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
9766 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
9767 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
9768 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
9769 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
9770 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
9771 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
9772 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
9773 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
9774 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
9775 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
9776 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
9777 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
9778 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
9779 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
9780 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
9781 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
9782 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
9783 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
9784 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
9785 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
9786 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
9787 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
9788 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
9789 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
9790 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
9791 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
9792 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
9793 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
9794 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
9795 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
9796 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
9797 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
9798 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
9799 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
9800 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
9801 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
9802 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
9803 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
9804 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
9805 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
9806 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
9807 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP
},
9808 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
9809 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
9810 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
9811 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
9812 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
9813 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
9814 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
9815 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
9816 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
9817 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
9818 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
9819 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
9820 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
9821 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
9822 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
9823 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
9824 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
9825 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
9826 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
9827 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
9828 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
9829 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
9830 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
9831 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
9832 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
9833 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
9834 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
9835 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
9836 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
9837 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
9838 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
9839 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
9840 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
9841 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
9842 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
9843 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
9844 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
9845 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
9846 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
9847 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
9849 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL
},
9850 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV
},
9852 { 0, CODE_FOR_paired_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
9853 { 0, CODE_FOR_paired_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
9854 { 0, CODE_FOR_paired_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
9855 { 0, CODE_FOR_paired_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
9856 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
9857 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
9858 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
9859 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
9860 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
9861 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
9863 /* Place holder, leave as first spe builtin. */
9864 { 0, CODE_FOR_addv2si3
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
9865 { 0, CODE_FOR_andv2si3
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
9866 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
9867 { 0, CODE_FOR_divv2si3
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
9868 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
9869 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
9870 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
9871 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
9872 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
9873 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
9874 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
9875 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
9876 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
9877 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
9878 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
9879 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
9880 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
9881 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
9882 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
9883 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
9884 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
9885 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
9886 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
9887 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
9888 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
9889 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
9890 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
9891 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
9892 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
9893 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
9894 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
9895 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
9896 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
9897 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
9898 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
9899 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
9900 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
9901 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
9902 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
9903 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
9904 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
9905 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
9906 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
9907 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
9908 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
9909 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
9910 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
9911 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
9912 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
9913 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
9914 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
9915 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
9916 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
9917 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
9918 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
9919 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
9920 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
9921 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
9922 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
9923 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
9924 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
9925 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
9926 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
9927 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
9928 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
9929 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
9930 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
9931 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
9932 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
9933 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
9934 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
9935 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
9936 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
9937 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
9938 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
9939 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
9940 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
9941 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
9942 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
9943 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
9944 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
9945 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
9946 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
9947 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
9948 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
9949 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
9950 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
9951 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
9952 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
9953 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
9954 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
9955 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
9956 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
9957 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
9958 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
9959 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
9960 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
9961 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
9962 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
9963 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
9964 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
9965 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
9966 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
9967 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
9968 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
9969 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
9970 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
9971 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
9972 { 0, CODE_FOR_subv2si3
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
9974 /* SPE binary operations expecting a 5-bit unsigned literal. */
9975 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
9977 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
9978 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
9979 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
9980 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
9981 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
9982 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
9983 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
9984 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
9985 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
9986 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
9987 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
9988 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
9989 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
9990 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
9991 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
9992 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
9993 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
9994 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
9995 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
9996 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
9997 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
9998 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
9999 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
10000 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
10001 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
10002 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
10004 /* Place-holder. Leave as last binary SPE builtin. */
10005 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
10008 /* AltiVec predicates. */
10010 struct builtin_description_predicates
10012 const unsigned int mask
;
10013 const enum insn_code icode
;
10014 const char *const name
;
10015 const enum rs6000_builtins code
;
10018 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
10020 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp_p
, "__builtin_altivec_vcmpbfp_p",
10021 ALTIVEC_BUILTIN_VCMPBFP_P
},
10022 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
,
10023 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
10024 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
,
10025 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
10026 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
,
10027 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
10028 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v4si_p
, "__builtin_altivec_vcmpequw_p",
10029 ALTIVEC_BUILTIN_VCMPEQUW_P
},
10030 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v4si_p
, "__builtin_altivec_vcmpgtsw_p",
10031 ALTIVEC_BUILTIN_VCMPGTSW_P
},
10032 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v4si_p
, "__builtin_altivec_vcmpgtuw_p",
10033 ALTIVEC_BUILTIN_VCMPGTUW_P
},
10034 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v8hi_p
, "__builtin_altivec_vcmpequh_p",
10035 ALTIVEC_BUILTIN_VCMPEQUH_P
},
10036 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v8hi_p
, "__builtin_altivec_vcmpgtsh_p",
10037 ALTIVEC_BUILTIN_VCMPGTSH_P
},
10038 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v8hi_p
, "__builtin_altivec_vcmpgtuh_p",
10039 ALTIVEC_BUILTIN_VCMPGTUH_P
},
10040 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v16qi_p
, "__builtin_altivec_vcmpequb_p",
10041 ALTIVEC_BUILTIN_VCMPEQUB_P
},
10042 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v16qi_p
, "__builtin_altivec_vcmpgtsb_p",
10043 ALTIVEC_BUILTIN_VCMPGTSB_P
},
10044 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v16qi_p
, "__builtin_altivec_vcmpgtub_p",
10045 ALTIVEC_BUILTIN_VCMPGTUB_P
},
10047 { MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
, "__builtin_vsx_xvcmpeqsp_p",
10048 VSX_BUILTIN_XVCMPEQSP_P
},
10049 { MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
, "__builtin_vsx_xvcmpgesp_p",
10050 VSX_BUILTIN_XVCMPGESP_P
},
10051 { MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
, "__builtin_vsx_xvcmpgtsp_p",
10052 VSX_BUILTIN_XVCMPGTSP_P
},
10053 { MASK_VSX
, CODE_FOR_vector_eq_v2df_p
, "__builtin_vsx_xvcmpeqdp_p",
10054 VSX_BUILTIN_XVCMPEQDP_P
},
10055 { MASK_VSX
, CODE_FOR_vector_ge_v2df_p
, "__builtin_vsx_xvcmpgedp_p",
10056 VSX_BUILTIN_XVCMPGEDP_P
},
10057 { MASK_VSX
, CODE_FOR_vector_gt_v2df_p
, "__builtin_vsx_xvcmpgtdp_p",
10058 VSX_BUILTIN_XVCMPGTDP_P
},
10060 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpeq_p",
10061 ALTIVEC_BUILTIN_VCMPEQ_P
},
10062 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpgt_p",
10063 ALTIVEC_BUILTIN_VCMPGT_P
},
10064 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpge_p",
10065 ALTIVEC_BUILTIN_VCMPGE_P
}
10068 /* SPE predicates. */
10069 static struct builtin_description bdesc_spe_predicates
[] =
10071 /* Place-holder. Leave as first. */
10072 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
10073 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
10074 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
10075 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
10076 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
10077 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
10078 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
10079 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
10080 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
10081 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
10082 /* Place-holder. Leave as last. */
10083 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
10086 /* SPE evsel predicates. */
10087 static struct builtin_description bdesc_spe_evsel
[] =
10089 /* Place-holder. Leave as first. */
10090 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
10091 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
10092 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
10093 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
10094 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
10095 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
10096 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
10097 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
10098 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
10099 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
10100 /* Place-holder. Leave as last. */
10101 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
10104 /* PAIRED predicates. */
10105 static const struct builtin_description bdesc_paired_preds
[] =
10107 /* Place-holder. Leave as first. */
10108 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
10109 /* Place-holder. Leave as last. */
10110 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
10113 /* ABS* operations. */
10115 static const struct builtin_description bdesc_abs
[] =
10117 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
10118 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
10119 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
10120 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
10121 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
10122 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
10123 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
},
10124 { MASK_VSX
, CODE_FOR_absv2df2
, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP
},
10125 { MASK_VSX
, CODE_FOR_vsx_nabsv2df2
, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP
},
10126 { MASK_VSX
, CODE_FOR_absv4sf2
, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP
},
10127 { MASK_VSX
, CODE_FOR_vsx_nabsv4sf2
, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP
},
10130 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10133 static struct builtin_description bdesc_1arg
[] =
10135 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
10136 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
10137 { MASK_ALTIVEC
, CODE_FOR_rev4sf2
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
10138 { MASK_ALTIVEC
, CODE_FOR_vector_floorv4sf2
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
10139 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
10140 { MASK_ALTIVEC
, CODE_FOR_vector_ceilv4sf2
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
10141 { MASK_ALTIVEC
, CODE_FOR_vector_btruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
10142 { MASK_ALTIVEC
, CODE_FOR_rsqrtv4sf2
, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP
},
10143 { MASK_ALTIVEC
, CODE_FOR_rsqrtev4sf2
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
10144 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
10145 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
10146 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
10147 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
10148 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
10149 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
10150 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
10151 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
10152 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
10154 { MASK_VSX
, CODE_FOR_negv2df2
, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP
},
10155 { MASK_VSX
, CODE_FOR_sqrtv2df2
, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP
},
10156 { MASK_VSX
, CODE_FOR_rsqrtv2df2
, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF
},
10157 { MASK_VSX
, CODE_FOR_rsqrtev2df2
, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP
},
10158 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fe
, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE
},
10159 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fg
, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG
},
10160 { MASK_VSX
, CODE_FOR_vsx_frev2df2
, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP
},
10162 { MASK_VSX
, CODE_FOR_negv4sf2
, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP
},
10163 { MASK_VSX
, CODE_FOR_sqrtv4sf2
, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP
},
10164 { MASK_VSX
, CODE_FOR_rsqrtv4sf2
, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF
},
10165 { MASK_VSX
, CODE_FOR_rsqrtev4sf2
, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP
},
10166 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fe
, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE
},
10167 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fg
, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG
},
10168 { MASK_VSX
, CODE_FOR_vsx_frev4sf2
, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP
},
10170 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP
},
10171 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP
},
10172 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsp
, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP
},
10173 { MASK_VSX
, CODE_FOR_vsx_xvcvspdp
, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP
},
10174 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fe
, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE
},
10175 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fg
, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG
},
10177 { MASK_VSX
, CODE_FOR_vsx_fix_truncv2dfv2di2
, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS
},
10178 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS
},
10179 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS
},
10180 { MASK_VSX
, CODE_FOR_vsx_floatv2div2df2
, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP
},
10181 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP
},
10182 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS
},
10184 { MASK_VSX
, CODE_FOR_vsx_fix_truncv4sfv4si2
, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS
},
10185 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv4sfv4si2
, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS
},
10186 { MASK_VSX
, CODE_FOR_vsx_floatv4siv4sf2
, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP
},
10187 { MASK_VSX
, CODE_FOR_vsx_floatunsv4siv4sf2
, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP
},
10189 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsxws
, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS
},
10190 { MASK_VSX
, CODE_FOR_vsx_xvcvdpuxws
, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS
},
10191 { MASK_VSX
, CODE_FOR_vsx_xvcvsxwdp
, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP
},
10192 { MASK_VSX
, CODE_FOR_vsx_xvcvuxwdp
, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP
},
10193 { MASK_VSX
, CODE_FOR_vsx_xvrdpi
, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI
},
10194 { MASK_VSX
, CODE_FOR_vsx_xvrdpic
, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC
},
10195 { MASK_VSX
, CODE_FOR_vsx_floorv2df2
, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM
},
10196 { MASK_VSX
, CODE_FOR_vsx_ceilv2df2
, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP
},
10197 { MASK_VSX
, CODE_FOR_vsx_btruncv2df2
, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ
},
10199 { MASK_VSX
, CODE_FOR_vsx_xvcvspsxds
, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS
},
10200 { MASK_VSX
, CODE_FOR_vsx_xvcvspuxds
, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS
},
10201 { MASK_VSX
, CODE_FOR_vsx_xvcvsxdsp
, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP
},
10202 { MASK_VSX
, CODE_FOR_vsx_xvcvuxdsp
, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP
},
10203 { MASK_VSX
, CODE_FOR_vsx_xvrspi
, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI
},
10204 { MASK_VSX
, CODE_FOR_vsx_xvrspic
, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC
},
10205 { MASK_VSX
, CODE_FOR_vsx_floorv4sf2
, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM
},
10206 { MASK_VSX
, CODE_FOR_vsx_ceilv4sf2
, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP
},
10207 { MASK_VSX
, CODE_FOR_vsx_btruncv4sf2
, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ
},
10209 { MASK_VSX
, CODE_FOR_vsx_xsrdpi
, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI
},
10210 { MASK_VSX
, CODE_FOR_vsx_xsrdpic
, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC
},
10211 { MASK_VSX
, CODE_FOR_vsx_floordf2
, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM
},
10212 { MASK_VSX
, CODE_FOR_vsx_ceildf2
, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP
},
10213 { MASK_VSX
, CODE_FOR_vsx_btruncdf2
, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ
},
10215 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
10216 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
10217 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
10218 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
10219 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
10220 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
10221 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
10222 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
10223 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
10224 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT
},
10225 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
10226 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
10227 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
10228 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
10229 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
10230 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
10231 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
10232 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
10233 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
10234 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
10236 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT
},
10237 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT
},
10238 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT
},
10240 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_floatv4siv4sf2
, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF
},
10241 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_unsigned_floatv4siv4sf2
, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
},
10242 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fix_truncv4sfv4si2
, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI
},
10243 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fixuns_truncv4sfv4si2
, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
},
10245 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10246 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10247 { 0, CODE_FOR_absv2si2
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
10248 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
10249 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
10250 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
10251 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
10252 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
10253 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
10254 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
10255 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
10256 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
10257 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
10258 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
10259 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
10260 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
10261 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
10262 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
10263 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
10264 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
10265 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
10266 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
10267 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
10268 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
10269 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
10270 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
10271 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
10272 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
10273 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
10274 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
10276 /* Place-holder. Leave as last unary SPE builtin. */
10277 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
10279 { 0, CODE_FOR_paired_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
10280 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
10281 { 0, CODE_FOR_paired_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
10282 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
10283 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
10287 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10290 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10291 rtx op0
= expand_normal (arg0
);
10292 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10293 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10295 if (icode
== CODE_FOR_nothing
)
10296 /* Builtin not supported on this processor. */
10299 /* If we got invalid arguments bail out before generating bad rtl. */
10300 if (arg0
== error_mark_node
)
10303 if (icode
== CODE_FOR_altivec_vspltisb
10304 || icode
== CODE_FOR_altivec_vspltish
10305 || icode
== CODE_FOR_altivec_vspltisw
10306 || icode
== CODE_FOR_spe_evsplatfi
10307 || icode
== CODE_FOR_spe_evsplati
)
10309 /* Only allow 5-bit *signed* literals. */
10310 if (GET_CODE (op0
) != CONST_INT
10311 || INTVAL (op0
) > 15
10312 || INTVAL (op0
) < -16)
10314 error ("argument 1 must be a 5-bit signed literal");
10320 || GET_MODE (target
) != tmode
10321 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10322 target
= gen_reg_rtx (tmode
);
10324 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10325 op0
= copy_to_mode_reg (mode0
, op0
);
10327 pat
= GEN_FCN (icode
) (target
, op0
);
10336 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
10338 rtx pat
, scratch1
, scratch2
;
10339 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10340 rtx op0
= expand_normal (arg0
);
10341 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10342 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10344 /* If we have invalid arguments, bail out before generating bad rtl. */
10345 if (arg0
== error_mark_node
)
10349 || GET_MODE (target
) != tmode
10350 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10351 target
= gen_reg_rtx (tmode
);
10353 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10354 op0
= copy_to_mode_reg (mode0
, op0
);
10356 scratch1
= gen_reg_rtx (mode0
);
10357 scratch2
= gen_reg_rtx (mode0
);
10359 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
10368 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10371 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10372 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10373 rtx op0
= expand_normal (arg0
);
10374 rtx op1
= expand_normal (arg1
);
10375 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10376 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10377 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10379 if (icode
== CODE_FOR_nothing
)
10380 /* Builtin not supported on this processor. */
10383 /* If we got invalid arguments bail out before generating bad rtl. */
10384 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10387 if (icode
== CODE_FOR_altivec_vcfux
10388 || icode
== CODE_FOR_altivec_vcfsx
10389 || icode
== CODE_FOR_altivec_vctsxs
10390 || icode
== CODE_FOR_altivec_vctuxs
10391 || icode
== CODE_FOR_altivec_vspltb
10392 || icode
== CODE_FOR_altivec_vsplth
10393 || icode
== CODE_FOR_altivec_vspltw
10394 || icode
== CODE_FOR_spe_evaddiw
10395 || icode
== CODE_FOR_spe_evldd
10396 || icode
== CODE_FOR_spe_evldh
10397 || icode
== CODE_FOR_spe_evldw
10398 || icode
== CODE_FOR_spe_evlhhesplat
10399 || icode
== CODE_FOR_spe_evlhhossplat
10400 || icode
== CODE_FOR_spe_evlhhousplat
10401 || icode
== CODE_FOR_spe_evlwhe
10402 || icode
== CODE_FOR_spe_evlwhos
10403 || icode
== CODE_FOR_spe_evlwhou
10404 || icode
== CODE_FOR_spe_evlwhsplat
10405 || icode
== CODE_FOR_spe_evlwwsplat
10406 || icode
== CODE_FOR_spe_evrlwi
10407 || icode
== CODE_FOR_spe_evslwi
10408 || icode
== CODE_FOR_spe_evsrwis
10409 || icode
== CODE_FOR_spe_evsubifw
10410 || icode
== CODE_FOR_spe_evsrwiu
)
10412 /* Only allow 5-bit unsigned literals. */
10414 if (TREE_CODE (arg1
) != INTEGER_CST
10415 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
10417 error ("argument 2 must be a 5-bit unsigned literal");
10423 || GET_MODE (target
) != tmode
10424 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10425 target
= gen_reg_rtx (tmode
);
10427 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10428 op0
= copy_to_mode_reg (mode0
, op0
);
10429 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10430 op1
= copy_to_mode_reg (mode1
, op1
);
10432 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
10441 altivec_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
10444 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
10445 tree arg0
= CALL_EXPR_ARG (exp
, 1);
10446 tree arg1
= CALL_EXPR_ARG (exp
, 2);
10447 rtx op0
= expand_normal (arg0
);
10448 rtx op1
= expand_normal (arg1
);
10449 enum machine_mode tmode
= SImode
;
10450 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10451 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10454 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
10456 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10460 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
10462 gcc_assert (mode0
== mode1
);
10464 /* If we have invalid arguments, bail out before generating bad rtl. */
10465 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10469 || GET_MODE (target
) != tmode
10470 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10471 target
= gen_reg_rtx (tmode
);
10473 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10474 op0
= copy_to_mode_reg (mode0
, op0
);
10475 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10476 op1
= copy_to_mode_reg (mode1
, op1
);
10478 scratch
= gen_reg_rtx (mode0
);
10480 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
10485 /* The vec_any* and vec_all* predicates use the same opcodes for two
10486 different operations, but the bits in CR6 will be different
10487 depending on what information we want. So we have to play tricks
10488 with CR6 to get the right bits out.
10490 If you think this is disgusting, look at the specs for the
10491 AltiVec predicates. */
10493 switch (cr6_form_int
)
10496 emit_insn (gen_cr6_test_for_zero (target
));
10499 emit_insn (gen_cr6_test_for_zero_reverse (target
));
10502 emit_insn (gen_cr6_test_for_lt (target
));
10505 emit_insn (gen_cr6_test_for_lt_reverse (target
));
10508 error ("argument 1 of __builtin_altivec_predicate is out of range");
10516 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
10519 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10520 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10521 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10522 enum machine_mode mode0
= Pmode
;
10523 enum machine_mode mode1
= Pmode
;
10524 rtx op0
= expand_normal (arg0
);
10525 rtx op1
= expand_normal (arg1
);
10527 if (icode
== CODE_FOR_nothing
)
10528 /* Builtin not supported on this processor. */
10531 /* If we got invalid arguments bail out before generating bad rtl. */
10532 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10536 || GET_MODE (target
) != tmode
10537 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10538 target
= gen_reg_rtx (tmode
);
10540 op1
= copy_to_mode_reg (mode1
, op1
);
10542 if (op0
== const0_rtx
)
10544 addr
= gen_rtx_MEM (tmode
, op1
);
10548 op0
= copy_to_mode_reg (mode0
, op0
);
10549 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
10552 pat
= GEN_FCN (icode
) (target
, addr
);
10562 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
10565 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10566 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10567 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10568 enum machine_mode mode0
= Pmode
;
10569 enum machine_mode mode1
= Pmode
;
10570 rtx op0
= expand_normal (arg0
);
10571 rtx op1
= expand_normal (arg1
);
10573 if (icode
== CODE_FOR_nothing
)
10574 /* Builtin not supported on this processor. */
10577 /* If we got invalid arguments bail out before generating bad rtl. */
10578 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10582 || GET_MODE (target
) != tmode
10583 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10584 target
= gen_reg_rtx (tmode
);
10586 op1
= copy_to_mode_reg (mode1
, op1
);
10588 if (op0
== const0_rtx
)
10590 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
10594 op0
= copy_to_mode_reg (mode0
, op0
);
10595 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
10598 pat
= GEN_FCN (icode
) (target
, addr
);
10608 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
10610 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10611 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10612 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10613 rtx op0
= expand_normal (arg0
);
10614 rtx op1
= expand_normal (arg1
);
10615 rtx op2
= expand_normal (arg2
);
10617 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
10618 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
10619 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
10621 /* Invalid arguments. Bail before doing anything stoopid! */
10622 if (arg0
== error_mark_node
10623 || arg1
== error_mark_node
10624 || arg2
== error_mark_node
)
10627 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
10628 op0
= copy_to_mode_reg (mode2
, op0
);
10629 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
10630 op1
= copy_to_mode_reg (mode0
, op1
);
10631 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
10632 op2
= copy_to_mode_reg (mode1
, op2
);
10634 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
10641 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
10643 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10644 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10645 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10646 rtx op0
= expand_normal (arg0
);
10647 rtx op1
= expand_normal (arg1
);
10648 rtx op2
= expand_normal (arg2
);
10650 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10651 enum machine_mode mode1
= Pmode
;
10652 enum machine_mode mode2
= Pmode
;
10654 /* Invalid arguments. Bail before doing anything stoopid! */
10655 if (arg0
== error_mark_node
10656 || arg1
== error_mark_node
10657 || arg2
== error_mark_node
)
10660 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
10661 op0
= copy_to_mode_reg (tmode
, op0
);
10663 op2
= copy_to_mode_reg (mode2
, op2
);
10665 if (op1
== const0_rtx
)
10667 addr
= gen_rtx_MEM (tmode
, op2
);
10671 op1
= copy_to_mode_reg (mode1
, op1
);
10672 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
10675 pat
= GEN_FCN (icode
) (addr
, op0
);
10682 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
10684 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10685 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10686 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10687 rtx op0
= expand_normal (arg0
);
10688 rtx op1
= expand_normal (arg1
);
10689 rtx op2
= expand_normal (arg2
);
10691 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10692 enum machine_mode smode
= insn_data
[icode
].operand
[1].mode
;
10693 enum machine_mode mode1
= Pmode
;
10694 enum machine_mode mode2
= Pmode
;
10696 /* Invalid arguments. Bail before doing anything stoopid! */
10697 if (arg0
== error_mark_node
10698 || arg1
== error_mark_node
10699 || arg2
== error_mark_node
)
10702 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, smode
))
10703 op0
= copy_to_mode_reg (smode
, op0
);
10705 op2
= copy_to_mode_reg (mode2
, op2
);
10707 if (op1
== const0_rtx
)
10709 addr
= gen_rtx_MEM (tmode
, op2
);
10713 op1
= copy_to_mode_reg (mode1
, op1
);
10714 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
10717 pat
= GEN_FCN (icode
) (addr
, op0
);
10724 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10727 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10728 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10729 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10730 rtx op0
= expand_normal (arg0
);
10731 rtx op1
= expand_normal (arg1
);
10732 rtx op2
= expand_normal (arg2
);
10733 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10734 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10735 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10736 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
10738 if (icode
== CODE_FOR_nothing
)
10739 /* Builtin not supported on this processor. */
10742 /* If we got invalid arguments bail out before generating bad rtl. */
10743 if (arg0
== error_mark_node
10744 || arg1
== error_mark_node
10745 || arg2
== error_mark_node
)
10748 /* Check and prepare argument depending on the instruction code.
10750 Note that a switch statement instead of the sequence of tests
10751 would be incorrect as many of the CODE_FOR values could be
10752 CODE_FOR_nothing and that would yield multiple alternatives
10753 with identical values. We'd never reach here at runtime in
10755 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
10756 || icode
== CODE_FOR_altivec_vsldoi_v4si
10757 || icode
== CODE_FOR_altivec_vsldoi_v8hi
10758 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
10760 /* Only allow 4-bit unsigned literals. */
10762 if (TREE_CODE (arg2
) != INTEGER_CST
10763 || TREE_INT_CST_LOW (arg2
) & ~0xf)
10765 error ("argument 3 must be a 4-bit unsigned literal");
10769 else if (icode
== CODE_FOR_vsx_xxpermdi_v2df
10770 || icode
== CODE_FOR_vsx_xxpermdi_v2di
10771 || icode
== CODE_FOR_vsx_xxsldwi_v16qi
10772 || icode
== CODE_FOR_vsx_xxsldwi_v8hi
10773 || icode
== CODE_FOR_vsx_xxsldwi_v4si
10774 || icode
== CODE_FOR_vsx_xxsldwi_v4sf
10775 || icode
== CODE_FOR_vsx_xxsldwi_v2di
10776 || icode
== CODE_FOR_vsx_xxsldwi_v2df
)
10778 /* Only allow 2-bit unsigned literals. */
10780 if (TREE_CODE (arg2
) != INTEGER_CST
10781 || TREE_INT_CST_LOW (arg2
) & ~0x3)
10783 error ("argument 3 must be a 2-bit unsigned literal");
10787 else if (icode
== CODE_FOR_vsx_set_v2df
10788 || icode
== CODE_FOR_vsx_set_v2di
)
10790 /* Only allow 1-bit unsigned literals. */
10792 if (TREE_CODE (arg2
) != INTEGER_CST
10793 || TREE_INT_CST_LOW (arg2
) & ~0x1)
10795 error ("argument 3 must be a 1-bit unsigned literal");
10801 || GET_MODE (target
) != tmode
10802 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10803 target
= gen_reg_rtx (tmode
);
10805 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10806 op0
= copy_to_mode_reg (mode0
, op0
);
10807 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10808 op1
= copy_to_mode_reg (mode1
, op1
);
10809 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
10810 op2
= copy_to_mode_reg (mode2
, op2
);
10812 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
10813 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
10815 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
10823 /* Expand the lvx builtins. */
10825 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
10827 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10828 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10830 enum machine_mode tmode
, mode0
;
10832 enum insn_code icode
;
10836 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
10837 icode
= CODE_FOR_vector_altivec_load_v16qi
;
10839 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
10840 icode
= CODE_FOR_vector_altivec_load_v8hi
;
10842 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
10843 icode
= CODE_FOR_vector_altivec_load_v4si
;
10845 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
10846 icode
= CODE_FOR_vector_altivec_load_v4sf
;
10848 case ALTIVEC_BUILTIN_LD_INTERNAL_2df
:
10849 icode
= CODE_FOR_vector_altivec_load_v2df
;
10851 case ALTIVEC_BUILTIN_LD_INTERNAL_2di
:
10852 icode
= CODE_FOR_vector_altivec_load_v2di
;
10855 *expandedp
= false;
10861 arg0
= CALL_EXPR_ARG (exp
, 0);
10862 op0
= expand_normal (arg0
);
10863 tmode
= insn_data
[icode
].operand
[0].mode
;
10864 mode0
= insn_data
[icode
].operand
[1].mode
;
10867 || GET_MODE (target
) != tmode
10868 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10869 target
= gen_reg_rtx (tmode
);
10871 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10872 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
10874 pat
= GEN_FCN (icode
) (target
, op0
);
10881 /* Expand the stvx builtins. */
10883 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
10886 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10887 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10889 enum machine_mode mode0
, mode1
;
10891 enum insn_code icode
;
10895 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
10896 icode
= CODE_FOR_vector_altivec_store_v16qi
;
10898 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
10899 icode
= CODE_FOR_vector_altivec_store_v8hi
;
10901 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
10902 icode
= CODE_FOR_vector_altivec_store_v4si
;
10904 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
10905 icode
= CODE_FOR_vector_altivec_store_v4sf
;
10907 case ALTIVEC_BUILTIN_ST_INTERNAL_2df
:
10908 icode
= CODE_FOR_vector_altivec_store_v2df
;
10910 case ALTIVEC_BUILTIN_ST_INTERNAL_2di
:
10911 icode
= CODE_FOR_vector_altivec_store_v2di
;
10914 *expandedp
= false;
10918 arg0
= CALL_EXPR_ARG (exp
, 0);
10919 arg1
= CALL_EXPR_ARG (exp
, 1);
10920 op0
= expand_normal (arg0
);
10921 op1
= expand_normal (arg1
);
10922 mode0
= insn_data
[icode
].operand
[0].mode
;
10923 mode1
= insn_data
[icode
].operand
[1].mode
;
10925 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
10926 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
10927 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
10928 op1
= copy_to_mode_reg (mode1
, op1
);
10930 pat
= GEN_FCN (icode
) (op0
, op1
);
10938 /* Expand the dst builtins. */
10940 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
10943 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10944 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10945 tree arg0
, arg1
, arg2
;
10946 enum machine_mode mode0
, mode1
;
10947 rtx pat
, op0
, op1
, op2
;
10948 const struct builtin_description
*d
;
10951 *expandedp
= false;
10953 /* Handle DST variants. */
10955 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
10956 if (d
->code
== fcode
)
10958 arg0
= CALL_EXPR_ARG (exp
, 0);
10959 arg1
= CALL_EXPR_ARG (exp
, 1);
10960 arg2
= CALL_EXPR_ARG (exp
, 2);
10961 op0
= expand_normal (arg0
);
10962 op1
= expand_normal (arg1
);
10963 op2
= expand_normal (arg2
);
10964 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10965 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10967 /* Invalid arguments, bail out before generating bad rtl. */
10968 if (arg0
== error_mark_node
10969 || arg1
== error_mark_node
10970 || arg2
== error_mark_node
)
10975 if (TREE_CODE (arg2
) != INTEGER_CST
10976 || TREE_INT_CST_LOW (arg2
) & ~0x3)
10978 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
10982 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
10983 op0
= copy_to_mode_reg (Pmode
, op0
);
10984 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
10985 op1
= copy_to_mode_reg (mode1
, op1
);
10987 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
10997 /* Expand vec_init builtin. */
10999 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
11001 enum machine_mode tmode
= TYPE_MODE (type
);
11002 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
11003 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
11004 rtvec v
= rtvec_alloc (n_elt
);
11006 gcc_assert (VECTOR_MODE_P (tmode
));
11007 gcc_assert (n_elt
== call_expr_nargs (exp
));
11009 for (i
= 0; i
< n_elt
; ++i
)
11011 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
11012 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
11015 if (!target
|| !register_operand (target
, tmode
))
11016 target
= gen_reg_rtx (tmode
);
11018 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
11022 /* Return the integer constant in ARG. Constrain it to be in the range
11023 of the subparts of VEC_TYPE; issue an error if not. */
11026 get_element_number (tree vec_type
, tree arg
)
11028 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
11030 if (!host_integerp (arg
, 1)
11031 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
11033 error ("selector must be an integer constant in the range 0..%wi", max
);
11040 /* Expand vec_set builtin. */
11042 altivec_expand_vec_set_builtin (tree exp
)
11044 enum machine_mode tmode
, mode1
;
11045 tree arg0
, arg1
, arg2
;
11049 arg0
= CALL_EXPR_ARG (exp
, 0);
11050 arg1
= CALL_EXPR_ARG (exp
, 1);
11051 arg2
= CALL_EXPR_ARG (exp
, 2);
11053 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
11054 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11055 gcc_assert (VECTOR_MODE_P (tmode
));
11057 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
11058 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
11059 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
11061 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
11062 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
11064 op0
= force_reg (tmode
, op0
);
11065 op1
= force_reg (mode1
, op1
);
11067 rs6000_expand_vector_set (op0
, op1
, elt
);
11072 /* Expand vec_ext builtin. */
11074 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
11076 enum machine_mode tmode
, mode0
;
11081 arg0
= CALL_EXPR_ARG (exp
, 0);
11082 arg1
= CALL_EXPR_ARG (exp
, 1);
11084 op0
= expand_normal (arg0
);
11085 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
11087 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11088 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
11089 gcc_assert (VECTOR_MODE_P (mode0
));
11091 op0
= force_reg (mode0
, op0
);
11093 if (optimize
|| !target
|| !register_operand (target
, tmode
))
11094 target
= gen_reg_rtx (tmode
);
11096 rs6000_expand_vector_extract (target
, op0
, elt
);
11101 /* Expand the builtin in EXP and store the result in TARGET. Store
11102 true in *EXPANDEDP if we found a builtin to expand. */
11104 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11106 const struct builtin_description
*d
;
11107 const struct builtin_description_predicates
*dp
;
11109 enum insn_code icode
;
11110 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11113 enum machine_mode tmode
, mode0
;
11114 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11116 if ((fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11117 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
11118 || (fcode
>= VSX_BUILTIN_OVERLOADED_FIRST
11119 && fcode
<= VSX_BUILTIN_OVERLOADED_LAST
))
11122 error ("unresolved overload for Altivec builtin %qF", fndecl
);
11126 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
11130 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
11134 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
11142 case ALTIVEC_BUILTIN_STVX
:
11143 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si
, exp
);
11144 case ALTIVEC_BUILTIN_STVEBX
:
11145 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
11146 case ALTIVEC_BUILTIN_STVEHX
:
11147 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
11148 case ALTIVEC_BUILTIN_STVEWX
:
11149 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
11150 case ALTIVEC_BUILTIN_STVXL
:
11151 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
11153 case ALTIVEC_BUILTIN_STVLX
:
11154 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
11155 case ALTIVEC_BUILTIN_STVLXL
:
11156 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
11157 case ALTIVEC_BUILTIN_STVRX
:
11158 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
11159 case ALTIVEC_BUILTIN_STVRXL
:
11160 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
11162 case VSX_BUILTIN_STXVD2X_V2DF
:
11163 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df
, exp
);
11164 case VSX_BUILTIN_STXVD2X_V2DI
:
11165 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di
, exp
);
11166 case VSX_BUILTIN_STXVW4X_V4SF
:
11167 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf
, exp
);
11168 case VSX_BUILTIN_STXVW4X_V4SI
:
11169 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si
, exp
);
11170 case VSX_BUILTIN_STXVW4X_V8HI
:
11171 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi
, exp
);
11172 case VSX_BUILTIN_STXVW4X_V16QI
:
11173 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi
, exp
);
11175 case ALTIVEC_BUILTIN_MFVSCR
:
11176 icode
= CODE_FOR_altivec_mfvscr
;
11177 tmode
= insn_data
[icode
].operand
[0].mode
;
11180 || GET_MODE (target
) != tmode
11181 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11182 target
= gen_reg_rtx (tmode
);
11184 pat
= GEN_FCN (icode
) (target
);
11190 case ALTIVEC_BUILTIN_MTVSCR
:
11191 icode
= CODE_FOR_altivec_mtvscr
;
11192 arg0
= CALL_EXPR_ARG (exp
, 0);
11193 op0
= expand_normal (arg0
);
11194 mode0
= insn_data
[icode
].operand
[0].mode
;
11196 /* If we got invalid arguments bail out before generating bad rtl. */
11197 if (arg0
== error_mark_node
)
11200 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11201 op0
= copy_to_mode_reg (mode0
, op0
);
11203 pat
= GEN_FCN (icode
) (op0
);
11208 case ALTIVEC_BUILTIN_DSSALL
:
11209 emit_insn (gen_altivec_dssall ());
11212 case ALTIVEC_BUILTIN_DSS
:
11213 icode
= CODE_FOR_altivec_dss
;
11214 arg0
= CALL_EXPR_ARG (exp
, 0);
11216 op0
= expand_normal (arg0
);
11217 mode0
= insn_data
[icode
].operand
[0].mode
;
11219 /* If we got invalid arguments bail out before generating bad rtl. */
11220 if (arg0
== error_mark_node
)
11223 if (TREE_CODE (arg0
) != INTEGER_CST
11224 || TREE_INT_CST_LOW (arg0
) & ~0x3)
11226 error ("argument to dss must be a 2-bit unsigned literal");
11230 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11231 op0
= copy_to_mode_reg (mode0
, op0
);
11233 emit_insn (gen_altivec_dss (op0
));
11236 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
11237 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
11238 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
11239 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
11240 case VSX_BUILTIN_VEC_INIT_V2DF
:
11241 case VSX_BUILTIN_VEC_INIT_V2DI
:
11242 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
11244 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
11245 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
11246 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
11247 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
11248 case VSX_BUILTIN_VEC_SET_V2DF
:
11249 case VSX_BUILTIN_VEC_SET_V2DI
:
11250 return altivec_expand_vec_set_builtin (exp
);
11252 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
11253 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
11254 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
11255 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
11256 case VSX_BUILTIN_VEC_EXT_V2DF
:
11257 case VSX_BUILTIN_VEC_EXT_V2DI
:
11258 return altivec_expand_vec_ext_builtin (exp
, target
);
11262 /* Fall through. */
11265 /* Expand abs* operations. */
11267 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
11268 if (d
->code
== fcode
)
11269 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
11271 /* Expand the AltiVec predicates. */
11272 dp
= bdesc_altivec_preds
;
11273 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
11274 if (dp
->code
== fcode
)
11275 return altivec_expand_predicate_builtin (dp
->icode
, exp
, target
);
11277 /* LV* are funky. We initialized them differently. */
11280 case ALTIVEC_BUILTIN_LVSL
:
11281 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
11282 exp
, target
, false);
11283 case ALTIVEC_BUILTIN_LVSR
:
11284 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
11285 exp
, target
, false);
11286 case ALTIVEC_BUILTIN_LVEBX
:
11287 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
11288 exp
, target
, false);
11289 case ALTIVEC_BUILTIN_LVEHX
:
11290 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
11291 exp
, target
, false);
11292 case ALTIVEC_BUILTIN_LVEWX
:
11293 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
11294 exp
, target
, false);
11295 case ALTIVEC_BUILTIN_LVXL
:
11296 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
11297 exp
, target
, false);
11298 case ALTIVEC_BUILTIN_LVX
:
11299 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si
,
11300 exp
, target
, false);
11301 case ALTIVEC_BUILTIN_LVLX
:
11302 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
11303 exp
, target
, true);
11304 case ALTIVEC_BUILTIN_LVLXL
:
11305 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
11306 exp
, target
, true);
11307 case ALTIVEC_BUILTIN_LVRX
:
11308 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
11309 exp
, target
, true);
11310 case ALTIVEC_BUILTIN_LVRXL
:
11311 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
11312 exp
, target
, true);
11313 case VSX_BUILTIN_LXVD2X_V2DF
:
11314 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df
,
11315 exp
, target
, false);
11316 case VSX_BUILTIN_LXVD2X_V2DI
:
11317 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di
,
11318 exp
, target
, false);
11319 case VSX_BUILTIN_LXVW4X_V4SF
:
11320 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf
,
11321 exp
, target
, false);
11322 case VSX_BUILTIN_LXVW4X_V4SI
:
11323 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si
,
11324 exp
, target
, false);
11325 case VSX_BUILTIN_LXVW4X_V8HI
:
11326 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi
,
11327 exp
, target
, false);
11328 case VSX_BUILTIN_LXVW4X_V16QI
:
11329 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi
,
11330 exp
, target
, false);
11334 /* Fall through. */
11337 *expandedp
= false;
11341 /* Expand the builtin in EXP and store the result in TARGET. Store
11342 true in *EXPANDEDP if we found a builtin to expand. */
11344 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
11346 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11347 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11348 const struct builtin_description
*d
;
11355 case PAIRED_BUILTIN_STX
:
11356 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
11357 case PAIRED_BUILTIN_LX
:
11358 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
11361 /* Fall through. */
11364 /* Expand the paired predicates. */
11365 d
= bdesc_paired_preds
;
11366 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
11367 if (d
->code
== fcode
)
11368 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
11370 *expandedp
= false;
11374 /* Binops that need to be initialized manually, but can be expanded
11375 automagically by rs6000_expand_binop_builtin. */
11376 static struct builtin_description bdesc_2arg_spe
[] =
11378 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
11379 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
11380 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
11381 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
11382 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
11383 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
11384 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
11385 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
11386 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
11387 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
11388 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
11389 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
11390 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
11391 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
11392 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
11393 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
11394 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
11395 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
11396 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
11397 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
11398 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
11399 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
11402 /* Expand the builtin in EXP and store the result in TARGET. Store
11403 true in *EXPANDEDP if we found a builtin to expand.
11405 This expands the SPE builtins that are not simple unary and binary
11408 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11410 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11412 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11413 enum insn_code icode
;
11414 enum machine_mode tmode
, mode0
;
11416 struct builtin_description
*d
;
11421 /* Syntax check for a 5-bit unsigned immediate. */
11424 case SPE_BUILTIN_EVSTDD
:
11425 case SPE_BUILTIN_EVSTDH
:
11426 case SPE_BUILTIN_EVSTDW
:
11427 case SPE_BUILTIN_EVSTWHE
:
11428 case SPE_BUILTIN_EVSTWHO
:
11429 case SPE_BUILTIN_EVSTWWE
:
11430 case SPE_BUILTIN_EVSTWWO
:
11431 arg1
= CALL_EXPR_ARG (exp
, 2);
11432 if (TREE_CODE (arg1
) != INTEGER_CST
11433 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
11435 error ("argument 2 must be a 5-bit unsigned literal");
11443 /* The evsplat*i instructions are not quite generic. */
11446 case SPE_BUILTIN_EVSPLATFI
:
11447 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
11449 case SPE_BUILTIN_EVSPLATI
:
11450 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
11456 d
= (struct builtin_description
*) bdesc_2arg_spe
;
11457 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
11458 if (d
->code
== fcode
)
11459 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
11461 d
= (struct builtin_description
*) bdesc_spe_predicates
;
11462 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
11463 if (d
->code
== fcode
)
11464 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
11466 d
= (struct builtin_description
*) bdesc_spe_evsel
;
11467 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
11468 if (d
->code
== fcode
)
11469 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
11473 case SPE_BUILTIN_EVSTDDX
:
11474 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
11475 case SPE_BUILTIN_EVSTDHX
:
11476 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
11477 case SPE_BUILTIN_EVSTDWX
:
11478 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
11479 case SPE_BUILTIN_EVSTWHEX
:
11480 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
11481 case SPE_BUILTIN_EVSTWHOX
:
11482 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
11483 case SPE_BUILTIN_EVSTWWEX
:
11484 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
11485 case SPE_BUILTIN_EVSTWWOX
:
11486 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
11487 case SPE_BUILTIN_EVSTDD
:
11488 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
11489 case SPE_BUILTIN_EVSTDH
:
11490 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
11491 case SPE_BUILTIN_EVSTDW
:
11492 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
11493 case SPE_BUILTIN_EVSTWHE
:
11494 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
11495 case SPE_BUILTIN_EVSTWHO
:
11496 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
11497 case SPE_BUILTIN_EVSTWWE
:
11498 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
11499 case SPE_BUILTIN_EVSTWWO
:
11500 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
11501 case SPE_BUILTIN_MFSPEFSCR
:
11502 icode
= CODE_FOR_spe_mfspefscr
;
11503 tmode
= insn_data
[icode
].operand
[0].mode
;
11506 || GET_MODE (target
) != tmode
11507 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11508 target
= gen_reg_rtx (tmode
);
11510 pat
= GEN_FCN (icode
) (target
);
11515 case SPE_BUILTIN_MTSPEFSCR
:
11516 icode
= CODE_FOR_spe_mtspefscr
;
11517 arg0
= CALL_EXPR_ARG (exp
, 0);
11518 op0
= expand_normal (arg0
);
11519 mode0
= insn_data
[icode
].operand
[0].mode
;
11521 if (arg0
== error_mark_node
)
11524 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11525 op0
= copy_to_mode_reg (mode0
, op0
);
11527 pat
= GEN_FCN (icode
) (op0
);
11535 *expandedp
= false;
11540 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
11542 rtx pat
, scratch
, tmp
;
11543 tree form
= CALL_EXPR_ARG (exp
, 0);
11544 tree arg0
= CALL_EXPR_ARG (exp
, 1);
11545 tree arg1
= CALL_EXPR_ARG (exp
, 2);
11546 rtx op0
= expand_normal (arg0
);
11547 rtx op1
= expand_normal (arg1
);
11548 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11549 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11551 enum rtx_code code
;
11553 if (TREE_CODE (form
) != INTEGER_CST
)
11555 error ("argument 1 of __builtin_paired_predicate must be a constant");
11559 form_int
= TREE_INT_CST_LOW (form
);
11561 gcc_assert (mode0
== mode1
);
11563 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11567 || GET_MODE (target
) != SImode
11568 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
11569 target
= gen_reg_rtx (SImode
);
11570 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11571 op0
= copy_to_mode_reg (mode0
, op0
);
11572 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11573 op1
= copy_to_mode_reg (mode1
, op1
);
11575 scratch
= gen_reg_rtx (CCFPmode
);
11577 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11599 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
11602 error ("argument 1 of __builtin_paired_predicate is out of range");
11606 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
11607 emit_move_insn (target
, tmp
);
11612 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
11614 rtx pat
, scratch
, tmp
;
11615 tree form
= CALL_EXPR_ARG (exp
, 0);
11616 tree arg0
= CALL_EXPR_ARG (exp
, 1);
11617 tree arg1
= CALL_EXPR_ARG (exp
, 2);
11618 rtx op0
= expand_normal (arg0
);
11619 rtx op1
= expand_normal (arg1
);
11620 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11621 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11623 enum rtx_code code
;
11625 if (TREE_CODE (form
) != INTEGER_CST
)
11627 error ("argument 1 of __builtin_spe_predicate must be a constant");
11631 form_int
= TREE_INT_CST_LOW (form
);
11633 gcc_assert (mode0
== mode1
);
11635 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11639 || GET_MODE (target
) != SImode
11640 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
11641 target
= gen_reg_rtx (SImode
);
11643 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11644 op0
= copy_to_mode_reg (mode0
, op0
);
11645 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11646 op1
= copy_to_mode_reg (mode1
, op1
);
11648 scratch
= gen_reg_rtx (CCmode
);
11650 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11655 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11656 _lower_. We use one compare, but look in different bits of the
11657 CR for each variant.
11659 There are 2 elements in each SPE simd type (upper/lower). The CR
11660 bits are set as follows:
11662 BIT0 | BIT 1 | BIT 2 | BIT 3
11663 U | L | (U | L) | (U & L)
11665 So, for an "all" relationship, BIT 3 would be set.
11666 For an "any" relationship, BIT 2 would be set. Etc.
11668 Following traditional nomenclature, these bits map to:
11670 BIT0 | BIT 1 | BIT 2 | BIT 3
11673 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11678 /* All variant. OV bit. */
11680 /* We need to get to the OV bit, which is the ORDERED bit. We
11681 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11682 that's ugly and will make validate_condition_mode die.
11683 So let's just use another pattern. */
11684 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
11686 /* Any variant. EQ bit. */
11690 /* Upper variant. LT bit. */
11694 /* Lower variant. GT bit. */
11699 error ("argument 1 of __builtin_spe_predicate is out of range");
11703 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
11704 emit_move_insn (target
, tmp
);
11709 /* The evsel builtins look like this:
11711 e = __builtin_spe_evsel_OP (a, b, c, d);
11713 and work like this:
11715 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11716 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11720 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
11723 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11724 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11725 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11726 tree arg3
= CALL_EXPR_ARG (exp
, 3);
11727 rtx op0
= expand_normal (arg0
);
11728 rtx op1
= expand_normal (arg1
);
11729 rtx op2
= expand_normal (arg2
);
11730 rtx op3
= expand_normal (arg3
);
11731 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11732 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11734 gcc_assert (mode0
== mode1
);
11736 if (arg0
== error_mark_node
|| arg1
== error_mark_node
11737 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
11741 || GET_MODE (target
) != mode0
11742 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
11743 target
= gen_reg_rtx (mode0
);
11745 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11746 op0
= copy_to_mode_reg (mode0
, op0
);
11747 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
11748 op1
= copy_to_mode_reg (mode0
, op1
);
11749 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
11750 op2
= copy_to_mode_reg (mode0
, op2
);
11751 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
11752 op3
= copy_to_mode_reg (mode0
, op3
);
11754 /* Generate the compare. */
11755 scratch
= gen_reg_rtx (CCmode
);
11756 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11761 if (mode0
== V2SImode
)
11762 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
11764 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
11769 /* Expand an expression EXP that calls a built-in function,
11770 with result going to TARGET if that's convenient
11771 (and in mode MODE if that's convenient).
11772 SUBTARGET may be used as the target for computing one of EXP's operands.
11773 IGNORE is nonzero if the value is to be ignored. */
11776 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
11777 enum machine_mode mode ATTRIBUTE_UNUSED
,
11778 int ignore ATTRIBUTE_UNUSED
)
11780 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11781 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11782 const struct builtin_description
*d
;
11789 case RS6000_BUILTIN_RECIP
:
11790 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
11792 case RS6000_BUILTIN_RECIPF
:
11793 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
11795 case RS6000_BUILTIN_RSQRTF
:
11796 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
11798 case RS6000_BUILTIN_RSQRT
:
11799 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2
, exp
, target
);
11801 case RS6000_BUILTIN_BSWAP_HI
:
11802 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2
, exp
, target
);
11804 case POWER7_BUILTIN_BPERMD
:
11805 return rs6000_expand_binop_builtin (((TARGET_64BIT
)
11806 ? CODE_FOR_bpermd_di
11807 : CODE_FOR_bpermd_si
), exp
, target
);
11809 case ALTIVEC_BUILTIN_MASK_FOR_LOAD
:
11810 case ALTIVEC_BUILTIN_MASK_FOR_STORE
:
11812 int icode
= (int) CODE_FOR_altivec_lvsr
;
11813 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11814 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
11818 gcc_assert (TARGET_ALTIVEC
);
11820 arg
= CALL_EXPR_ARG (exp
, 0);
11821 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg
)));
11822 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
11823 addr
= memory_address (mode
, op
);
11824 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
11828 /* For the load case need to negate the address. */
11829 op
= gen_reg_rtx (GET_MODE (addr
));
11830 emit_insn (gen_rtx_SET (VOIDmode
, op
,
11831 gen_rtx_NEG (GET_MODE (addr
), addr
)));
11833 op
= gen_rtx_MEM (mode
, op
);
11836 || GET_MODE (target
) != tmode
11837 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11838 target
= gen_reg_rtx (tmode
);
11840 /*pat = gen_altivec_lvsr (target, op);*/
11841 pat
= GEN_FCN (icode
) (target
, op
);
11849 case ALTIVEC_BUILTIN_VCFUX
:
11850 case ALTIVEC_BUILTIN_VCFSX
:
11851 case ALTIVEC_BUILTIN_VCTUXS
:
11852 case ALTIVEC_BUILTIN_VCTSXS
:
11853 /* FIXME: There's got to be a nicer way to handle this case than
11854 constructing a new CALL_EXPR. */
11855 if (call_expr_nargs (exp
) == 1)
11857 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
11858 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
11866 if (TARGET_ALTIVEC
)
11868 ret
= altivec_expand_builtin (exp
, target
, &success
);
11875 ret
= spe_expand_builtin (exp
, target
, &success
);
11880 if (TARGET_PAIRED_FLOAT
)
11882 ret
= paired_expand_builtin (exp
, target
, &success
);
11888 gcc_assert (TARGET_ALTIVEC
|| TARGET_VSX
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
11890 /* Handle simple unary operations. */
11891 d
= (struct builtin_description
*) bdesc_1arg
;
11892 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
11893 if (d
->code
== fcode
)
11894 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
11896 /* Handle simple binary operations. */
11897 d
= (struct builtin_description
*) bdesc_2arg
;
11898 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
11899 if (d
->code
== fcode
)
11900 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
11902 /* Handle simple ternary operations. */
11904 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
11905 if (d
->code
== fcode
)
11906 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
11908 gcc_unreachable ();
11912 rs6000_init_builtins (void)
11917 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
11918 V2SF_type_node
= build_vector_type (float_type_node
, 2);
11919 V2DI_type_node
= build_vector_type (intDI_type_node
, 2);
11920 V2DF_type_node
= build_vector_type (double_type_node
, 2);
11921 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
11922 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
11923 V4SF_type_node
= build_vector_type (float_type_node
, 4);
11924 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
11925 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
11927 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
11928 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
11929 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
11930 unsigned_V2DI_type_node
= build_vector_type (unsigned_intDI_type_node
, 2);
11932 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
11933 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
11934 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
11935 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
11937 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11938 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11939 'vector unsigned short'. */
11941 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
11942 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
11943 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
11944 bool_long_type_node
= build_distinct_type_copy (unsigned_intDI_type_node
);
11945 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
11947 long_integer_type_internal_node
= long_integer_type_node
;
11948 long_unsigned_type_internal_node
= long_unsigned_type_node
;
11949 long_long_integer_type_internal_node
= long_long_integer_type_node
;
11950 long_long_unsigned_type_internal_node
= long_long_unsigned_type_node
;
11951 intQI_type_internal_node
= intQI_type_node
;
11952 uintQI_type_internal_node
= unsigned_intQI_type_node
;
11953 intHI_type_internal_node
= intHI_type_node
;
11954 uintHI_type_internal_node
= unsigned_intHI_type_node
;
11955 intSI_type_internal_node
= intSI_type_node
;
11956 uintSI_type_internal_node
= unsigned_intSI_type_node
;
11957 intDI_type_internal_node
= intDI_type_node
;
11958 uintDI_type_internal_node
= unsigned_intDI_type_node
;
11959 float_type_internal_node
= float_type_node
;
11960 double_type_internal_node
= double_type_node
;
11961 void_type_internal_node
= void_type_node
;
11963 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11965 builtin_mode_to_type
[QImode
][0] = integer_type_node
;
11966 builtin_mode_to_type
[HImode
][0] = integer_type_node
;
11967 builtin_mode_to_type
[SImode
][0] = intSI_type_node
;
11968 builtin_mode_to_type
[SImode
][1] = unsigned_intSI_type_node
;
11969 builtin_mode_to_type
[DImode
][0] = intDI_type_node
;
11970 builtin_mode_to_type
[DImode
][1] = unsigned_intDI_type_node
;
11971 builtin_mode_to_type
[SFmode
][0] = float_type_node
;
11972 builtin_mode_to_type
[DFmode
][0] = double_type_node
;
11973 builtin_mode_to_type
[V2SImode
][0] = V2SI_type_node
;
11974 builtin_mode_to_type
[V2SFmode
][0] = V2SF_type_node
;
11975 builtin_mode_to_type
[V2DImode
][0] = V2DI_type_node
;
11976 builtin_mode_to_type
[V2DImode
][1] = unsigned_V2DI_type_node
;
11977 builtin_mode_to_type
[V2DFmode
][0] = V2DF_type_node
;
11978 builtin_mode_to_type
[V4HImode
][0] = V4HI_type_node
;
11979 builtin_mode_to_type
[V4SImode
][0] = V4SI_type_node
;
11980 builtin_mode_to_type
[V4SImode
][1] = unsigned_V4SI_type_node
;
11981 builtin_mode_to_type
[V4SFmode
][0] = V4SF_type_node
;
11982 builtin_mode_to_type
[V8HImode
][0] = V8HI_type_node
;
11983 builtin_mode_to_type
[V8HImode
][1] = unsigned_V8HI_type_node
;
11984 builtin_mode_to_type
[V16QImode
][0] = V16QI_type_node
;
11985 builtin_mode_to_type
[V16QImode
][1] = unsigned_V16QI_type_node
;
11987 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
11988 get_identifier ("__bool char"),
11989 bool_char_type_node
);
11990 TYPE_NAME (bool_char_type_node
) = tdecl
;
11991 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11992 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
11993 get_identifier ("__bool short"),
11994 bool_short_type_node
);
11995 TYPE_NAME (bool_short_type_node
) = tdecl
;
11996 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11997 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
11998 get_identifier ("__bool int"),
11999 bool_int_type_node
);
12000 TYPE_NAME (bool_int_type_node
) = tdecl
;
12001 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12002 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
, get_identifier ("__pixel"),
12004 TYPE_NAME (pixel_type_node
) = tdecl
;
12005 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12007 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
12008 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
12009 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
12010 bool_V2DI_type_node
= build_vector_type (bool_long_type_node
, 2);
12011 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
12013 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12014 get_identifier ("__vector unsigned char"),
12015 unsigned_V16QI_type_node
);
12016 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
12017 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12018 tdecl
= build_decl (BUILTINS_LOCATION
,
12019 TYPE_DECL
, get_identifier ("__vector signed char"),
12021 TYPE_NAME (V16QI_type_node
) = tdecl
;
12022 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12023 tdecl
= build_decl (BUILTINS_LOCATION
,
12024 TYPE_DECL
, get_identifier ("__vector __bool char"),
12025 bool_V16QI_type_node
);
12026 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
12027 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12029 tdecl
= build_decl (BUILTINS_LOCATION
,
12030 TYPE_DECL
, get_identifier ("__vector unsigned short"),
12031 unsigned_V8HI_type_node
);
12032 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
12033 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12034 tdecl
= build_decl (BUILTINS_LOCATION
,
12035 TYPE_DECL
, get_identifier ("__vector signed short"),
12037 TYPE_NAME (V8HI_type_node
) = tdecl
;
12038 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12039 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12040 get_identifier ("__vector __bool short"),
12041 bool_V8HI_type_node
);
12042 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
12043 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12045 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12046 get_identifier ("__vector unsigned int"),
12047 unsigned_V4SI_type_node
);
12048 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
12049 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12050 tdecl
= build_decl (BUILTINS_LOCATION
,
12051 TYPE_DECL
, get_identifier ("__vector signed int"),
12053 TYPE_NAME (V4SI_type_node
) = tdecl
;
12054 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12055 tdecl
= build_decl (BUILTINS_LOCATION
,
12056 TYPE_DECL
, get_identifier ("__vector __bool int"),
12057 bool_V4SI_type_node
);
12058 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
12059 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12061 tdecl
= build_decl (BUILTINS_LOCATION
,
12062 TYPE_DECL
, get_identifier ("__vector float"),
12064 TYPE_NAME (V4SF_type_node
) = tdecl
;
12065 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12066 tdecl
= build_decl (BUILTINS_LOCATION
,
12067 TYPE_DECL
, get_identifier ("__vector __pixel"),
12068 pixel_V8HI_type_node
);
12069 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
12070 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12074 tdecl
= build_decl (BUILTINS_LOCATION
,
12075 TYPE_DECL
, get_identifier ("__vector double"),
12077 TYPE_NAME (V2DF_type_node
) = tdecl
;
12078 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12080 tdecl
= build_decl (BUILTINS_LOCATION
,
12081 TYPE_DECL
, get_identifier ("__vector long"),
12083 TYPE_NAME (V2DI_type_node
) = tdecl
;
12084 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12086 tdecl
= build_decl (BUILTINS_LOCATION
,
12087 TYPE_DECL
, get_identifier ("__vector unsigned long"),
12088 unsigned_V2DI_type_node
);
12089 TYPE_NAME (unsigned_V2DI_type_node
) = tdecl
;
12090 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12092 tdecl
= build_decl (BUILTINS_LOCATION
,
12093 TYPE_DECL
, get_identifier ("__vector __bool long"),
12094 bool_V2DI_type_node
);
12095 TYPE_NAME (bool_V2DI_type_node
) = tdecl
;
12096 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12099 if (TARGET_PAIRED_FLOAT
)
12100 paired_init_builtins ();
12102 spe_init_builtins ();
12103 if (TARGET_ALTIVEC
)
12104 altivec_init_builtins ();
12105 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
|| TARGET_VSX
)
12106 rs6000_common_init_builtins ();
12109 ftype
= builtin_function_type (DFmode
, DFmode
, DFmode
, VOIDmode
,
12110 RS6000_BUILTIN_RECIP
,
12111 "__builtin_recipdiv");
12112 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
12113 RS6000_BUILTIN_RECIP
);
12117 ftype
= builtin_function_type (SFmode
, SFmode
, SFmode
, VOIDmode
,
12118 RS6000_BUILTIN_RECIPF
,
12119 "__builtin_recipdivf");
12120 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
12121 RS6000_BUILTIN_RECIPF
);
12123 if (TARGET_FRSQRTE
)
12125 ftype
= builtin_function_type (DFmode
, DFmode
, VOIDmode
, VOIDmode
,
12126 RS6000_BUILTIN_RSQRT
,
12127 "__builtin_rsqrt");
12128 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrt", ftype
,
12129 RS6000_BUILTIN_RSQRT
);
12131 if (TARGET_FRSQRTES
)
12133 ftype
= builtin_function_type (SFmode
, SFmode
, VOIDmode
, VOIDmode
,
12134 RS6000_BUILTIN_RSQRTF
,
12135 "__builtin_rsqrtf");
12136 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
12137 RS6000_BUILTIN_RSQRTF
);
12139 if (TARGET_POPCNTD
)
12141 enum machine_mode mode
= (TARGET_64BIT
) ? DImode
: SImode
;
12142 tree ftype
= builtin_function_type (mode
, mode
, mode
, VOIDmode
,
12143 POWER7_BUILTIN_BPERMD
,
12144 "__builtin_bpermd");
12145 def_builtin (MASK_POPCNTD
, "__builtin_bpermd", ftype
,
12146 POWER7_BUILTIN_BPERMD
);
12148 if (TARGET_POWERPC
)
12150 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12151 tree ftype
= build_function_type_list (unsigned_intHI_type_node
,
12152 unsigned_intHI_type_node
,
12154 def_builtin (MASK_POWERPC
, "__builtin_bswap16", ftype
,
12155 RS6000_BUILTIN_BSWAP_HI
);
12159 /* AIX libm provides clog as __clog. */
12160 if ((tdecl
= builtin_decl_explicit (BUILT_IN_CLOG
)) != NULL_TREE
)
12161 set_user_assembler_name (tdecl
, "__clog");
12164 #ifdef SUBTARGET_INIT_BUILTINS
12165 SUBTARGET_INIT_BUILTINS
;
12169 /* Returns the rs6000 builtin decl for CODE. */
12172 rs6000_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
12174 if (code
>= RS6000_BUILTIN_COUNT
)
12175 return error_mark_node
;
12177 return rs6000_builtin_decls
[code
];
12180 /* Search through a set of builtins and enable the mask bits.
12181 DESC is an array of builtins.
12182 SIZE is the total number of builtins.
12183 START is the builtin enum at which to start.
12184 END is the builtin enum at which to end. */
12186 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
12187 enum rs6000_builtins start
,
12188 enum rs6000_builtins end
)
12192 for (i
= 0; i
< size
; ++i
)
12193 if (desc
[i
].code
== start
)
12199 for (; i
< size
; ++i
)
12201 /* Flip all the bits on. */
12202 desc
[i
].mask
= target_flags
;
12203 if (desc
[i
].code
== end
)
12209 spe_init_builtins (void)
12211 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
12212 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
12213 struct builtin_description
*d
;
12216 tree v2si_ftype_4_v2si
12217 = build_function_type_list (opaque_V2SI_type_node
,
12218 opaque_V2SI_type_node
,
12219 opaque_V2SI_type_node
,
12220 opaque_V2SI_type_node
,
12221 opaque_V2SI_type_node
,
12224 tree v2sf_ftype_4_v2sf
12225 = build_function_type_list (opaque_V2SF_type_node
,
12226 opaque_V2SF_type_node
,
12227 opaque_V2SF_type_node
,
12228 opaque_V2SF_type_node
,
12229 opaque_V2SF_type_node
,
12232 tree int_ftype_int_v2si_v2si
12233 = build_function_type_list (integer_type_node
,
12235 opaque_V2SI_type_node
,
12236 opaque_V2SI_type_node
,
12239 tree int_ftype_int_v2sf_v2sf
12240 = build_function_type_list (integer_type_node
,
12242 opaque_V2SF_type_node
,
12243 opaque_V2SF_type_node
,
12246 tree void_ftype_v2si_puint_int
12247 = build_function_type_list (void_type_node
,
12248 opaque_V2SI_type_node
,
12253 tree void_ftype_v2si_puint_char
12254 = build_function_type_list (void_type_node
,
12255 opaque_V2SI_type_node
,
12260 tree void_ftype_v2si_pv2si_int
12261 = build_function_type_list (void_type_node
,
12262 opaque_V2SI_type_node
,
12263 opaque_p_V2SI_type_node
,
12267 tree void_ftype_v2si_pv2si_char
12268 = build_function_type_list (void_type_node
,
12269 opaque_V2SI_type_node
,
12270 opaque_p_V2SI_type_node
,
12274 tree void_ftype_int
12275 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
12277 tree int_ftype_void
12278 = build_function_type_list (integer_type_node
, NULL_TREE
);
12280 tree v2si_ftype_pv2si_int
12281 = build_function_type_list (opaque_V2SI_type_node
,
12282 opaque_p_V2SI_type_node
,
12286 tree v2si_ftype_puint_int
12287 = build_function_type_list (opaque_V2SI_type_node
,
12292 tree v2si_ftype_pushort_int
12293 = build_function_type_list (opaque_V2SI_type_node
,
12298 tree v2si_ftype_signed_char
12299 = build_function_type_list (opaque_V2SI_type_node
,
12300 signed_char_type_node
,
12303 /* The initialization of the simple binary and unary builtins is
12304 done in rs6000_common_init_builtins, but we have to enable the
12305 mask bits here manually because we have run out of `target_flags'
12306 bits. We really need to redesign this mask business. */
12308 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
12309 ARRAY_SIZE (bdesc_2arg
),
12310 SPE_BUILTIN_EVADDW
,
12311 SPE_BUILTIN_EVXOR
);
12312 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
12313 ARRAY_SIZE (bdesc_1arg
),
12315 SPE_BUILTIN_EVSUBFUSIAAW
);
12316 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
12317 ARRAY_SIZE (bdesc_spe_predicates
),
12318 SPE_BUILTIN_EVCMPEQ
,
12319 SPE_BUILTIN_EVFSTSTLT
);
12320 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
12321 ARRAY_SIZE (bdesc_spe_evsel
),
12322 SPE_BUILTIN_EVSEL_CMPGTS
,
12323 SPE_BUILTIN_EVSEL_FSTSTEQ
);
12325 (*lang_hooks
.decls
.pushdecl
)
12326 (build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12327 get_identifier ("__ev64_opaque__"),
12328 opaque_V2SI_type_node
));
12330 /* Initialize irregular SPE builtins. */
12332 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
12333 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
12334 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
12335 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
12336 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
12337 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
12338 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
12339 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
12340 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
12341 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
12342 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
12343 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
12344 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
12345 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
12346 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
12347 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
12348 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
12349 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
12352 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
12353 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
12354 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
12355 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
12356 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
12357 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
12358 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
12359 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
12360 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
12361 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
12362 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
12363 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
12364 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
12365 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
12366 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
12367 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
12368 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
12369 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
12370 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
12371 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
12372 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
12373 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
12376 d
= (struct builtin_description
*) bdesc_spe_predicates
;
12377 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
12381 switch (insn_data
[d
->icode
].operand
[1].mode
)
12384 type
= int_ftype_int_v2si_v2si
;
12387 type
= int_ftype_int_v2sf_v2sf
;
12390 gcc_unreachable ();
12393 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12396 /* Evsel predicates. */
12397 d
= (struct builtin_description
*) bdesc_spe_evsel
;
12398 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
12402 switch (insn_data
[d
->icode
].operand
[1].mode
)
12405 type
= v2si_ftype_4_v2si
;
12408 type
= v2sf_ftype_4_v2sf
;
12411 gcc_unreachable ();
12414 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12419 paired_init_builtins (void)
12421 const struct builtin_description
*d
;
12424 tree int_ftype_int_v2sf_v2sf
12425 = build_function_type_list (integer_type_node
,
12430 tree pcfloat_type_node
=
12431 build_pointer_type (build_qualified_type
12432 (float_type_node
, TYPE_QUAL_CONST
));
12434 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
12435 long_integer_type_node
,
12438 tree void_ftype_v2sf_long_pcfloat
=
12439 build_function_type_list (void_type_node
,
12441 long_integer_type_node
,
12446 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
12447 PAIRED_BUILTIN_LX
);
12450 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
12451 PAIRED_BUILTIN_STX
);
12454 d
= bdesc_paired_preds
;
12455 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
12459 switch (insn_data
[d
->icode
].operand
[1].mode
)
12462 type
= int_ftype_int_v2sf_v2sf
;
12465 gcc_unreachable ();
12468 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12473 altivec_init_builtins (void)
12475 const struct builtin_description
*d
;
12476 const struct builtin_description_predicates
*dp
;
12480 tree pvoid_type_node
= build_pointer_type (void_type_node
);
12482 tree pcvoid_type_node
12483 = build_pointer_type (build_qualified_type (void_type_node
,
12486 tree int_ftype_opaque
12487 = build_function_type_list (integer_type_node
,
12488 opaque_V4SI_type_node
, NULL_TREE
);
12489 tree opaque_ftype_opaque
12490 = build_function_type_list (integer_type_node
, NULL_TREE
);
12491 tree opaque_ftype_opaque_int
12492 = build_function_type_list (opaque_V4SI_type_node
,
12493 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
12494 tree opaque_ftype_opaque_opaque_int
12495 = build_function_type_list (opaque_V4SI_type_node
,
12496 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
12497 integer_type_node
, NULL_TREE
);
12498 tree int_ftype_int_opaque_opaque
12499 = build_function_type_list (integer_type_node
,
12500 integer_type_node
, opaque_V4SI_type_node
,
12501 opaque_V4SI_type_node
, NULL_TREE
);
12502 tree int_ftype_int_v4si_v4si
12503 = build_function_type_list (integer_type_node
,
12504 integer_type_node
, V4SI_type_node
,
12505 V4SI_type_node
, NULL_TREE
);
12506 tree void_ftype_v4si
12507 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
12508 tree v8hi_ftype_void
12509 = build_function_type_list (V8HI_type_node
, NULL_TREE
);
12510 tree void_ftype_void
12511 = build_function_type_list (void_type_node
, NULL_TREE
);
12512 tree void_ftype_int
12513 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
12515 tree opaque_ftype_long_pcvoid
12516 = build_function_type_list (opaque_V4SI_type_node
,
12517 long_integer_type_node
, pcvoid_type_node
,
12519 tree v16qi_ftype_long_pcvoid
12520 = build_function_type_list (V16QI_type_node
,
12521 long_integer_type_node
, pcvoid_type_node
,
12523 tree v8hi_ftype_long_pcvoid
12524 = build_function_type_list (V8HI_type_node
,
12525 long_integer_type_node
, pcvoid_type_node
,
12527 tree v4si_ftype_long_pcvoid
12528 = build_function_type_list (V4SI_type_node
,
12529 long_integer_type_node
, pcvoid_type_node
,
12531 tree v4sf_ftype_long_pcvoid
12532 = build_function_type_list (V4SF_type_node
,
12533 long_integer_type_node
, pcvoid_type_node
,
12535 tree v2df_ftype_long_pcvoid
12536 = build_function_type_list (V2DF_type_node
,
12537 long_integer_type_node
, pcvoid_type_node
,
12539 tree v2di_ftype_long_pcvoid
12540 = build_function_type_list (V2DI_type_node
,
12541 long_integer_type_node
, pcvoid_type_node
,
12544 tree void_ftype_opaque_long_pvoid
12545 = build_function_type_list (void_type_node
,
12546 opaque_V4SI_type_node
, long_integer_type_node
,
12547 pvoid_type_node
, NULL_TREE
);
12548 tree void_ftype_v4si_long_pvoid
12549 = build_function_type_list (void_type_node
,
12550 V4SI_type_node
, long_integer_type_node
,
12551 pvoid_type_node
, NULL_TREE
);
12552 tree void_ftype_v16qi_long_pvoid
12553 = build_function_type_list (void_type_node
,
12554 V16QI_type_node
, long_integer_type_node
,
12555 pvoid_type_node
, NULL_TREE
);
12556 tree void_ftype_v8hi_long_pvoid
12557 = build_function_type_list (void_type_node
,
12558 V8HI_type_node
, long_integer_type_node
,
12559 pvoid_type_node
, NULL_TREE
);
12560 tree void_ftype_v4sf_long_pvoid
12561 = build_function_type_list (void_type_node
,
12562 V4SF_type_node
, long_integer_type_node
,
12563 pvoid_type_node
, NULL_TREE
);
12564 tree void_ftype_v2df_long_pvoid
12565 = build_function_type_list (void_type_node
,
12566 V2DF_type_node
, long_integer_type_node
,
12567 pvoid_type_node
, NULL_TREE
);
12568 tree void_ftype_v2di_long_pvoid
12569 = build_function_type_list (void_type_node
,
12570 V2DI_type_node
, long_integer_type_node
,
12571 pvoid_type_node
, NULL_TREE
);
12572 tree int_ftype_int_v8hi_v8hi
12573 = build_function_type_list (integer_type_node
,
12574 integer_type_node
, V8HI_type_node
,
12575 V8HI_type_node
, NULL_TREE
);
12576 tree int_ftype_int_v16qi_v16qi
12577 = build_function_type_list (integer_type_node
,
12578 integer_type_node
, V16QI_type_node
,
12579 V16QI_type_node
, NULL_TREE
);
12580 tree int_ftype_int_v4sf_v4sf
12581 = build_function_type_list (integer_type_node
,
12582 integer_type_node
, V4SF_type_node
,
12583 V4SF_type_node
, NULL_TREE
);
12584 tree int_ftype_int_v2df_v2df
12585 = build_function_type_list (integer_type_node
,
12586 integer_type_node
, V2DF_type_node
,
12587 V2DF_type_node
, NULL_TREE
);
12588 tree v4si_ftype_v4si
12589 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
12590 tree v8hi_ftype_v8hi
12591 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
12592 tree v16qi_ftype_v16qi
12593 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
12594 tree v4sf_ftype_v4sf
12595 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
12596 tree v2df_ftype_v2df
12597 = build_function_type_list (V2DF_type_node
, V2DF_type_node
, NULL_TREE
);
12598 tree void_ftype_pcvoid_int_int
12599 = build_function_type_list (void_type_node
,
12600 pcvoid_type_node
, integer_type_node
,
12601 integer_type_node
, NULL_TREE
);
12603 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
12604 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
12605 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
12606 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
12607 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
12608 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
12609 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
12610 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
12611 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
12612 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
12613 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
12614 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
12615 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
12616 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
12617 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
12618 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
12619 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
12620 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
12621 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
12622 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
12623 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
12624 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
12625 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
12626 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
12627 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
12628 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
12629 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
12630 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
12631 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
12632 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
12634 def_builtin (MASK_VSX
, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid
,
12635 VSX_BUILTIN_LXVD2X_V2DF
);
12636 def_builtin (MASK_VSX
, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid
,
12637 VSX_BUILTIN_LXVD2X_V2DI
);
12638 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid
,
12639 VSX_BUILTIN_LXVW4X_V4SF
);
12640 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid
,
12641 VSX_BUILTIN_LXVW4X_V4SI
);
12642 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v8hi",
12643 v8hi_ftype_long_pcvoid
, VSX_BUILTIN_LXVW4X_V8HI
);
12644 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v16qi",
12645 v16qi_ftype_long_pcvoid
, VSX_BUILTIN_LXVW4X_V16QI
);
12646 def_builtin (MASK_VSX
, "__builtin_vsx_stxvd2x_v2df",
12647 void_ftype_v2df_long_pvoid
, VSX_BUILTIN_STXVD2X_V2DF
);
12648 def_builtin (MASK_VSX
, "__builtin_vsx_stxvd2x_v2di",
12649 void_ftype_v2di_long_pvoid
, VSX_BUILTIN_STXVD2X_V2DI
);
12650 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v4sf",
12651 void_ftype_v4sf_long_pvoid
, VSX_BUILTIN_STXVW4X_V4SF
);
12652 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v4si",
12653 void_ftype_v4si_long_pvoid
, VSX_BUILTIN_STXVW4X_V4SI
);
12654 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v8hi",
12655 void_ftype_v8hi_long_pvoid
, VSX_BUILTIN_STXVW4X_V8HI
);
12656 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v16qi",
12657 void_ftype_v16qi_long_pvoid
, VSX_BUILTIN_STXVW4X_V16QI
);
12658 def_builtin (MASK_VSX
, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid
,
12659 VSX_BUILTIN_VEC_LD
);
12660 def_builtin (MASK_VSX
, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid
,
12661 VSX_BUILTIN_VEC_ST
);
12663 if (rs6000_cpu
== PROCESSOR_CELL
)
12665 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
12666 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
12667 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
12668 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
12670 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
12671 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
12672 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
12673 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
12675 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
12676 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
12677 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
12678 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
12680 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
12681 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
12682 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
12683 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
12685 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
12686 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
12687 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
12689 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
12690 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
12691 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
12692 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
12693 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
12694 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
12695 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
12696 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
12697 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
12698 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
12699 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
12700 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
12702 /* Add the DST variants. */
12704 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
12705 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
12707 /* Initialize the predicates. */
12708 dp
= bdesc_altivec_preds
;
12709 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
12711 enum machine_mode mode1
;
12713 bool is_overloaded
= ((dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12714 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
12715 || (dp
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
12716 && dp
->code
<= VSX_BUILTIN_OVERLOADED_LAST
));
12721 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
12726 type
= int_ftype_int_opaque_opaque
;
12729 type
= int_ftype_int_v4si_v4si
;
12732 type
= int_ftype_int_v8hi_v8hi
;
12735 type
= int_ftype_int_v16qi_v16qi
;
12738 type
= int_ftype_int_v4sf_v4sf
;
12741 type
= int_ftype_int_v2df_v2df
;
12744 gcc_unreachable ();
12747 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
12750 /* Initialize the abs* operators. */
12752 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
12754 enum machine_mode mode0
;
12757 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
12762 type
= v4si_ftype_v4si
;
12765 type
= v8hi_ftype_v8hi
;
12768 type
= v16qi_ftype_v16qi
;
12771 type
= v4sf_ftype_v4sf
;
12774 type
= v2df_ftype_v2df
;
12777 gcc_unreachable ();
12780 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12783 if (TARGET_ALTIVEC
)
12787 /* Initialize target builtin that implements
12788 targetm.vectorize.builtin_mask_for_load. */
12790 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
12791 v16qi_ftype_long_pcvoid
,
12792 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
12793 BUILT_IN_MD
, NULL
, NULL_TREE
);
12794 TREE_READONLY (decl
) = 1;
12795 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12796 altivec_builtin_mask_for_load
= decl
;
12799 /* Access to the vec_init patterns. */
12800 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
12801 integer_type_node
, integer_type_node
,
12802 integer_type_node
, NULL_TREE
);
12803 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
12804 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
12806 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
12807 short_integer_type_node
,
12808 short_integer_type_node
,
12809 short_integer_type_node
,
12810 short_integer_type_node
,
12811 short_integer_type_node
,
12812 short_integer_type_node
,
12813 short_integer_type_node
, NULL_TREE
);
12814 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
12815 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
12817 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
12818 char_type_node
, char_type_node
,
12819 char_type_node
, char_type_node
,
12820 char_type_node
, char_type_node
,
12821 char_type_node
, char_type_node
,
12822 char_type_node
, char_type_node
,
12823 char_type_node
, char_type_node
,
12824 char_type_node
, char_type_node
,
12825 char_type_node
, NULL_TREE
);
12826 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
12827 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
12829 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
12830 float_type_node
, float_type_node
,
12831 float_type_node
, NULL_TREE
);
12832 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
12833 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
12837 ftype
= build_function_type_list (V2DF_type_node
, double_type_node
,
12838 double_type_node
, NULL_TREE
);
12839 def_builtin (MASK_VSX
, "__builtin_vec_init_v2df", ftype
,
12840 VSX_BUILTIN_VEC_INIT_V2DF
);
12842 ftype
= build_function_type_list (V2DI_type_node
, intDI_type_node
,
12843 intDI_type_node
, NULL_TREE
);
12844 def_builtin (MASK_VSX
, "__builtin_vec_init_v2di", ftype
,
12845 VSX_BUILTIN_VEC_INIT_V2DI
);
12848 /* Access to the vec_set patterns. */
12849 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
12851 integer_type_node
, NULL_TREE
);
12852 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
12853 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
12855 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
12857 integer_type_node
, NULL_TREE
);
12858 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
12859 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
12861 ftype
= build_function_type_list (V16QI_type_node
, V16QI_type_node
,
12863 integer_type_node
, NULL_TREE
);
12864 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
12865 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
12867 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
12869 integer_type_node
, NULL_TREE
);
12870 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_set_v4sf", ftype
,
12871 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
12875 ftype
= build_function_type_list (V2DF_type_node
, V2DF_type_node
,
12877 integer_type_node
, NULL_TREE
);
12878 def_builtin (MASK_VSX
, "__builtin_vec_set_v2df", ftype
,
12879 VSX_BUILTIN_VEC_SET_V2DF
);
12881 ftype
= build_function_type_list (V2DI_type_node
, V2DI_type_node
,
12883 integer_type_node
, NULL_TREE
);
12884 def_builtin (MASK_VSX
, "__builtin_vec_set_v2di", ftype
,
12885 VSX_BUILTIN_VEC_SET_V2DI
);
12888 /* Access to the vec_extract patterns. */
12889 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
12890 integer_type_node
, NULL_TREE
);
12891 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
12892 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
12894 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
12895 integer_type_node
, NULL_TREE
);
12896 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
12897 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
12899 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
12900 integer_type_node
, NULL_TREE
);
12901 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
12902 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
12904 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
12905 integer_type_node
, NULL_TREE
);
12906 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_ext_v4sf", ftype
,
12907 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
12911 ftype
= build_function_type_list (double_type_node
, V2DF_type_node
,
12912 integer_type_node
, NULL_TREE
);
12913 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2df", ftype
,
12914 VSX_BUILTIN_VEC_EXT_V2DF
);
12916 ftype
= build_function_type_list (intDI_type_node
, V2DI_type_node
,
12917 integer_type_node
, NULL_TREE
);
12918 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2di", ftype
,
12919 VSX_BUILTIN_VEC_EXT_V2DI
);
12923 /* Hash function for builtin functions with up to 3 arguments and a return
12926 builtin_hash_function (const void *hash_entry
)
12930 const struct builtin_hash_struct
*bh
=
12931 (const struct builtin_hash_struct
*) hash_entry
;
12933 for (i
= 0; i
< 4; i
++)
12935 ret
= (ret
* (unsigned)MAX_MACHINE_MODE
) + ((unsigned)bh
->mode
[i
]);
12936 ret
= (ret
* 2) + bh
->uns_p
[i
];
12942 /* Compare builtin hash entries H1 and H2 for equivalence. */
12944 builtin_hash_eq (const void *h1
, const void *h2
)
12946 const struct builtin_hash_struct
*p1
= (const struct builtin_hash_struct
*) h1
;
12947 const struct builtin_hash_struct
*p2
= (const struct builtin_hash_struct
*) h2
;
12949 return ((p1
->mode
[0] == p2
->mode
[0])
12950 && (p1
->mode
[1] == p2
->mode
[1])
12951 && (p1
->mode
[2] == p2
->mode
[2])
12952 && (p1
->mode
[3] == p2
->mode
[3])
12953 && (p1
->uns_p
[0] == p2
->uns_p
[0])
12954 && (p1
->uns_p
[1] == p2
->uns_p
[1])
12955 && (p1
->uns_p
[2] == p2
->uns_p
[2])
12956 && (p1
->uns_p
[3] == p2
->uns_p
[3]));
12959 /* Map types for builtin functions with an explicit return type and up to 3
12960 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12961 of the argument. */
12963 builtin_function_type (enum machine_mode mode_ret
, enum machine_mode mode_arg0
,
12964 enum machine_mode mode_arg1
, enum machine_mode mode_arg2
,
12965 enum rs6000_builtins builtin
, const char *name
)
12967 struct builtin_hash_struct h
;
12968 struct builtin_hash_struct
*h2
;
12972 tree ret_type
= NULL_TREE
;
12973 tree arg_type
[3] = { NULL_TREE
, NULL_TREE
, NULL_TREE
};
12975 /* Create builtin_hash_table. */
12976 if (builtin_hash_table
== NULL
)
12977 builtin_hash_table
= htab_create_ggc (1500, builtin_hash_function
,
12978 builtin_hash_eq
, NULL
);
12980 h
.type
= NULL_TREE
;
12981 h
.mode
[0] = mode_ret
;
12982 h
.mode
[1] = mode_arg0
;
12983 h
.mode
[2] = mode_arg1
;
12984 h
.mode
[3] = mode_arg2
;
12990 /* If the builtin is a type that produces unsigned results or takes unsigned
12991 arguments, and it is returned as a decl for the vectorizer (such as
12992 widening multiplies, permute), make sure the arguments and return value
12993 are type correct. */
12996 /* unsigned 2 argument functions. */
12997 case ALTIVEC_BUILTIN_VMULEUB_UNS
:
12998 case ALTIVEC_BUILTIN_VMULEUH_UNS
:
12999 case ALTIVEC_BUILTIN_VMULOUB_UNS
:
13000 case ALTIVEC_BUILTIN_VMULOUH_UNS
:
13006 /* unsigned 3 argument functions. */
13007 case ALTIVEC_BUILTIN_VPERM_16QI_UNS
:
13008 case ALTIVEC_BUILTIN_VPERM_8HI_UNS
:
13009 case ALTIVEC_BUILTIN_VPERM_4SI_UNS
:
13010 case ALTIVEC_BUILTIN_VPERM_2DI_UNS
:
13011 case ALTIVEC_BUILTIN_VSEL_16QI_UNS
:
13012 case ALTIVEC_BUILTIN_VSEL_8HI_UNS
:
13013 case ALTIVEC_BUILTIN_VSEL_4SI_UNS
:
13014 case ALTIVEC_BUILTIN_VSEL_2DI_UNS
:
13015 case VSX_BUILTIN_VPERM_16QI_UNS
:
13016 case VSX_BUILTIN_VPERM_8HI_UNS
:
13017 case VSX_BUILTIN_VPERM_4SI_UNS
:
13018 case VSX_BUILTIN_VPERM_2DI_UNS
:
13019 case VSX_BUILTIN_XXSEL_16QI_UNS
:
13020 case VSX_BUILTIN_XXSEL_8HI_UNS
:
13021 case VSX_BUILTIN_XXSEL_4SI_UNS
:
13022 case VSX_BUILTIN_XXSEL_2DI_UNS
:
13029 /* signed permute functions with unsigned char mask. */
13030 case ALTIVEC_BUILTIN_VPERM_16QI
:
13031 case ALTIVEC_BUILTIN_VPERM_8HI
:
13032 case ALTIVEC_BUILTIN_VPERM_4SI
:
13033 case ALTIVEC_BUILTIN_VPERM_4SF
:
13034 case ALTIVEC_BUILTIN_VPERM_2DI
:
13035 case ALTIVEC_BUILTIN_VPERM_2DF
:
13036 case VSX_BUILTIN_VPERM_16QI
:
13037 case VSX_BUILTIN_VPERM_8HI
:
13038 case VSX_BUILTIN_VPERM_4SI
:
13039 case VSX_BUILTIN_VPERM_4SF
:
13040 case VSX_BUILTIN_VPERM_2DI
:
13041 case VSX_BUILTIN_VPERM_2DF
:
13045 /* unsigned args, signed return. */
13046 case VSX_BUILTIN_XVCVUXDDP_UNS
:
13047 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
:
13051 /* signed args, unsigned return. */
13052 case VSX_BUILTIN_XVCVDPUXDS_UNS
:
13053 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
:
13061 /* Figure out how many args are present. */
13062 while (num_args
> 0 && h
.mode
[num_args
] == VOIDmode
)
13066 fatal_error ("internal error: builtin function %s had no type", name
);
13068 ret_type
= builtin_mode_to_type
[h
.mode
[0]][h
.uns_p
[0]];
13069 if (!ret_type
&& h
.uns_p
[0])
13070 ret_type
= builtin_mode_to_type
[h
.mode
[0]][0];
13073 fatal_error ("internal error: builtin function %s had an unexpected "
13074 "return type %s", name
, GET_MODE_NAME (h
.mode
[0]));
13076 for (i
= 0; i
< (int) ARRAY_SIZE (arg_type
); i
++)
13077 arg_type
[i
] = NULL_TREE
;
13079 for (i
= 0; i
< num_args
; i
++)
13081 int m
= (int) h
.mode
[i
+1];
13082 int uns_p
= h
.uns_p
[i
+1];
13084 arg_type
[i
] = builtin_mode_to_type
[m
][uns_p
];
13085 if (!arg_type
[i
] && uns_p
)
13086 arg_type
[i
] = builtin_mode_to_type
[m
][0];
13089 fatal_error ("internal error: builtin function %s, argument %d "
13090 "had unexpected argument type %s", name
, i
,
13091 GET_MODE_NAME (m
));
13094 found
= htab_find_slot (builtin_hash_table
, &h
, INSERT
);
13095 if (*found
== NULL
)
13097 h2
= ggc_alloc_builtin_hash_struct ();
13099 *found
= (void *)h2
;
13101 h2
->type
= build_function_type_list (ret_type
, arg_type
[0], arg_type
[1],
13102 arg_type
[2], NULL_TREE
);
13105 return ((struct builtin_hash_struct
*)(*found
))->type
;
13109 rs6000_common_init_builtins (void)
13111 const struct builtin_description
*d
;
13114 tree opaque_ftype_opaque
= NULL_TREE
;
13115 tree opaque_ftype_opaque_opaque
= NULL_TREE
;
13116 tree opaque_ftype_opaque_opaque_opaque
= NULL_TREE
;
13117 tree v2si_ftype_qi
= NULL_TREE
;
13118 tree v2si_ftype_v2si_qi
= NULL_TREE
;
13119 tree v2si_ftype_int_qi
= NULL_TREE
;
13121 if (!TARGET_PAIRED_FLOAT
)
13123 builtin_mode_to_type
[V2SImode
][0] = opaque_V2SI_type_node
;
13124 builtin_mode_to_type
[V2SFmode
][0] = opaque_V2SF_type_node
;
13127 /* Add the ternary operators. */
13129 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
13132 int mask
= d
->mask
;
13134 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13135 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13138 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13139 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13140 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13141 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13143 if (! (type
= opaque_ftype_opaque_opaque_opaque
))
13144 type
= opaque_ftype_opaque_opaque_opaque
13145 = build_function_type_list (opaque_V4SI_type_node
,
13146 opaque_V4SI_type_node
,
13147 opaque_V4SI_type_node
,
13148 opaque_V4SI_type_node
,
13153 enum insn_code icode
= d
->icode
;
13154 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13157 type
= builtin_function_type (insn_data
[icode
].operand
[0].mode
,
13158 insn_data
[icode
].operand
[1].mode
,
13159 insn_data
[icode
].operand
[2].mode
,
13160 insn_data
[icode
].operand
[3].mode
,
13164 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13167 /* Add the binary operators. */
13169 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
13171 enum machine_mode mode0
, mode1
, mode2
;
13173 int mask
= d
->mask
;
13175 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13176 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13179 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13180 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13181 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13182 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13184 if (! (type
= opaque_ftype_opaque_opaque
))
13185 type
= opaque_ftype_opaque_opaque
13186 = build_function_type_list (opaque_V4SI_type_node
,
13187 opaque_V4SI_type_node
,
13188 opaque_V4SI_type_node
,
13193 enum insn_code icode
= d
->icode
;
13194 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13197 mode0
= insn_data
[icode
].operand
[0].mode
;
13198 mode1
= insn_data
[icode
].operand
[1].mode
;
13199 mode2
= insn_data
[icode
].operand
[2].mode
;
13201 if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
13203 if (! (type
= v2si_ftype_v2si_qi
))
13204 type
= v2si_ftype_v2si_qi
13205 = build_function_type_list (opaque_V2SI_type_node
,
13206 opaque_V2SI_type_node
,
13211 else if (mode0
== V2SImode
&& GET_MODE_CLASS (mode1
) == MODE_INT
13212 && mode2
== QImode
)
13214 if (! (type
= v2si_ftype_int_qi
))
13215 type
= v2si_ftype_int_qi
13216 = build_function_type_list (opaque_V2SI_type_node
,
13223 type
= builtin_function_type (mode0
, mode1
, mode2
, VOIDmode
,
13227 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13230 /* Add the simple unary operators. */
13231 d
= (struct builtin_description
*) bdesc_1arg
;
13232 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
13234 enum machine_mode mode0
, mode1
;
13236 int mask
= d
->mask
;
13238 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13239 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13242 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13243 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13244 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13245 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13247 if (! (type
= opaque_ftype_opaque
))
13248 type
= opaque_ftype_opaque
13249 = build_function_type_list (opaque_V4SI_type_node
,
13250 opaque_V4SI_type_node
,
13255 enum insn_code icode
= d
->icode
;
13256 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13259 mode0
= insn_data
[icode
].operand
[0].mode
;
13260 mode1
= insn_data
[icode
].operand
[1].mode
;
13262 if (mode0
== V2SImode
&& mode1
== QImode
)
13264 if (! (type
= v2si_ftype_qi
))
13265 type
= v2si_ftype_qi
13266 = build_function_type_list (opaque_V2SI_type_node
,
13272 type
= builtin_function_type (mode0
, mode1
, VOIDmode
, VOIDmode
,
13276 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13281 rs6000_init_libfuncs (void)
13283 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
13284 && !TARGET_POWER2
&& !TARGET_POWERPC
)
13286 /* AIX library routines for float->int conversion. */
13287 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
13288 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
13289 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
13290 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
13293 if (!TARGET_IEEEQUAD
)
13294 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13295 if (!TARGET_XL_COMPAT
)
13297 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
13298 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
13299 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
13300 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
13302 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
13304 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
13305 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
13306 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
13307 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
13308 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
13309 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
13310 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
13312 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
13313 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
13314 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
13315 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
13316 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
13317 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
13318 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
13319 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
13322 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
13323 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
13327 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
13328 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
13329 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
13330 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
13334 /* 32-bit SVR4 quad floating point routines. */
13336 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
13337 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
13338 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
13339 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
13340 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
13341 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
13342 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
13344 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
13345 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
13346 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
13347 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
13348 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
13349 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
13351 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
13352 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
13353 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
13354 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
13355 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
13356 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
13357 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
13358 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
13363 /* Expand a block clear operation, and return 1 if successful. Return 0
13364 if we should let the compiler generate normal code.
13366 operands[0] is the destination
13367 operands[1] is the length
13368 operands[3] is the alignment */
13371 expand_block_clear (rtx operands
[])
13373 rtx orig_dest
= operands
[0];
13374 rtx bytes_rtx
= operands
[1];
13375 rtx align_rtx
= operands
[3];
13376 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
13377 HOST_WIDE_INT align
;
13378 HOST_WIDE_INT bytes
;
13383 /* If this is not a fixed size move, just call memcpy */
13387 /* This must be a fixed size alignment */
13388 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
13389 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
13391 /* Anything to clear? */
13392 bytes
= INTVAL (bytes_rtx
);
13396 /* Use the builtin memset after a point, to avoid huge code bloat.
13397 When optimize_size, avoid any significant code bloat; calling
13398 memset is about 4 instructions, so allow for one instruction to
13399 load zero and three to do clearing. */
13400 if (TARGET_ALTIVEC
&& align
>= 128)
13402 else if (TARGET_POWERPC64
&& align
>= 32)
13404 else if (TARGET_SPE
&& align
>= 64)
13409 if (optimize_size
&& bytes
> 3 * clear_step
)
13411 if (! optimize_size
&& bytes
> 8 * clear_step
)
13414 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
13416 enum machine_mode mode
= BLKmode
;
13419 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
13424 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
13429 else if (bytes
>= 8 && TARGET_POWERPC64
13430 /* 64-bit loads and stores require word-aligned
13432 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
13437 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
13438 { /* move 4 bytes */
13442 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
13443 { /* move 2 bytes */
13447 else /* move 1 byte at a time */
13453 dest
= adjust_address (orig_dest
, mode
, offset
);
13455 emit_move_insn (dest
, CONST0_RTX (mode
));
13462 /* Expand a block move operation, and return 1 if successful. Return 0
13463 if we should let the compiler generate normal code.
13465 operands[0] is the destination
13466 operands[1] is the source
13467 operands[2] is the length
13468 operands[3] is the alignment */
13470 #define MAX_MOVE_REG 4
13473 expand_block_move (rtx operands
[])
13475 rtx orig_dest
= operands
[0];
13476 rtx orig_src
= operands
[1];
13477 rtx bytes_rtx
= operands
[2];
13478 rtx align_rtx
= operands
[3];
13479 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
13484 rtx stores
[MAX_MOVE_REG
];
13487 /* If this is not a fixed size move, just call memcpy */
13491 /* This must be a fixed size alignment */
13492 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
13493 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
13495 /* Anything to move? */
13496 bytes
= INTVAL (bytes_rtx
);
13500 if (bytes
> rs6000_block_move_inline_limit
)
13503 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
13506 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
13507 rtx (*mov
) (rtx
, rtx
);
13509 enum machine_mode mode
= BLKmode
;
13512 /* Altivec first, since it will be faster than a string move
13513 when it applies, and usually not significantly larger. */
13514 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
13518 gen_func
.mov
= gen_movv4si
;
13520 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
13524 gen_func
.mov
= gen_movv2si
;
13526 else if (TARGET_STRING
13527 && bytes
> 24 /* move up to 32 bytes at a time */
13533 && ! fixed_regs
[10]
13534 && ! fixed_regs
[11]
13535 && ! fixed_regs
[12])
13537 move_bytes
= (bytes
> 32) ? 32 : bytes
;
13538 gen_func
.movmemsi
= gen_movmemsi_8reg
;
13540 else if (TARGET_STRING
13541 && bytes
> 16 /* move up to 24 bytes at a time */
13547 && ! fixed_regs
[10])
13549 move_bytes
= (bytes
> 24) ? 24 : bytes
;
13550 gen_func
.movmemsi
= gen_movmemsi_6reg
;
13552 else if (TARGET_STRING
13553 && bytes
> 8 /* move up to 16 bytes at a time */
13557 && ! fixed_regs
[8])
13559 move_bytes
= (bytes
> 16) ? 16 : bytes
;
13560 gen_func
.movmemsi
= gen_movmemsi_4reg
;
13562 else if (bytes
>= 8 && TARGET_POWERPC64
13563 /* 64-bit loads and stores require word-aligned
13565 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
13569 gen_func
.mov
= gen_movdi
;
13571 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
13572 { /* move up to 8 bytes at a time */
13573 move_bytes
= (bytes
> 8) ? 8 : bytes
;
13574 gen_func
.movmemsi
= gen_movmemsi_2reg
;
13576 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
13577 { /* move 4 bytes */
13580 gen_func
.mov
= gen_movsi
;
13582 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
13583 { /* move 2 bytes */
13586 gen_func
.mov
= gen_movhi
;
13588 else if (TARGET_STRING
&& bytes
> 1)
13589 { /* move up to 4 bytes at a time */
13590 move_bytes
= (bytes
> 4) ? 4 : bytes
;
13591 gen_func
.movmemsi
= gen_movmemsi_1reg
;
13593 else /* move 1 byte at a time */
13597 gen_func
.mov
= gen_movqi
;
13600 src
= adjust_address (orig_src
, mode
, offset
);
13601 dest
= adjust_address (orig_dest
, mode
, offset
);
13603 if (mode
!= BLKmode
)
13605 rtx tmp_reg
= gen_reg_rtx (mode
);
13607 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
13608 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
13611 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
13614 for (i
= 0; i
< num_reg
; i
++)
13615 emit_insn (stores
[i
]);
13619 if (mode
== BLKmode
)
13621 /* Move the address into scratch registers. The movmemsi
13622 patterns require zero offset. */
13623 if (!REG_P (XEXP (src
, 0)))
13625 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
13626 src
= replace_equiv_address (src
, src_reg
);
13628 set_mem_size (src
, move_bytes
);
13630 if (!REG_P (XEXP (dest
, 0)))
13632 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
13633 dest
= replace_equiv_address (dest
, dest_reg
);
13635 set_mem_size (dest
, move_bytes
);
13637 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
13638 GEN_INT (move_bytes
& 31),
13647 /* Return a string to perform a load_multiple operation.
13648 operands[0] is the vector.
13649 operands[1] is the source address.
13650 operands[2] is the first destination register. */
13653 rs6000_output_load_multiple (rtx operands
[3])
13655 /* We have to handle the case where the pseudo used to contain the address
13656 is assigned to one of the output registers. */
13658 int words
= XVECLEN (operands
[0], 0);
13661 if (XVECLEN (operands
[0], 0) == 1)
13662 return "{l|lwz} %2,0(%1)";
13664 for (i
= 0; i
< words
; i
++)
13665 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
13666 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
13670 xop
[0] = GEN_INT (4 * (words
-1));
13671 xop
[1] = operands
[1];
13672 xop
[2] = operands
[2];
13673 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
13678 xop
[0] = GEN_INT (4 * (words
-1));
13679 xop
[1] = operands
[1];
13680 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
13681 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
);
13686 for (j
= 0; j
< words
; j
++)
13689 xop
[0] = GEN_INT (j
* 4);
13690 xop
[1] = operands
[1];
13691 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
13692 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
13694 xop
[0] = GEN_INT (i
* 4);
13695 xop
[1] = operands
[1];
13696 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
13701 return "{lsi|lswi} %2,%1,%N0";
13705 /* A validation routine: say whether CODE, a condition code, and MODE
13706 match. The other alternatives either don't make sense or should
13707 never be generated. */
13710 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
13712 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
13713 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
13714 && GET_MODE_CLASS (mode
) == MODE_CC
);
13716 /* These don't make sense. */
13717 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
13718 || mode
!= CCUNSmode
);
13720 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
13721 || mode
== CCUNSmode
);
13723 gcc_assert (mode
== CCFPmode
13724 || (code
!= ORDERED
&& code
!= UNORDERED
13725 && code
!= UNEQ
&& code
!= LTGT
13726 && code
!= UNGT
&& code
!= UNLT
13727 && code
!= UNGE
&& code
!= UNLE
));
13729 /* These should never be generated except for
13730 flag_finite_math_only. */
13731 gcc_assert (mode
!= CCFPmode
13732 || flag_finite_math_only
13733 || (code
!= LE
&& code
!= GE
13734 && code
!= UNEQ
&& code
!= LTGT
13735 && code
!= UNGT
&& code
!= UNLT
));
13737 /* These are invalid; the information is not there. */
13738 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
13742 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13743 mask required to convert the result of a rotate insn into a shift
13744 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13747 includes_lshift_p (rtx shiftop
, rtx andop
)
13749 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
13751 shift_mask
<<= INTVAL (shiftop
);
13753 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
13756 /* Similar, but for right shift. */
13759 includes_rshift_p (rtx shiftop
, rtx andop
)
13761 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
13763 shift_mask
>>= INTVAL (shiftop
);
13765 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
13768 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13769 to perform a left shift. It must have exactly SHIFTOP least
13770 significant 0's, then one or more 1's, then zero or more 0's. */
13773 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
13775 if (GET_CODE (andop
) == CONST_INT
)
13777 HOST_WIDE_INT c
, lsb
, shift_mask
;
13779 c
= INTVAL (andop
);
13780 if (c
== 0 || c
== ~0)
13784 shift_mask
<<= INTVAL (shiftop
);
13786 /* Find the least significant one bit. */
13789 /* It must coincide with the LSB of the shift mask. */
13790 if (-lsb
!= shift_mask
)
13793 /* Invert to look for the next transition (if any). */
13796 /* Remove the low group of ones (originally low group of zeros). */
13799 /* Again find the lsb, and check we have all 1's above. */
13803 else if (GET_CODE (andop
) == CONST_DOUBLE
13804 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
13806 HOST_WIDE_INT low
, high
, lsb
;
13807 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
13809 low
= CONST_DOUBLE_LOW (andop
);
13810 if (HOST_BITS_PER_WIDE_INT
< 64)
13811 high
= CONST_DOUBLE_HIGH (andop
);
13813 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
13814 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
13817 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
13819 shift_mask_high
= ~0;
13820 if (INTVAL (shiftop
) > 32)
13821 shift_mask_high
<<= INTVAL (shiftop
) - 32;
13823 lsb
= high
& -high
;
13825 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
13831 lsb
= high
& -high
;
13832 return high
== -lsb
;
13835 shift_mask_low
= ~0;
13836 shift_mask_low
<<= INTVAL (shiftop
);
13840 if (-lsb
!= shift_mask_low
)
13843 if (HOST_BITS_PER_WIDE_INT
< 64)
13848 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
13850 lsb
= high
& -high
;
13851 return high
== -lsb
;
13855 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
13861 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13862 to perform a left shift. It must have SHIFTOP or more least
13863 significant 0's, with the remainder of the word 1's. */
13866 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
13868 if (GET_CODE (andop
) == CONST_INT
)
13870 HOST_WIDE_INT c
, lsb
, shift_mask
;
13873 shift_mask
<<= INTVAL (shiftop
);
13874 c
= INTVAL (andop
);
13876 /* Find the least significant one bit. */
13879 /* It must be covered by the shift mask.
13880 This test also rejects c == 0. */
13881 if ((lsb
& shift_mask
) == 0)
13884 /* Check we have all 1's above the transition, and reject all 1's. */
13885 return c
== -lsb
&& lsb
!= 1;
13887 else if (GET_CODE (andop
) == CONST_DOUBLE
13888 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
13890 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
13892 low
= CONST_DOUBLE_LOW (andop
);
13894 if (HOST_BITS_PER_WIDE_INT
< 64)
13896 HOST_WIDE_INT high
, shift_mask_high
;
13898 high
= CONST_DOUBLE_HIGH (andop
);
13902 shift_mask_high
= ~0;
13903 if (INTVAL (shiftop
) > 32)
13904 shift_mask_high
<<= INTVAL (shiftop
) - 32;
13906 lsb
= high
& -high
;
13908 if ((lsb
& shift_mask_high
) == 0)
13911 return high
== -lsb
;
13917 shift_mask_low
= ~0;
13918 shift_mask_low
<<= INTVAL (shiftop
);
13922 if ((lsb
& shift_mask_low
) == 0)
13925 return low
== -lsb
&& lsb
!= 1;
13931 /* Return 1 if operands will generate a valid arguments to rlwimi
13932 instruction for insert with right shift in 64-bit mode. The mask may
13933 not start on the first bit or stop on the last bit because wrap-around
13934 effects of instruction do not correspond to semantics of RTL insn. */
13937 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
13939 if (INTVAL (startop
) > 32
13940 && INTVAL (startop
) < 64
13941 && INTVAL (sizeop
) > 1
13942 && INTVAL (sizeop
) + INTVAL (startop
) < 64
13943 && INTVAL (shiftop
) > 0
13944 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
13945 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
13951 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13952 for lfq and stfq insns iff the registers are hard registers. */
13955 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
13957 /* We might have been passed a SUBREG. */
13958 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
13961 /* We might have been passed non floating point registers. */
13962 if (!FP_REGNO_P (REGNO (reg1
))
13963 || !FP_REGNO_P (REGNO (reg2
)))
13966 return (REGNO (reg1
) == REGNO (reg2
) - 1);
13969 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13970 addr1 and addr2 must be in consecutive memory locations
13971 (addr2 == addr1 + 8). */
13974 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
13977 unsigned int reg1
, reg2
;
13978 int offset1
, offset2
;
13980 /* The mems cannot be volatile. */
13981 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
13984 addr1
= XEXP (mem1
, 0);
13985 addr2
= XEXP (mem2
, 0);
13987 /* Extract an offset (if used) from the first addr. */
13988 if (GET_CODE (addr1
) == PLUS
)
13990 /* If not a REG, return zero. */
13991 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
13995 reg1
= REGNO (XEXP (addr1
, 0));
13996 /* The offset must be constant! */
13997 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
13999 offset1
= INTVAL (XEXP (addr1
, 1));
14002 else if (GET_CODE (addr1
) != REG
)
14006 reg1
= REGNO (addr1
);
14007 /* This was a simple (mem (reg)) expression. Offset is 0. */
14011 /* And now for the second addr. */
14012 if (GET_CODE (addr2
) == PLUS
)
14014 /* If not a REG, return zero. */
14015 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
14019 reg2
= REGNO (XEXP (addr2
, 0));
14020 /* The offset must be constant. */
14021 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
14023 offset2
= INTVAL (XEXP (addr2
, 1));
14026 else if (GET_CODE (addr2
) != REG
)
14030 reg2
= REGNO (addr2
);
14031 /* This was a simple (mem (reg)) expression. Offset is 0. */
14035 /* Both of these must have the same base register. */
14039 /* The offset for the second addr must be 8 more than the first addr. */
14040 if (offset2
!= offset1
+ 8)
14043 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14050 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
14052 static bool eliminated
= false;
14055 if (mode
!= SDmode
)
14056 ret
= assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
14059 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
14060 gcc_assert (mem
!= NULL_RTX
);
14064 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
14065 cfun
->machine
->sdmode_stack_slot
= mem
;
14071 if (TARGET_DEBUG_ADDR
)
14073 fprintf (stderr
, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14074 GET_MODE_NAME (mode
));
14076 fprintf (stderr
, "\tNULL_RTX\n");
14085 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
14087 /* Don't walk into types. */
14088 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
14090 *walk_subtrees
= 0;
14094 switch (TREE_CODE (*tp
))
14103 case VIEW_CONVERT_EXPR
:
14104 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
14114 enum reload_reg_type
{
14116 VECTOR_REGISTER_TYPE
,
14117 OTHER_REGISTER_TYPE
14120 static enum reload_reg_type
14121 rs6000_reload_register_type (enum reg_class rclass
)
14127 return GPR_REGISTER_TYPE
;
14132 return VECTOR_REGISTER_TYPE
;
14135 return OTHER_REGISTER_TYPE
;
14139 /* Inform reload about cases where moving X with a mode MODE to a register in
14140 RCLASS requires an extra scratch or immediate register. Return the class
14141 needed for the immediate register.
14143 For VSX and Altivec, we may need a register to convert sp+offset into
14146 For misaligned 64-bit gpr loads and stores we need a register to
14147 convert an offset address to indirect. */
14150 rs6000_secondary_reload (bool in_p
,
14152 reg_class_t rclass_i
,
14153 enum machine_mode mode
,
14154 secondary_reload_info
*sri
)
14156 enum reg_class rclass
= (enum reg_class
) rclass_i
;
14157 reg_class_t ret
= ALL_REGS
;
14158 enum insn_code icode
;
14159 bool default_p
= false;
14161 sri
->icode
= CODE_FOR_nothing
;
14163 /* Convert vector loads and stores into gprs to use an additional base
14165 icode
= rs6000_vector_reload
[mode
][in_p
!= false];
14166 if (icode
!= CODE_FOR_nothing
)
14169 sri
->icode
= CODE_FOR_nothing
;
14170 sri
->extra_cost
= 0;
14172 if (GET_CODE (x
) == MEM
)
14174 rtx addr
= XEXP (x
, 0);
14176 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14177 an extra register in that case, but it would need an extra
14178 register if the addressing is reg+reg or (reg+reg)&(-16). */
14179 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
)
14181 if (!legitimate_indirect_address_p (addr
, false)
14182 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14184 sri
->icode
= icode
;
14185 /* account for splitting the loads, and converting the
14186 address from reg+reg to reg. */
14187 sri
->extra_cost
= (((TARGET_64BIT
) ? 3 : 5)
14188 + ((GET_CODE (addr
) == AND
) ? 1 : 0));
14191 /* Loads to and stores from vector registers can only do reg+reg
14192 addressing. Altivec registers can also do (reg+reg)&(-16). */
14193 else if (rclass
== VSX_REGS
|| rclass
== ALTIVEC_REGS
14194 || rclass
== FLOAT_REGS
|| rclass
== NO_REGS
)
14196 if (!VECTOR_MEM_ALTIVEC_P (mode
)
14197 && GET_CODE (addr
) == AND
14198 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14199 && INTVAL (XEXP (addr
, 1)) == -16
14200 && (legitimate_indirect_address_p (XEXP (addr
, 0), false)
14201 || legitimate_indexed_address_p (XEXP (addr
, 0), false)))
14203 sri
->icode
= icode
;
14204 sri
->extra_cost
= ((GET_CODE (XEXP (addr
, 0)) == PLUS
)
14207 else if (!legitimate_indirect_address_p (addr
, false)
14208 && (rclass
== NO_REGS
14209 || !legitimate_indexed_address_p (addr
, false)))
14211 sri
->icode
= icode
;
14212 sri
->extra_cost
= 1;
14215 icode
= CODE_FOR_nothing
;
14217 /* Any other loads, including to pseudo registers which haven't been
14218 assigned to a register yet, default to require a scratch
14222 sri
->icode
= icode
;
14223 sri
->extra_cost
= 2;
14226 else if (REG_P (x
))
14228 int regno
= true_regnum (x
);
14230 icode
= CODE_FOR_nothing
;
14231 if (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
)
14235 enum reg_class xclass
= REGNO_REG_CLASS (regno
);
14236 enum reload_reg_type rtype1
= rs6000_reload_register_type (rclass
);
14237 enum reload_reg_type rtype2
= rs6000_reload_register_type (xclass
);
14239 /* If memory is needed, use default_secondary_reload to create the
14241 if (rtype1
!= rtype2
|| rtype1
== OTHER_REGISTER_TYPE
)
14250 else if (TARGET_POWERPC64
14251 && rs6000_reload_register_type (rclass
) == GPR_REGISTER_TYPE
14253 && GET_MODE_SIZE (GET_MODE (x
)) >= UNITS_PER_WORD
)
14255 rtx addr
= XEXP (x
, 0);
14257 if (GET_CODE (addr
) == PRE_MODIFY
)
14258 addr
= XEXP (addr
, 1);
14259 else if (GET_CODE (addr
) == LO_SUM
14260 && GET_CODE (XEXP (addr
, 0)) == REG
14261 && GET_CODE (XEXP (addr
, 1)) == CONST
)
14262 addr
= XEXP (XEXP (addr
, 1), 0);
14264 if (GET_CODE (addr
) == PLUS
14265 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14266 && (INTVAL (XEXP (addr
, 1)) & 3) != 0)
14269 sri
->icode
= CODE_FOR_reload_di_load
;
14271 sri
->icode
= CODE_FOR_reload_di_store
;
14272 sri
->extra_cost
= 2;
14282 ret
= default_secondary_reload (in_p
, x
, rclass
, mode
, sri
);
14284 gcc_assert (ret
!= ALL_REGS
);
14286 if (TARGET_DEBUG_ADDR
)
14289 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14291 reg_class_names
[ret
],
14292 in_p
? "true" : "false",
14293 reg_class_names
[rclass
],
14294 GET_MODE_NAME (mode
));
14297 fprintf (stderr
, ", default secondary reload");
14299 if (sri
->icode
!= CODE_FOR_nothing
)
14300 fprintf (stderr
, ", reload func = %s, extra cost = %d\n",
14301 insn_data
[sri
->icode
].name
, sri
->extra_cost
);
14303 fprintf (stderr
, "\n");
14311 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14312 to SP+reg addressing. */
14315 rs6000_secondary_reload_inner (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
14317 int regno
= true_regnum (reg
);
14318 enum machine_mode mode
= GET_MODE (reg
);
14319 enum reg_class rclass
;
14321 rtx and_op2
= NULL_RTX
;
14324 rtx scratch_or_premodify
= scratch
;
14328 if (TARGET_DEBUG_ADDR
)
14330 fprintf (stderr
, "\nrs6000_secondary_reload_inner, type = %s\n",
14331 store_p
? "store" : "load");
14332 fprintf (stderr
, "reg:\n");
14334 fprintf (stderr
, "mem:\n");
14336 fprintf (stderr
, "scratch:\n");
14337 debug_rtx (scratch
);
14340 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
14341 gcc_assert (GET_CODE (mem
) == MEM
);
14342 rclass
= REGNO_REG_CLASS (regno
);
14343 addr
= XEXP (mem
, 0);
14347 /* GPRs can handle reg + small constant, all other addresses need to use
14348 the scratch register. */
14351 if (GET_CODE (addr
) == AND
)
14353 and_op2
= XEXP (addr
, 1);
14354 addr
= XEXP (addr
, 0);
14357 if (GET_CODE (addr
) == PRE_MODIFY
)
14359 scratch_or_premodify
= XEXP (addr
, 0);
14360 gcc_assert (REG_P (scratch_or_premodify
));
14361 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14362 addr
= XEXP (addr
, 1);
14365 if (GET_CODE (addr
) == PLUS
14366 && (!rs6000_legitimate_offset_address_p (TImode
, addr
, false)
14367 || and_op2
!= NULL_RTX
))
14369 addr_op1
= XEXP (addr
, 0);
14370 addr_op2
= XEXP (addr
, 1);
14371 gcc_assert (legitimate_indirect_address_p (addr_op1
, false));
14373 if (!REG_P (addr_op2
)
14374 && (GET_CODE (addr_op2
) != CONST_INT
14375 || !satisfies_constraint_I (addr_op2
)))
14377 if (TARGET_DEBUG_ADDR
)
14380 "\nMove plus addr to register %s, mode = %s: ",
14381 rs6000_reg_names
[REGNO (scratch
)],
14382 GET_MODE_NAME (mode
));
14383 debug_rtx (addr_op2
);
14385 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14386 addr_op2
= scratch
;
14389 emit_insn (gen_rtx_SET (VOIDmode
,
14390 scratch_or_premodify
,
14391 gen_rtx_PLUS (Pmode
,
14395 addr
= scratch_or_premodify
;
14396 scratch_or_premodify
= scratch
;
14398 else if (!legitimate_indirect_address_p (addr
, false)
14399 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14401 if (TARGET_DEBUG_ADDR
)
14403 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
14404 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
14405 GET_MODE_NAME (mode
));
14408 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14409 addr
= scratch_or_premodify
;
14410 scratch_or_premodify
= scratch
;
14414 /* Float/Altivec registers can only handle reg+reg addressing. Move
14415 other addresses into a scratch register. */
14420 /* With float regs, we need to handle the AND ourselves, since we can't
14421 use the Altivec instruction with an implicit AND -16. Allow scalar
14422 loads to float registers to use reg+offset even if VSX. */
14423 if (GET_CODE (addr
) == AND
14424 && (rclass
!= ALTIVEC_REGS
|| GET_MODE_SIZE (mode
) != 16
14425 || GET_CODE (XEXP (addr
, 1)) != CONST_INT
14426 || INTVAL (XEXP (addr
, 1)) != -16
14427 || !VECTOR_MEM_ALTIVEC_P (mode
)))
14429 and_op2
= XEXP (addr
, 1);
14430 addr
= XEXP (addr
, 0);
14433 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14434 as the address later. */
14435 if (GET_CODE (addr
) == PRE_MODIFY
14436 && (!VECTOR_MEM_VSX_P (mode
)
14437 || and_op2
!= NULL_RTX
14438 || !legitimate_indexed_address_p (XEXP (addr
, 1), false)))
14440 scratch_or_premodify
= XEXP (addr
, 0);
14441 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify
,
14443 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14444 addr
= XEXP (addr
, 1);
14447 if (legitimate_indirect_address_p (addr
, false) /* reg */
14448 || legitimate_indexed_address_p (addr
, false) /* reg+reg */
14449 || GET_CODE (addr
) == PRE_MODIFY
/* VSX pre-modify */
14450 || (GET_CODE (addr
) == AND
/* Altivec memory */
14451 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14452 && INTVAL (XEXP (addr
, 1)) == -16
14453 && VECTOR_MEM_ALTIVEC_P (mode
))
14454 || (rclass
== FLOAT_REGS
/* legacy float mem */
14455 && GET_MODE_SIZE (mode
) == 8
14456 && and_op2
== NULL_RTX
14457 && scratch_or_premodify
== scratch
14458 && rs6000_legitimate_offset_address_p (mode
, addr
, false)))
14461 else if (GET_CODE (addr
) == PLUS
)
14463 addr_op1
= XEXP (addr
, 0);
14464 addr_op2
= XEXP (addr
, 1);
14465 gcc_assert (REG_P (addr_op1
));
14467 if (TARGET_DEBUG_ADDR
)
14469 fprintf (stderr
, "\nMove plus addr to register %s, mode = %s: ",
14470 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
14471 debug_rtx (addr_op2
);
14473 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14474 emit_insn (gen_rtx_SET (VOIDmode
,
14475 scratch_or_premodify
,
14476 gen_rtx_PLUS (Pmode
,
14479 addr
= scratch_or_premodify
;
14480 scratch_or_premodify
= scratch
;
14483 else if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == CONST
14484 || GET_CODE (addr
) == CONST_INT
|| REG_P (addr
))
14486 if (TARGET_DEBUG_ADDR
)
14488 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
14489 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
14490 GET_MODE_NAME (mode
));
14494 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14495 addr
= scratch_or_premodify
;
14496 scratch_or_premodify
= scratch
;
14500 gcc_unreachable ();
14505 gcc_unreachable ();
14508 /* If the original address involved a pre-modify that we couldn't use the VSX
14509 memory instruction with update, and we haven't taken care of already,
14510 store the address in the pre-modify register and use that as the
14512 if (scratch_or_premodify
!= scratch
&& scratch_or_premodify
!= addr
)
14514 emit_insn (gen_rtx_SET (VOIDmode
, scratch_or_premodify
, addr
));
14515 addr
= scratch_or_premodify
;
14518 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14519 memory instruction, recreate the AND now, including the clobber which is
14520 generated by the general ANDSI3/ANDDI3 patterns for the
14521 andi. instruction. */
14522 if (and_op2
!= NULL_RTX
)
14524 if (! legitimate_indirect_address_p (addr
, false))
14526 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, addr
));
14530 if (TARGET_DEBUG_ADDR
)
14532 fprintf (stderr
, "\nAnd addr to register %s, mode = %s: ",
14533 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
14534 debug_rtx (and_op2
);
14537 and_rtx
= gen_rtx_SET (VOIDmode
,
14539 gen_rtx_AND (Pmode
,
14543 cc_clobber
= gen_rtx_CLOBBER (CCmode
, gen_rtx_SCRATCH (CCmode
));
14544 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
14545 gen_rtvec (2, and_rtx
, cc_clobber
)));
14549 /* Adjust the address if it changed. */
14550 if (addr
!= XEXP (mem
, 0))
14552 mem
= change_address (mem
, mode
, addr
);
14553 if (TARGET_DEBUG_ADDR
)
14554 fprintf (stderr
, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14557 /* Now create the move. */
14559 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
14561 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
14566 /* Convert reloads involving 64-bit gprs and misaligned offset
14567 addressing to use indirect addressing. */
14570 rs6000_secondary_reload_ppc64 (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
14572 int regno
= true_regnum (reg
);
14573 enum reg_class rclass
;
14575 rtx scratch_or_premodify
= scratch
;
14577 if (TARGET_DEBUG_ADDR
)
14579 fprintf (stderr
, "\nrs6000_secondary_reload_ppc64, type = %s\n",
14580 store_p
? "store" : "load");
14581 fprintf (stderr
, "reg:\n");
14583 fprintf (stderr
, "mem:\n");
14585 fprintf (stderr
, "scratch:\n");
14586 debug_rtx (scratch
);
14589 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
14590 gcc_assert (GET_CODE (mem
) == MEM
);
14591 rclass
= REGNO_REG_CLASS (regno
);
14592 gcc_assert (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
);
14593 addr
= XEXP (mem
, 0);
14595 if (GET_CODE (addr
) == PRE_MODIFY
)
14597 scratch_or_premodify
= XEXP (addr
, 0);
14598 gcc_assert (REG_P (scratch_or_premodify
));
14599 addr
= XEXP (addr
, 1);
14601 gcc_assert (GET_CODE (addr
) == PLUS
|| GET_CODE (addr
) == LO_SUM
);
14603 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14605 mem
= replace_equiv_address_nv (mem
, scratch_or_premodify
);
14607 /* Now create the move. */
14609 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
14611 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
14616 /* Allocate a 64-bit stack slot to be used for copying SDmode
14617 values through if this function has any SDmode references. */
14620 rs6000_alloc_sdmode_stack_slot (void)
14624 gimple_stmt_iterator gsi
;
14626 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
14629 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
14631 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
14634 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
14635 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
14641 /* Check for any SDmode parameters of the function. */
14642 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= DECL_CHAIN (t
))
14644 if (TREE_TYPE (t
) == error_mark_node
)
14647 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
14648 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
14650 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
14651 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
14659 rs6000_instantiate_decls (void)
14661 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
14662 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
14665 /* Given an rtx X being reloaded into a reg required to be
14666 in class CLASS, return the class of reg to actually use.
14667 In general this is just CLASS; but on some machines
14668 in some cases it is preferable to use a more restrictive class.
14670 On the RS/6000, we have to return NO_REGS when we want to reload a
14671 floating-point CONST_DOUBLE to force it to be copied to memory.
14673 We also don't want to reload integer values into floating-point
14674 registers if we can at all help it. In fact, this can
14675 cause reload to die, if it tries to generate a reload of CTR
14676 into a FP register and discovers it doesn't have the memory location
14679 ??? Would it be a good idea to have reload do the converse, that is
14680 try to reload floating modes into FP registers if possible?
14683 static enum reg_class
14684 rs6000_preferred_reload_class (rtx x
, enum reg_class rclass
)
14686 enum machine_mode mode
= GET_MODE (x
);
14688 if (VECTOR_UNIT_VSX_P (mode
)
14689 && x
== CONST0_RTX (mode
) && VSX_REG_CLASS_P (rclass
))
14692 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
14693 && (rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
14694 && easy_vector_constant (x
, mode
))
14695 return ALTIVEC_REGS
;
14697 if (CONSTANT_P (x
) && reg_classes_intersect_p (rclass
, FLOAT_REGS
))
14700 if (GET_MODE_CLASS (mode
) == MODE_INT
&& rclass
== NON_SPECIAL_REGS
)
14701 return GENERAL_REGS
;
14703 /* For VSX, prefer the traditional registers for 64-bit values because we can
14704 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14705 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14706 prefer Altivec loads.. */
14707 if (rclass
== VSX_REGS
)
14709 if (GET_MODE_SIZE (mode
) <= 8)
14712 if (VECTOR_UNIT_ALTIVEC_P (mode
) || VECTOR_MEM_ALTIVEC_P (mode
))
14713 return ALTIVEC_REGS
;
14721 /* Debug version of rs6000_preferred_reload_class. */
14722 static enum reg_class
14723 rs6000_debug_preferred_reload_class (rtx x
, enum reg_class rclass
)
14725 enum reg_class ret
= rs6000_preferred_reload_class (x
, rclass
);
14728 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14730 reg_class_names
[ret
], reg_class_names
[rclass
],
14731 GET_MODE_NAME (GET_MODE (x
)));
14737 /* If we are copying between FP or AltiVec registers and anything else, we need
14738 a memory location. The exception is when we are targeting ppc64 and the
14739 move to/from fpr to gpr instructions are available. Also, under VSX, you
14740 can copy vector registers from the FP register set to the Altivec register
14741 set and vice versa. */
14744 rs6000_secondary_memory_needed (enum reg_class class1
,
14745 enum reg_class class2
,
14746 enum machine_mode mode
)
14748 if (class1
== class2
)
14751 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14752 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14753 between these classes. But we need memory for other things that can go in
14754 FLOAT_REGS like SFmode. */
14756 && (VECTOR_MEM_VSX_P (mode
) || VECTOR_UNIT_VSX_P (mode
))
14757 && (class1
== VSX_REGS
|| class1
== ALTIVEC_REGS
14758 || class1
== FLOAT_REGS
))
14759 return (class2
!= VSX_REGS
&& class2
!= ALTIVEC_REGS
14760 && class2
!= FLOAT_REGS
);
14762 if (class1
== VSX_REGS
|| class2
== VSX_REGS
)
14765 if (class1
== FLOAT_REGS
14766 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
14767 || ((mode
!= DFmode
)
14768 && (mode
!= DDmode
)
14769 && (mode
!= DImode
))))
14772 if (class2
== FLOAT_REGS
14773 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
14774 || ((mode
!= DFmode
)
14775 && (mode
!= DDmode
)
14776 && (mode
!= DImode
))))
14779 if (class1
== ALTIVEC_REGS
|| class2
== ALTIVEC_REGS
)
14785 /* Debug version of rs6000_secondary_memory_needed. */
14787 rs6000_debug_secondary_memory_needed (enum reg_class class1
,
14788 enum reg_class class2
,
14789 enum machine_mode mode
)
14791 bool ret
= rs6000_secondary_memory_needed (class1
, class2
, mode
);
14794 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14795 "class2 = %s, mode = %s\n",
14796 ret
? "true" : "false", reg_class_names
[class1
],
14797 reg_class_names
[class2
], GET_MODE_NAME (mode
));
14802 /* Return the register class of a scratch register needed to copy IN into
14803 or out of a register in RCLASS in MODE. If it can be done directly,
14804 NO_REGS is returned. */
14806 static enum reg_class
14807 rs6000_secondary_reload_class (enum reg_class rclass
, enum machine_mode mode
,
14812 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
14814 && MACHOPIC_INDIRECT
14818 /* We cannot copy a symbolic operand directly into anything
14819 other than BASE_REGS for TARGET_ELF. So indicate that a
14820 register from BASE_REGS is needed as an intermediate
14823 On Darwin, pic addresses require a load from memory, which
14824 needs a base register. */
14825 if (rclass
!= BASE_REGS
14826 && (GET_CODE (in
) == SYMBOL_REF
14827 || GET_CODE (in
) == HIGH
14828 || GET_CODE (in
) == LABEL_REF
14829 || GET_CODE (in
) == CONST
))
14833 if (GET_CODE (in
) == REG
)
14835 regno
= REGNO (in
);
14836 if (regno
>= FIRST_PSEUDO_REGISTER
)
14838 regno
= true_regnum (in
);
14839 if (regno
>= FIRST_PSEUDO_REGISTER
)
14843 else if (GET_CODE (in
) == SUBREG
)
14845 regno
= true_regnum (in
);
14846 if (regno
>= FIRST_PSEUDO_REGISTER
)
14852 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14854 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
14855 || (regno
>= 0 && INT_REGNO_P (regno
)))
14858 /* Constants, memory, and FP registers can go into FP registers. */
14859 if ((regno
== -1 || FP_REGNO_P (regno
))
14860 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
14861 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
14863 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14866 && (regno
== -1 || VSX_REGNO_P (regno
))
14867 && VSX_REG_CLASS_P (rclass
))
14870 /* Memory, and AltiVec registers can go into AltiVec registers. */
14871 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
14872 && rclass
== ALTIVEC_REGS
)
14875 /* We can copy among the CR registers. */
14876 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
14877 && regno
>= 0 && CR_REGNO_P (regno
))
14880 /* Otherwise, we need GENERAL_REGS. */
14881 return GENERAL_REGS
;
14884 /* Debug version of rs6000_secondary_reload_class. */
14885 static enum reg_class
14886 rs6000_debug_secondary_reload_class (enum reg_class rclass
,
14887 enum machine_mode mode
, rtx in
)
14889 enum reg_class ret
= rs6000_secondary_reload_class (rclass
, mode
, in
);
14891 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14892 "mode = %s, input rtx:\n",
14893 reg_class_names
[ret
], reg_class_names
[rclass
],
14894 GET_MODE_NAME (mode
));
14900 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14903 rs6000_cannot_change_mode_class (enum machine_mode from
,
14904 enum machine_mode to
,
14905 enum reg_class rclass
)
14907 unsigned from_size
= GET_MODE_SIZE (from
);
14908 unsigned to_size
= GET_MODE_SIZE (to
);
14910 if (from_size
!= to_size
)
14912 enum reg_class xclass
= (TARGET_VSX
) ? VSX_REGS
: FLOAT_REGS
;
14913 return ((from_size
< 8 || to_size
< 8 || TARGET_IEEEQUAD
)
14914 && reg_classes_intersect_p (xclass
, rclass
));
14917 if (TARGET_E500_DOUBLE
14918 && ((((to
) == DFmode
) + ((from
) == DFmode
)) == 1
14919 || (((to
) == TFmode
) + ((from
) == TFmode
)) == 1
14920 || (((to
) == DDmode
) + ((from
) == DDmode
)) == 1
14921 || (((to
) == TDmode
) + ((from
) == TDmode
)) == 1
14922 || (((to
) == DImode
) + ((from
) == DImode
)) == 1))
14925 /* Since the VSX register set includes traditional floating point registers
14926 and altivec registers, just check for the size being different instead of
14927 trying to check whether the modes are vector modes. Otherwise it won't
14928 allow say DF and DI to change classes. */
14929 if (TARGET_VSX
&& VSX_REG_CLASS_P (rclass
))
14930 return (from_size
!= 8 && from_size
!= 16);
14932 if (TARGET_ALTIVEC
&& rclass
== ALTIVEC_REGS
14933 && (ALTIVEC_VECTOR_MODE (from
) + ALTIVEC_VECTOR_MODE (to
)) == 1)
14936 if (TARGET_SPE
&& (SPE_VECTOR_MODE (from
) + SPE_VECTOR_MODE (to
)) == 1
14937 && reg_classes_intersect_p (GENERAL_REGS
, rclass
))
14943 /* Debug version of rs6000_cannot_change_mode_class. */
14945 rs6000_debug_cannot_change_mode_class (enum machine_mode from
,
14946 enum machine_mode to
,
14947 enum reg_class rclass
)
14949 bool ret
= rs6000_cannot_change_mode_class (from
, to
, rclass
);
14952 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14953 "to = %s, rclass = %s\n",
14954 ret
? "true" : "false",
14955 GET_MODE_NAME (from
), GET_MODE_NAME (to
),
14956 reg_class_names
[rclass
]);
14961 /* Given a comparison operation, return the bit number in CCR to test. We
14962 know this is a valid comparison.
14964 SCC_P is 1 if this is for an scc. That means that %D will have been
14965 used instead of %C, so the bits will be in different places.
14967 Return -1 if OP isn't a valid comparison for some reason. */
14970 ccr_bit (rtx op
, int scc_p
)
14972 enum rtx_code code
= GET_CODE (op
);
14973 enum machine_mode cc_mode
;
14978 if (!COMPARISON_P (op
))
14981 reg
= XEXP (op
, 0);
14983 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
14985 cc_mode
= GET_MODE (reg
);
14986 cc_regnum
= REGNO (reg
);
14987 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
14989 validate_condition_mode (code
, cc_mode
);
14991 /* When generating a sCOND operation, only positive conditions are
14994 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
14995 || code
== GTU
|| code
== LTU
);
15000 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
15002 return base_bit
+ 2;
15003 case GT
: case GTU
: case UNLE
:
15004 return base_bit
+ 1;
15005 case LT
: case LTU
: case UNGE
:
15007 case ORDERED
: case UNORDERED
:
15008 return base_bit
+ 3;
15011 /* If scc, we will have done a cror to put the bit in the
15012 unordered position. So test that bit. For integer, this is ! LT
15013 unless this is an scc insn. */
15014 return scc_p
? base_bit
+ 3 : base_bit
;
15017 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
15020 gcc_unreachable ();
15024 /* Return the GOT register. */
15027 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
15029 /* The second flow pass currently (June 1999) can't update
15030 regs_ever_live without disturbing other parts of the compiler, so
15031 update it here to make the prolog/epilogue code happy. */
15032 if (!can_create_pseudo_p ()
15033 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
15034 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
15036 crtl
->uses_pic_offset_table
= 1;
15038 return pic_offset_table_rtx
;
15041 static rs6000_stack_t stack_info
;
15043 /* Function to init struct machine_function.
15044 This will be called, via a pointer variable,
15045 from push_function_context. */
15047 static struct machine_function
*
15048 rs6000_init_machine_status (void)
15050 stack_info
.reload_completed
= 0;
15051 return ggc_alloc_cleared_machine_function ();
15054 /* These macros test for integers and extract the low-order bits. */
15056 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15057 && GET_MODE (X) == VOIDmode)
15059 #define INT_LOWPART(X) \
15060 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15063 extract_MB (rtx op
)
15066 unsigned long val
= INT_LOWPART (op
);
15068 /* If the high bit is zero, the value is the first 1 bit we find
15070 if ((val
& 0x80000000) == 0)
15072 gcc_assert (val
& 0xffffffff);
15075 while (((val
<<= 1) & 0x80000000) == 0)
15080 /* If the high bit is set and the low bit is not, or the mask is all
15081 1's, the value is zero. */
15082 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
15085 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15088 while (((val
>>= 1) & 1) != 0)
15095 extract_ME (rtx op
)
15098 unsigned long val
= INT_LOWPART (op
);
15100 /* If the low bit is zero, the value is the first 1 bit we find from
15102 if ((val
& 1) == 0)
15104 gcc_assert (val
& 0xffffffff);
15107 while (((val
>>= 1) & 1) == 0)
15113 /* If the low bit is set and the high bit is not, or the mask is all
15114 1's, the value is 31. */
15115 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
15118 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15121 while (((val
<<= 1) & 0x80000000) != 0)
15127 /* Locate some local-dynamic symbol still in use by this function
15128 so that we can print its name in some tls_ld pattern. */
15130 static const char *
15131 rs6000_get_some_local_dynamic_name (void)
15135 if (cfun
->machine
->some_ld_name
)
15136 return cfun
->machine
->some_ld_name
;
15138 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15140 && for_each_rtx (&PATTERN (insn
),
15141 rs6000_get_some_local_dynamic_name_1
, 0))
15142 return cfun
->machine
->some_ld_name
;
15144 gcc_unreachable ();
15147 /* Helper function for rs6000_get_some_local_dynamic_name. */
15150 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
15154 if (GET_CODE (x
) == SYMBOL_REF
)
15156 const char *str
= XSTR (x
, 0);
15157 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
15159 cfun
->machine
->some_ld_name
= str
;
15167 /* Write out a function code label. */
15170 rs6000_output_function_entry (FILE *file
, const char *fname
)
15172 if (fname
[0] != '.')
15174 switch (DEFAULT_ABI
)
15177 gcc_unreachable ();
15183 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
15192 RS6000_OUTPUT_BASENAME (file
, fname
);
15195 /* Print an operand. Recognize special options, documented below. */
15198 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15199 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15201 #define SMALL_DATA_RELOC "sda21"
15202 #define SMALL_DATA_REG 0
15206 print_operand (FILE *file
, rtx x
, int code
)
15210 unsigned HOST_WIDE_INT uval
;
15215 /* Write out an instruction after the call which may be replaced
15216 with glue code by the loader. This depends on the AIX version. */
15217 asm_fprintf (file
, RS6000_CALL_GLUE
);
15220 /* %a is output_address. */
15223 /* If X is a constant integer whose low-order 5 bits are zero,
15224 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15225 in the AIX assembler where "sri" with a zero shift count
15226 writes a trash instruction. */
15227 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
15234 /* If constant, low-order 16 bits of constant, unsigned.
15235 Otherwise, write normally. */
15237 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
15239 print_operand (file
, x
, 0);
15243 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15244 for 64-bit mask direction. */
15245 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
15248 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15252 /* X is a CR register. Print the number of the GT bit of the CR. */
15253 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15254 output_operand_lossage ("invalid %%c value");
15256 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
15260 /* Like 'J' but get to the GT bit only. */
15261 gcc_assert (GET_CODE (x
) == REG
);
15263 /* Bit 1 is GT bit. */
15264 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
15266 /* Add one for shift count in rlinm for scc. */
15267 fprintf (file
, "%d", i
+ 1);
15271 /* X is a CR register. Print the number of the EQ bit of the CR */
15272 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15273 output_operand_lossage ("invalid %%E value");
15275 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
15279 /* X is a CR register. Print the shift count needed to move it
15280 to the high-order four bits. */
15281 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15282 output_operand_lossage ("invalid %%f value");
15284 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
15288 /* Similar, but print the count for the rotate in the opposite
15290 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15291 output_operand_lossage ("invalid %%F value");
15293 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
15297 /* X is a constant integer. If it is negative, print "m",
15298 otherwise print "z". This is to make an aze or ame insn. */
15299 if (GET_CODE (x
) != CONST_INT
)
15300 output_operand_lossage ("invalid %%G value");
15301 else if (INTVAL (x
) >= 0)
15308 /* If constant, output low-order five bits. Otherwise, write
15311 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
15313 print_operand (file
, x
, 0);
15317 /* If constant, output low-order six bits. Otherwise, write
15320 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
15322 print_operand (file
, x
, 0);
15326 /* Print `i' if this is a constant, else nothing. */
15332 /* Write the bit number in CCR for jump. */
15333 i
= ccr_bit (x
, 0);
15335 output_operand_lossage ("invalid %%j code");
15337 fprintf (file
, "%d", i
);
15341 /* Similar, but add one for shift count in rlinm for scc and pass
15342 scc flag to `ccr_bit'. */
15343 i
= ccr_bit (x
, 1);
15345 output_operand_lossage ("invalid %%J code");
15347 /* If we want bit 31, write a shift count of zero, not 32. */
15348 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15352 /* X must be a constant. Write the 1's complement of the
15355 output_operand_lossage ("invalid %%k value");
15357 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
15361 /* X must be a symbolic constant on ELF. Write an
15362 expression suitable for an 'addi' that adds in the low 16
15363 bits of the MEM. */
15364 if (GET_CODE (x
) == CONST
)
15366 if (GET_CODE (XEXP (x
, 0)) != PLUS
15367 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
15368 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
15369 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
15370 output_operand_lossage ("invalid %%K value");
15372 print_operand_address (file
, x
);
15373 fputs ("@l", file
);
15376 /* %l is output_asm_label. */
15379 /* Write second word of DImode or DFmode reference. Works on register
15380 or non-indexed memory only. */
15381 if (GET_CODE (x
) == REG
)
15382 fputs (reg_names
[REGNO (x
) + 1], file
);
15383 else if (GET_CODE (x
) == MEM
)
15385 /* Handle possible auto-increment. Since it is pre-increment and
15386 we have already done it, we can just use an offset of word. */
15387 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15388 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15389 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15391 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15392 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15395 output_address (XEXP (adjust_address_nv (x
, SImode
,
15399 if (small_data_operand (x
, GET_MODE (x
)))
15400 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15401 reg_names
[SMALL_DATA_REG
]);
15406 /* MB value for a mask operand. */
15407 if (! mask_operand (x
, SImode
))
15408 output_operand_lossage ("invalid %%m value");
15410 fprintf (file
, "%d", extract_MB (x
));
15414 /* ME value for a mask operand. */
15415 if (! mask_operand (x
, SImode
))
15416 output_operand_lossage ("invalid %%M value");
15418 fprintf (file
, "%d", extract_ME (x
));
15421 /* %n outputs the negative of its operand. */
15424 /* Write the number of elements in the vector times 4. */
15425 if (GET_CODE (x
) != PARALLEL
)
15426 output_operand_lossage ("invalid %%N value");
15428 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
15432 /* Similar, but subtract 1 first. */
15433 if (GET_CODE (x
) != PARALLEL
)
15434 output_operand_lossage ("invalid %%O value");
15436 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
15440 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15442 || INT_LOWPART (x
) < 0
15443 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
15444 output_operand_lossage ("invalid %%p value");
15446 fprintf (file
, "%d", i
);
15450 /* The operand must be an indirect memory reference. The result
15451 is the register name. */
15452 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
15453 || REGNO (XEXP (x
, 0)) >= 32)
15454 output_operand_lossage ("invalid %%P value");
15456 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
15460 /* This outputs the logical code corresponding to a boolean
15461 expression. The expression may have one or both operands
15462 negated (if one, only the first one). For condition register
15463 logical operations, it will also treat the negated
15464 CR codes as NOTs, but not handle NOTs of them. */
15466 const char *const *t
= 0;
15468 enum rtx_code code
= GET_CODE (x
);
15469 static const char * const tbl
[3][3] = {
15470 { "and", "andc", "nor" },
15471 { "or", "orc", "nand" },
15472 { "xor", "eqv", "xor" } };
15476 else if (code
== IOR
)
15478 else if (code
== XOR
)
15481 output_operand_lossage ("invalid %%q value");
15483 if (GET_CODE (XEXP (x
, 0)) != NOT
)
15487 if (GET_CODE (XEXP (x
, 1)) == NOT
)
15505 /* X is a CR register. Print the mask for `mtcrf'. */
15506 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15507 output_operand_lossage ("invalid %%R value");
15509 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
15513 /* Low 5 bits of 32 - value */
15515 output_operand_lossage ("invalid %%s value");
15517 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
15521 /* PowerPC64 mask position. All 0's is excluded.
15522 CONST_INT 32-bit mask is considered sign-extended so any
15523 transition must occur within the CONST_INT, not on the boundary. */
15524 if (! mask64_operand (x
, DImode
))
15525 output_operand_lossage ("invalid %%S value");
15527 uval
= INT_LOWPART (x
);
15529 if (uval
& 1) /* Clear Left */
15531 #if HOST_BITS_PER_WIDE_INT > 64
15532 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
15536 else /* Clear Right */
15539 #if HOST_BITS_PER_WIDE_INT > 64
15540 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
15546 gcc_assert (i
>= 0);
15547 fprintf (file
, "%d", i
);
15551 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15552 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
15554 /* Bit 3 is OV bit. */
15555 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
15557 /* If we want bit 31, write a shift count of zero, not 32. */
15558 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15562 /* Print the symbolic name of a branch target register. */
15563 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
15564 && REGNO (x
) != CTR_REGNO
))
15565 output_operand_lossage ("invalid %%T value");
15566 else if (REGNO (x
) == LR_REGNO
)
15567 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
15569 fputs ("ctr", file
);
15573 /* High-order 16 bits of constant for use in unsigned operand. */
15575 output_operand_lossage ("invalid %%u value");
15577 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
15578 (INT_LOWPART (x
) >> 16) & 0xffff);
15582 /* High-order 16 bits of constant for use in signed operand. */
15584 output_operand_lossage ("invalid %%v value");
15586 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
15587 (INT_LOWPART (x
) >> 16) & 0xffff);
15591 /* Print `u' if this has an auto-increment or auto-decrement. */
15592 if (GET_CODE (x
) == MEM
15593 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
15594 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
15595 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
15600 /* Print the trap code for this operand. */
15601 switch (GET_CODE (x
))
15604 fputs ("eq", file
); /* 4 */
15607 fputs ("ne", file
); /* 24 */
15610 fputs ("lt", file
); /* 16 */
15613 fputs ("le", file
); /* 20 */
15616 fputs ("gt", file
); /* 8 */
15619 fputs ("ge", file
); /* 12 */
15622 fputs ("llt", file
); /* 2 */
15625 fputs ("lle", file
); /* 6 */
15628 fputs ("lgt", file
); /* 1 */
15631 fputs ("lge", file
); /* 5 */
15634 gcc_unreachable ();
15639 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15642 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
15643 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
15645 print_operand (file
, x
, 0);
15649 /* MB value for a PowerPC64 rldic operand. */
15650 val
= (GET_CODE (x
) == CONST_INT
15651 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
15656 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
15657 if ((val
<<= 1) < 0)
15660 #if HOST_BITS_PER_WIDE_INT == 32
15661 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
15662 i
+= 32; /* zero-extend high-part was all 0's */
15663 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
15665 val
= CONST_DOUBLE_LOW (x
);
15671 for ( ; i
< 64; i
++)
15672 if ((val
<<= 1) < 0)
15677 fprintf (file
, "%d", i
+ 1);
15681 /* X is a FPR or Altivec register used in a VSX context. */
15682 if (GET_CODE (x
) != REG
|| !VSX_REGNO_P (REGNO (x
)))
15683 output_operand_lossage ("invalid %%x value");
15686 int reg
= REGNO (x
);
15687 int vsx_reg
= (FP_REGNO_P (reg
)
15689 : reg
- FIRST_ALTIVEC_REGNO
+ 32);
15691 #ifdef TARGET_REGNAMES
15692 if (TARGET_REGNAMES
)
15693 fprintf (file
, "%%vs%d", vsx_reg
);
15696 fprintf (file
, "%d", vsx_reg
);
15701 if (GET_CODE (x
) == MEM
15702 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
15703 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
15704 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
15709 /* Like 'L', for third word of TImode */
15710 if (GET_CODE (x
) == REG
)
15711 fputs (reg_names
[REGNO (x
) + 2], file
);
15712 else if (GET_CODE (x
) == MEM
)
15714 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15715 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15716 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
15717 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15718 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
15720 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
15721 if (small_data_operand (x
, GET_MODE (x
)))
15722 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15723 reg_names
[SMALL_DATA_REG
]);
15728 /* X is a SYMBOL_REF. Write out the name preceded by a
15729 period and without any trailing data in brackets. Used for function
15730 names. If we are configured for System V (or the embedded ABI) on
15731 the PowerPC, do not emit the period, since those systems do not use
15732 TOCs and the like. */
15733 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
15735 /* Mark the decl as referenced so that cgraph will output the
15737 if (SYMBOL_REF_DECL (x
))
15738 mark_decl_referenced (SYMBOL_REF_DECL (x
));
15740 /* For macho, check to see if we need a stub. */
15743 const char *name
= XSTR (x
, 0);
15745 if (darwin_emit_branch_islands
15746 && MACHOPIC_INDIRECT
15747 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
15748 name
= machopic_indirection_name (x
, /*stub_p=*/true);
15750 assemble_name (file
, name
);
15752 else if (!DOT_SYMBOLS
)
15753 assemble_name (file
, XSTR (x
, 0));
15755 rs6000_output_function_entry (file
, XSTR (x
, 0));
15759 /* Like 'L', for last word of TImode. */
15760 if (GET_CODE (x
) == REG
)
15761 fputs (reg_names
[REGNO (x
) + 3], file
);
15762 else if (GET_CODE (x
) == MEM
)
15764 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15765 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15766 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
15767 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15768 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
15770 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
15771 if (small_data_operand (x
, GET_MODE (x
)))
15772 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15773 reg_names
[SMALL_DATA_REG
]);
15777 /* Print AltiVec or SPE memory operand. */
15782 gcc_assert (GET_CODE (x
) == MEM
);
15786 /* Ugly hack because %y is overloaded. */
15787 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
15788 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
15789 || GET_MODE (x
) == TFmode
15790 || GET_MODE (x
) == TImode
))
15792 /* Handle [reg]. */
15793 if (GET_CODE (tmp
) == REG
)
15795 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
15798 /* Handle [reg+UIMM]. */
15799 else if (GET_CODE (tmp
) == PLUS
&&
15800 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
15804 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
15806 x
= INTVAL (XEXP (tmp
, 1));
15807 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
15811 /* Fall through. Must be [reg+reg]. */
15813 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x
))
15814 && GET_CODE (tmp
) == AND
15815 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
15816 && INTVAL (XEXP (tmp
, 1)) == -16)
15817 tmp
= XEXP (tmp
, 0);
15818 else if (VECTOR_MEM_VSX_P (GET_MODE (x
))
15819 && GET_CODE (tmp
) == PRE_MODIFY
)
15820 tmp
= XEXP (tmp
, 1);
15821 if (GET_CODE (tmp
) == REG
)
15822 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
15825 if (!GET_CODE (tmp
) == PLUS
15826 || !REG_P (XEXP (tmp
, 0))
15827 || !REG_P (XEXP (tmp
, 1)))
15829 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15833 if (REGNO (XEXP (tmp
, 0)) == 0)
15834 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
15835 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
15837 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
15838 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
15844 if (GET_CODE (x
) == REG
)
15845 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
15846 else if (GET_CODE (x
) == MEM
)
15848 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15849 know the width from the mode. */
15850 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
15851 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
15852 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
15853 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15854 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
15855 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
15856 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15857 output_address (XEXP (XEXP (x
, 0), 1));
15859 output_address (XEXP (x
, 0));
15863 if (toc_relative_expr_p (x
))
15864 /* This hack along with a corresponding hack in
15865 rs6000_output_addr_const_extra arranges to output addends
15866 where the assembler expects to find them. eg.
15867 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
15868 without this hack would be output as "x@toc+4". We
15870 output_addr_const (file
, tocrel_base
);
15872 output_addr_const (file
, x
);
15877 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
15881 output_operand_lossage ("invalid %%xn code");
15885 /* Print the address of an operand. */
15888 print_operand_address (FILE *file
, rtx x
)
15890 if (GET_CODE (x
) == REG
)
15891 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
15892 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
15893 || GET_CODE (x
) == LABEL_REF
)
15895 output_addr_const (file
, x
);
15896 if (small_data_operand (x
, GET_MODE (x
)))
15897 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15898 reg_names
[SMALL_DATA_REG
]);
15900 gcc_assert (!TARGET_TOC
);
15902 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
15904 gcc_assert (REG_P (XEXP (x
, 0)));
15905 if (REGNO (XEXP (x
, 0)) == 0)
15906 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
15907 reg_names
[ REGNO (XEXP (x
, 0)) ]);
15909 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
15910 reg_names
[ REGNO (XEXP (x
, 1)) ]);
15912 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
15913 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
15914 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
15916 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
15917 && CONSTANT_P (XEXP (x
, 1)))
15919 fprintf (file
, "lo16(");
15920 output_addr_const (file
, XEXP (x
, 1));
15921 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
15924 else if (legitimate_constant_pool_address_p (x
, QImode
, true))
15926 /* This hack along with a corresponding hack in
15927 rs6000_output_addr_const_extra arranges to output addends
15928 where the assembler expects to find them. eg.
15930 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15931 without this hack would be output as "x@toc+8@l(9)". We
15932 want "x+8@toc@l(9)". */
15933 output_addr_const (file
, tocrel_base
);
15934 if (GET_CODE (x
) == LO_SUM
)
15935 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
15937 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
15940 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
15941 && CONSTANT_P (XEXP (x
, 1)))
15943 output_addr_const (file
, XEXP (x
, 1));
15944 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
15948 gcc_unreachable ();
15951 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
15954 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
15956 if (GET_CODE (x
) == UNSPEC
)
15957 switch (XINT (x
, 1))
15959 case UNSPEC_TOCREL
:
15960 gcc_assert (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
);
15961 output_addr_const (file
, XVECEXP (x
, 0, 0));
15962 if (x
== tocrel_base
&& tocrel_offset
!= const0_rtx
)
15964 if (INTVAL (tocrel_offset
) >= 0)
15965 fprintf (file
, "+");
15966 output_addr_const (file
, tocrel_offset
);
15968 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
15971 assemble_name (file
, toc_label_name
);
15973 else if (TARGET_ELF
)
15974 fputs ("@toc", file
);
15978 case UNSPEC_MACHOPIC_OFFSET
:
15979 output_addr_const (file
, XVECEXP (x
, 0, 0));
15981 machopic_output_function_base_name (file
);
15988 /* Target hook for assembling integer objects. The PowerPC version has
15989 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15990 is defined. It also needs to handle DI-mode objects on 64-bit
15994 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
15996 #ifdef RELOCATABLE_NEEDS_FIXUP
15997 /* Special handling for SI values. */
15998 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
16000 static int recurse
= 0;
16002 /* For -mrelocatable, we mark all addresses that need to be fixed up
16003 in the .fixup section. */
16004 if (TARGET_RELOCATABLE
16005 && in_section
!= toc_section
16006 && in_section
!= text_section
16007 && !unlikely_text_section_p (in_section
)
16009 && GET_CODE (x
) != CONST_INT
16010 && GET_CODE (x
) != CONST_DOUBLE
16016 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
16018 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
16019 fprintf (asm_out_file
, "\t.long\t(");
16020 output_addr_const (asm_out_file
, x
);
16021 fprintf (asm_out_file
, ")@fixup\n");
16022 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
16023 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
16024 fprintf (asm_out_file
, "\t.long\t");
16025 assemble_name (asm_out_file
, buf
);
16026 fprintf (asm_out_file
, "\n\t.previous\n");
16030 /* Remove initial .'s to turn a -mcall-aixdesc function
16031 address into the address of the descriptor, not the function
16033 else if (GET_CODE (x
) == SYMBOL_REF
16034 && XSTR (x
, 0)[0] == '.'
16035 && DEFAULT_ABI
== ABI_AIX
)
16037 const char *name
= XSTR (x
, 0);
16038 while (*name
== '.')
16041 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
16045 #endif /* RELOCATABLE_NEEDS_FIXUP */
16046 return default_assemble_integer (x
, size
, aligned_p
);
16049 #if defined (HAVE_GAS_HIDDEN) && !defined (TARGET_MACHO)
16050 /* Emit an assembler directive to set symbol visibility for DECL to
16051 VISIBILITY_TYPE. */
16054 rs6000_assemble_visibility (tree decl
, int vis
)
16056 /* Functions need to have their entry point symbol visibility set as
16057 well as their descriptor symbol visibility. */
16058 if (DEFAULT_ABI
== ABI_AIX
16060 && TREE_CODE (decl
) == FUNCTION_DECL
)
16062 static const char * const visibility_types
[] = {
16063 NULL
, "internal", "hidden", "protected"
16066 const char *name
, *type
;
16068 name
= ((* targetm
.strip_name_encoding
)
16069 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
16070 type
= visibility_types
[vis
];
16072 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
16073 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
16076 default_assemble_visibility (decl
, vis
);
16081 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
16083 /* Reversal of FP compares takes care -- an ordered compare
16084 becomes an unordered compare and vice versa. */
16085 if (mode
== CCFPmode
16086 && (!flag_finite_math_only
16087 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
16088 || code
== UNEQ
|| code
== LTGT
))
16089 return reverse_condition_maybe_unordered (code
);
16091 return reverse_condition (code
);
16094 /* Generate a compare for CODE. Return a brand-new rtx that
16095 represents the result of the compare. */
16098 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
16100 enum machine_mode comp_mode
;
16101 rtx compare_result
;
16102 enum rtx_code code
= GET_CODE (cmp
);
16103 rtx op0
= XEXP (cmp
, 0);
16104 rtx op1
= XEXP (cmp
, 1);
16106 if (FLOAT_MODE_P (mode
))
16107 comp_mode
= CCFPmode
;
16108 else if (code
== GTU
|| code
== LTU
16109 || code
== GEU
|| code
== LEU
)
16110 comp_mode
= CCUNSmode
;
16111 else if ((code
== EQ
|| code
== NE
)
16112 && GET_CODE (op0
) == SUBREG
16113 && GET_CODE (op1
) == SUBREG
16114 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
16115 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
16116 /* These are unsigned values, perhaps there will be a later
16117 ordering compare that can be shared with this one.
16118 Unfortunately we cannot detect the signedness of the operands
16119 for non-subregs. */
16120 comp_mode
= CCUNSmode
;
16122 comp_mode
= CCmode
;
16124 /* First, the compare. */
16125 compare_result
= gen_reg_rtx (comp_mode
);
16127 /* E500 FP compare instructions on the GPRs. Yuck! */
16128 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16129 && FLOAT_MODE_P (mode
))
16131 rtx cmp
, or_result
, compare_result2
;
16132 enum machine_mode op_mode
= GET_MODE (op0
);
16134 if (op_mode
== VOIDmode
)
16135 op_mode
= GET_MODE (op1
);
16137 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16138 This explains the following mess. */
16142 case EQ
: case UNEQ
: case NE
: case LTGT
:
16146 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16147 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
16148 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
16152 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16153 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
16154 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
16158 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16159 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
16160 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
16164 gcc_unreachable ();
16168 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
16172 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16173 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
16174 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
16178 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16179 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
16180 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
16184 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16185 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
16186 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
16190 gcc_unreachable ();
16194 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
16198 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16199 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
16200 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
16204 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16205 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
16206 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
16210 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16211 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
16212 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
16216 gcc_unreachable ();
16220 gcc_unreachable ();
16223 /* Synthesize LE and GE from LT/GT || EQ. */
16224 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
16230 case LE
: code
= LT
; break;
16231 case GE
: code
= GT
; break;
16232 case LEU
: code
= LT
; break;
16233 case GEU
: code
= GT
; break;
16234 default: gcc_unreachable ();
16237 compare_result2
= gen_reg_rtx (CCFPmode
);
16243 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16244 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
16245 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
16249 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16250 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
16251 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
16255 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16256 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
16257 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
16261 gcc_unreachable ();
16265 /* OR them together. */
16266 or_result
= gen_reg_rtx (CCFPmode
);
16267 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
16269 compare_result
= or_result
;
16274 if (code
== NE
|| code
== LTGT
)
16284 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16285 CLOBBERs to match cmptf_internal2 pattern. */
16286 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
16287 && GET_MODE (op0
) == TFmode
16288 && !TARGET_IEEEQUAD
16289 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
16290 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
16292 gen_rtx_SET (VOIDmode
,
16294 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
16295 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16296 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16297 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16298 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16299 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16300 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16301 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16302 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16303 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (Pmode
)))));
16304 else if (GET_CODE (op1
) == UNSPEC
16305 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
16307 rtx op1b
= XVECEXP (op1
, 0, 0);
16308 comp_mode
= CCEQmode
;
16309 compare_result
= gen_reg_rtx (CCEQmode
);
16311 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
16313 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
16316 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
16317 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
16320 /* Some kinds of FP comparisons need an OR operation;
16321 under flag_finite_math_only we don't bother. */
16322 if (FLOAT_MODE_P (mode
)
16323 && !flag_finite_math_only
16324 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
16325 && (code
== LE
|| code
== GE
16326 || code
== UNEQ
|| code
== LTGT
16327 || code
== UNGT
|| code
== UNLT
))
16329 enum rtx_code or1
, or2
;
16330 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
16331 rtx or_result
= gen_reg_rtx (CCEQmode
);
16335 case LE
: or1
= LT
; or2
= EQ
; break;
16336 case GE
: or1
= GT
; or2
= EQ
; break;
16337 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
16338 case LTGT
: or1
= LT
; or2
= GT
; break;
16339 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
16340 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
16341 default: gcc_unreachable ();
16343 validate_condition_mode (or1
, comp_mode
);
16344 validate_condition_mode (or2
, comp_mode
);
16345 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
16346 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
16347 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
16348 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
16350 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
16352 compare_result
= or_result
;
16356 validate_condition_mode (code
, GET_MODE (compare_result
));
16358 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
16362 /* Emit the RTL for an sISEL pattern. */
16365 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx operands
[])
16367 rs6000_emit_int_cmove (operands
[0], operands
[1], const1_rtx
, const0_rtx
);
16371 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
16374 enum machine_mode op_mode
;
16375 enum rtx_code cond_code
;
16376 rtx result
= operands
[0];
16378 if (TARGET_ISEL
&& (mode
== SImode
|| mode
== DImode
))
16380 rs6000_emit_sISEL (mode
, operands
);
16384 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
16385 cond_code
= GET_CODE (condition_rtx
);
16387 if (FLOAT_MODE_P (mode
)
16388 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16392 PUT_MODE (condition_rtx
, SImode
);
16393 t
= XEXP (condition_rtx
, 0);
16395 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
16397 if (cond_code
== NE
)
16398 emit_insn (gen_e500_flip_gt_bit (t
, t
));
16400 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
16404 if (cond_code
== NE
16405 || cond_code
== GE
|| cond_code
== LE
16406 || cond_code
== GEU
|| cond_code
== LEU
16407 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
16409 rtx not_result
= gen_reg_rtx (CCEQmode
);
16410 rtx not_op
, rev_cond_rtx
;
16411 enum machine_mode cc_mode
;
16413 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
16415 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
16416 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
16417 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
16418 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
16419 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
16422 op_mode
= GET_MODE (XEXP (operands
[1], 0));
16423 if (op_mode
== VOIDmode
)
16424 op_mode
= GET_MODE (XEXP (operands
[1], 1));
16426 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
16428 PUT_MODE (condition_rtx
, DImode
);
16429 convert_move (result
, condition_rtx
, 0);
16433 PUT_MODE (condition_rtx
, SImode
);
16434 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
16438 /* Emit a branch of kind CODE to location LOC. */
16441 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
16443 rtx condition_rtx
, loc_ref
;
16445 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
16446 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
16447 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
16448 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
16449 loc_ref
, pc_rtx
)));
16452 /* Return the string to output a conditional branch to LABEL, which is
16453 the operand number of the label, or -1 if the branch is really a
16454 conditional return.
16456 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16457 condition code register and its mode specifies what kind of
16458 comparison we made.
16460 REVERSED is nonzero if we should reverse the sense of the comparison.
16462 INSN is the insn. */
16465 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
16467 static char string
[64];
16468 enum rtx_code code
= GET_CODE (op
);
16469 rtx cc_reg
= XEXP (op
, 0);
16470 enum machine_mode mode
= GET_MODE (cc_reg
);
16471 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
16472 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
16473 int really_reversed
= reversed
^ need_longbranch
;
16479 validate_condition_mode (code
, mode
);
16481 /* Work out which way this really branches. We could use
16482 reverse_condition_maybe_unordered here always but this
16483 makes the resulting assembler clearer. */
16484 if (really_reversed
)
16486 /* Reversal of FP compares takes care -- an ordered compare
16487 becomes an unordered compare and vice versa. */
16488 if (mode
== CCFPmode
)
16489 code
= reverse_condition_maybe_unordered (code
);
16491 code
= reverse_condition (code
);
16494 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
16496 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16501 /* Opposite of GT. */
16510 gcc_unreachable ();
16516 /* Not all of these are actually distinct opcodes, but
16517 we distinguish them for clarity of the resulting assembler. */
16518 case NE
: case LTGT
:
16519 ccode
= "ne"; break;
16520 case EQ
: case UNEQ
:
16521 ccode
= "eq"; break;
16523 ccode
= "ge"; break;
16524 case GT
: case GTU
: case UNGT
:
16525 ccode
= "gt"; break;
16527 ccode
= "le"; break;
16528 case LT
: case LTU
: case UNLT
:
16529 ccode
= "lt"; break;
16530 case UNORDERED
: ccode
= "un"; break;
16531 case ORDERED
: ccode
= "nu"; break;
16532 case UNGE
: ccode
= "nl"; break;
16533 case UNLE
: ccode
= "ng"; break;
16535 gcc_unreachable ();
16538 /* Maybe we have a guess as to how likely the branch is.
16539 The old mnemonics don't have a way to specify this information. */
16541 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
16542 if (note
!= NULL_RTX
)
16544 /* PROB is the difference from 50%. */
16545 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
16547 /* Only hint for highly probable/improbable branches on newer
16548 cpus as static prediction overrides processor dynamic
16549 prediction. For older cpus we may as well always hint, but
16550 assume not taken for branches that are very close to 50% as a
16551 mispredicted taken branch is more expensive than a
16552 mispredicted not-taken branch. */
16553 if (rs6000_always_hint
16554 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
16555 && br_prob_note_reliable_p (note
)))
16557 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
16558 && ((prob
> 0) ^ need_longbranch
))
16566 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
16568 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
16570 /* We need to escape any '%' characters in the reg_names string.
16571 Assume they'd only be the first character.... */
16572 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
16574 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
16578 /* If the branch distance was too far, we may have to use an
16579 unconditional branch to go the distance. */
16580 if (need_longbranch
)
16581 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
16583 s
+= sprintf (s
, ",%s", label
);
16589 /* Return the string to flip the GT bit on a CR. */
16591 output_e500_flip_gt_bit (rtx dst
, rtx src
)
16593 static char string
[64];
16596 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
16597 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
16600 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
16601 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
16603 sprintf (string
, "crnot %d,%d", a
, b
);
16607 /* Return insn for VSX or Altivec comparisons. */
16610 rs6000_emit_vector_compare_inner (enum rtx_code code
, rtx op0
, rtx op1
)
16613 enum machine_mode mode
= GET_MODE (op0
);
16621 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
16627 mask
= gen_reg_rtx (mode
);
16628 emit_insn (gen_rtx_SET (VOIDmode
,
16630 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
16637 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16638 DMODE is expected destination mode. This is a recursive function. */
16641 rs6000_emit_vector_compare (enum rtx_code rcode
,
16643 enum machine_mode dmode
)
16646 bool swap_operands
= false;
16647 bool try_again
= false;
16649 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode
));
16650 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
16652 /* See if the comparison works as is. */
16653 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
16661 swap_operands
= true;
16666 swap_operands
= true;
16674 /* Invert condition and try again.
16675 e.g., A != B becomes ~(A==B). */
16677 enum rtx_code rev_code
;
16678 enum insn_code nor_code
;
16681 rev_code
= reverse_condition_maybe_unordered (rcode
);
16682 if (rev_code
== UNKNOWN
)
16685 nor_code
= optab_handler (one_cmpl_optab
, dmode
);
16686 if (nor_code
== CODE_FOR_nothing
)
16689 mask2
= rs6000_emit_vector_compare (rev_code
, op0
, op1
, dmode
);
16693 mask
= gen_reg_rtx (dmode
);
16694 emit_insn (GEN_FCN (nor_code
) (mask
, mask2
));
16702 /* Try GT/GTU/LT/LTU OR EQ */
16705 enum insn_code ior_code
;
16706 enum rtx_code new_code
;
16727 gcc_unreachable ();
16730 ior_code
= optab_handler (ior_optab
, dmode
);
16731 if (ior_code
== CODE_FOR_nothing
)
16734 c_rtx
= rs6000_emit_vector_compare (new_code
, op0
, op1
, dmode
);
16738 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
, dmode
);
16742 mask
= gen_reg_rtx (dmode
);
16743 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
16761 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
16766 /* You only get two chances. */
16770 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16771 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16772 operands for the relation operation COND. */
16775 rs6000_emit_vector_cond_expr (rtx dest
, rtx op_true
, rtx op_false
,
16776 rtx cond
, rtx cc_op0
, rtx cc_op1
)
16778 enum machine_mode dest_mode
= GET_MODE (dest
);
16779 enum machine_mode mask_mode
= GET_MODE (cc_op0
);
16780 enum rtx_code rcode
= GET_CODE (cond
);
16781 enum machine_mode cc_mode
= CCmode
;
16785 bool invert_move
= false;
16787 if (VECTOR_UNIT_NONE_P (dest_mode
))
16790 gcc_assert (GET_MODE_SIZE (dest_mode
) == GET_MODE_SIZE (mask_mode
)
16791 && GET_MODE_NUNITS (dest_mode
) == GET_MODE_NUNITS (mask_mode
));
16795 /* Swap operands if we can, and fall back to doing the operation as
16796 specified, and doing a NOR to invert the test. */
16802 /* Invert condition and try again.
16803 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16804 invert_move
= true;
16805 rcode
= reverse_condition_maybe_unordered (rcode
);
16806 if (rcode
== UNKNOWN
)
16810 /* Mark unsigned tests with CCUNSmode. */
16815 cc_mode
= CCUNSmode
;
16822 /* Get the vector mask for the given relational operations. */
16823 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, mask_mode
);
16831 op_true
= op_false
;
16835 cond2
= gen_rtx_fmt_ee (NE
, cc_mode
, gen_lowpart (dest_mode
, mask
),
16836 CONST0_RTX (dest_mode
));
16837 emit_insn (gen_rtx_SET (VOIDmode
,
16839 gen_rtx_IF_THEN_ELSE (dest_mode
,
16846 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16847 operands of the last comparison is nonzero/true, FALSE_COND if it
16848 is zero/false. Return 0 if the hardware has no such operation. */
16851 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
16853 enum rtx_code code
= GET_CODE (op
);
16854 rtx op0
= XEXP (op
, 0);
16855 rtx op1
= XEXP (op
, 1);
16856 REAL_VALUE_TYPE c1
;
16857 enum machine_mode compare_mode
= GET_MODE (op0
);
16858 enum machine_mode result_mode
= GET_MODE (dest
);
16860 bool is_against_zero
;
16862 /* These modes should always match. */
16863 if (GET_MODE (op1
) != compare_mode
16864 /* In the isel case however, we can use a compare immediate, so
16865 op1 may be a small constant. */
16866 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
16868 if (GET_MODE (true_cond
) != result_mode
)
16870 if (GET_MODE (false_cond
) != result_mode
)
16873 /* First, work out if the hardware can do this at all, or
16874 if it's too slow.... */
16875 if (!FLOAT_MODE_P (compare_mode
))
16878 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
16881 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
16882 && SCALAR_FLOAT_MODE_P (compare_mode
))
16885 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
16887 /* A floating-point subtract might overflow, underflow, or produce
16888 an inexact result, thus changing the floating-point flags, so it
16889 can't be generated if we care about that. It's safe if one side
16890 of the construct is zero, since then no subtract will be
16892 if (SCALAR_FLOAT_MODE_P (compare_mode
)
16893 && flag_trapping_math
&& ! is_against_zero
)
16896 /* Eliminate half of the comparisons by switching operands, this
16897 makes the remaining code simpler. */
16898 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
16899 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
16901 code
= reverse_condition_maybe_unordered (code
);
16903 true_cond
= false_cond
;
16907 /* UNEQ and LTGT take four instructions for a comparison with zero,
16908 it'll probably be faster to use a branch here too. */
16909 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
16912 if (GET_CODE (op1
) == CONST_DOUBLE
)
16913 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
16915 /* We're going to try to implement comparisons by performing
16916 a subtract, then comparing against zero. Unfortunately,
16917 Inf - Inf is NaN which is not zero, and so if we don't
16918 know that the operand is finite and the comparison
16919 would treat EQ different to UNORDERED, we can't do it. */
16920 if (HONOR_INFINITIES (compare_mode
)
16921 && code
!= GT
&& code
!= UNGE
16922 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
16923 /* Constructs of the form (a OP b ? a : b) are safe. */
16924 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
16925 || (! rtx_equal_p (op0
, true_cond
)
16926 && ! rtx_equal_p (op1
, true_cond
))))
16929 /* At this point we know we can use fsel. */
16931 /* Reduce the comparison to a comparison against zero. */
16932 if (! is_against_zero
)
16934 temp
= gen_reg_rtx (compare_mode
);
16935 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
16936 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
16938 op1
= CONST0_RTX (compare_mode
);
16941 /* If we don't care about NaNs we can reduce some of the comparisons
16942 down to faster ones. */
16943 if (! HONOR_NANS (compare_mode
))
16949 true_cond
= false_cond
;
16962 /* Now, reduce everything down to a GE. */
16969 temp
= gen_reg_rtx (compare_mode
);
16970 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
16975 temp
= gen_reg_rtx (compare_mode
);
16976 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
16981 temp
= gen_reg_rtx (compare_mode
);
16982 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
16983 gen_rtx_NEG (compare_mode
,
16984 gen_rtx_ABS (compare_mode
, op0
))));
16989 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16990 temp
= gen_reg_rtx (result_mode
);
16991 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
16992 gen_rtx_IF_THEN_ELSE (result_mode
,
16993 gen_rtx_GE (VOIDmode
,
16995 true_cond
, false_cond
)));
16996 false_cond
= true_cond
;
16999 temp
= gen_reg_rtx (compare_mode
);
17000 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17005 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17006 temp
= gen_reg_rtx (result_mode
);
17007 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17008 gen_rtx_IF_THEN_ELSE (result_mode
,
17009 gen_rtx_GE (VOIDmode
,
17011 true_cond
, false_cond
)));
17012 true_cond
= false_cond
;
17015 temp
= gen_reg_rtx (compare_mode
);
17016 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17021 gcc_unreachable ();
17024 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
17025 gen_rtx_IF_THEN_ELSE (result_mode
,
17026 gen_rtx_GE (VOIDmode
,
17028 true_cond
, false_cond
)));
17032 /* Same as above, but for ints (isel). */
17035 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17037 rtx condition_rtx
, cr
;
17038 enum machine_mode mode
= GET_MODE (dest
);
17039 enum rtx_code cond_code
;
17040 rtx (*isel_func
) (rtx
, rtx
, rtx
, rtx
, rtx
);
17043 if (mode
!= SImode
&& (!TARGET_POWERPC64
|| mode
!= DImode
))
17046 /* We still have to do the compare, because isel doesn't do a
17047 compare, it just looks at the CRx bits set by a previous compare
17049 condition_rtx
= rs6000_generate_compare (op
, mode
);
17050 cond_code
= GET_CODE (condition_rtx
);
17051 cr
= XEXP (condition_rtx
, 0);
17052 signedp
= GET_MODE (cr
) == CCmode
;
17054 isel_func
= (mode
== SImode
17055 ? (signedp
? gen_isel_signed_si
: gen_isel_unsigned_si
)
17056 : (signedp
? gen_isel_signed_di
: gen_isel_unsigned_di
));
17060 case LT
: case GT
: case LTU
: case GTU
: case EQ
:
17061 /* isel handles these directly. */
17065 /* We need to swap the sense of the comparison. */
17068 true_cond
= false_cond
;
17070 PUT_CODE (condition_rtx
, reverse_condition (cond_code
));
17075 false_cond
= force_reg (mode
, false_cond
);
17076 if (true_cond
!= const0_rtx
)
17077 true_cond
= force_reg (mode
, true_cond
);
17079 emit_insn (isel_func (dest
, condition_rtx
, true_cond
, false_cond
, cr
));
17085 output_isel (rtx
*operands
)
17087 enum rtx_code code
;
17089 code
= GET_CODE (operands
[1]);
17091 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
17093 gcc_assert (GET_CODE (operands
[2]) == REG
17094 && GET_CODE (operands
[3]) == REG
);
17095 PUT_CODE (operands
[1], reverse_condition (code
));
17096 return "isel %0,%3,%2,%j1";
17099 return "isel %0,%2,%3,%j1";
17103 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
17105 enum machine_mode mode
= GET_MODE (op0
);
17109 /* VSX/altivec have direct min/max insns. */
17110 if ((code
== SMAX
|| code
== SMIN
)
17111 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
17112 || (mode
== SFmode
&& VECTOR_UNIT_VSX_P (DFmode
))))
17114 emit_insn (gen_rtx_SET (VOIDmode
,
17116 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17120 if (code
== SMAX
|| code
== SMIN
)
17125 if (code
== SMAX
|| code
== UMAX
)
17126 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17127 op0
, op1
, mode
, 0);
17129 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17130 op1
, op0
, mode
, 0);
17131 gcc_assert (target
);
17132 if (target
!= dest
)
17133 emit_move_insn (dest
, target
);
17136 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17137 COND is true. Mark the jump as unlikely to be taken. */
17140 emit_unlikely_jump (rtx cond
, rtx label
)
17142 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
17145 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
17146 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
17147 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
17150 /* A subroutine of the atomic operation splitters. Emit a load-locked
17151 instruction in MODE. */
17154 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
17156 rtx (*fn
) (rtx
, rtx
) = NULL
;
17161 fn
= gen_load_lockedsi
;
17164 fn
= gen_load_lockeddi
;
17167 gcc_unreachable ();
17169 emit_insn (fn (reg
, mem
));
17172 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17173 instruction in MODE. */
17176 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
17178 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
17183 fn
= gen_store_conditionalsi
;
17186 fn
= gen_store_conditionaldi
;
17189 gcc_unreachable ();
17192 /* Emit sync before stwcx. to address PPC405 Erratum. */
17193 if (PPC405_ERRATUM77
)
17194 emit_insn (gen_hwsync ());
17196 emit_insn (fn (res
, mem
, val
));
17199 /* Expand barriers before and after a load_locked/store_cond sequence. */
17202 rs6000_pre_atomic_barrier (enum memmodel model
)
17206 case MEMMODEL_RELAXED
:
17207 case MEMMODEL_CONSUME
:
17208 case MEMMODEL_ACQUIRE
:
17210 case MEMMODEL_RELEASE
:
17211 case MEMMODEL_ACQ_REL
:
17212 emit_insn (gen_lwsync ());
17214 case MEMMODEL_SEQ_CST
:
17215 emit_insn (gen_hwsync ());
17218 gcc_unreachable ();
17223 rs6000_post_atomic_barrier (enum memmodel model
)
17227 case MEMMODEL_RELAXED
:
17228 case MEMMODEL_CONSUME
:
17229 case MEMMODEL_RELEASE
:
17231 case MEMMODEL_ACQUIRE
:
17232 case MEMMODEL_ACQ_REL
:
17233 case MEMMODEL_SEQ_CST
:
17234 emit_insn (gen_isync ());
17237 gcc_unreachable ();
17241 /* A subroutine of the various atomic expanders. For sub-word operations,
17242 we must adjust things to operate on SImode. Given the original MEM,
17243 return a new aligned memory. Also build and return the quantities by
17244 which to shift and mask. */
17247 rs6000_adjust_atomic_subword (rtx orig_mem
, rtx
*pshift
, rtx
*pmask
)
17249 rtx addr
, align
, shift
, mask
, mem
;
17250 HOST_WIDE_INT shift_mask
;
17251 enum machine_mode mode
= GET_MODE (orig_mem
);
17253 /* For smaller modes, we have to implement this via SImode. */
17254 shift_mask
= (mode
== QImode
? 0x18 : 0x10);
17256 addr
= XEXP (orig_mem
, 0);
17257 addr
= force_reg (GET_MODE (addr
), addr
);
17259 /* Aligned memory containing subword. Generate a new memory. We
17260 do not want any of the existing MEM_ATTR data, as we're now
17261 accessing memory outside the original object. */
17262 align
= expand_simple_binop (Pmode
, AND
, addr
, GEN_INT (-4),
17263 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17264 mem
= gen_rtx_MEM (SImode
, align
);
17265 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (orig_mem
);
17266 if (MEM_ALIAS_SET (orig_mem
) == ALIAS_SET_MEMORY_BARRIER
)
17267 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
17269 /* Shift amount for subword relative to aligned word. */
17270 shift
= gen_reg_rtx (SImode
);
17271 addr
= gen_lowpart (SImode
, addr
);
17272 emit_insn (gen_rlwinm (shift
, addr
, GEN_INT (3), GEN_INT (shift_mask
)));
17273 shift
= expand_simple_binop (SImode
, XOR
, shift
, GEN_INT (shift_mask
),
17274 shift
, 1, OPTAB_LIB_WIDEN
);
17277 /* Mask for insertion. */
17278 mask
= expand_simple_binop (SImode
, ASHIFT
, GEN_INT (GET_MODE_MASK (mode
)),
17279 shift
, NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17285 /* A subroutine of the various atomic expanders. For sub-word operands,
17286 combine OLDVAL and NEWVAL via MASK. Returns a new pseduo. */
17289 rs6000_mask_atomic_subword (rtx oldval
, rtx newval
, rtx mask
)
17293 x
= gen_reg_rtx (SImode
);
17294 emit_insn (gen_rtx_SET (VOIDmode
, x
,
17295 gen_rtx_AND (SImode
,
17296 gen_rtx_NOT (SImode
, mask
),
17299 x
= expand_simple_binop (SImode
, IOR
, newval
, x
, x
, 1, OPTAB_LIB_WIDEN
);
17304 /* A subroutine of the various atomic expanders. For sub-word operands,
17305 extract WIDE to NARROW via SHIFT. */
17308 rs6000_finish_atomic_subword (rtx narrow
, rtx wide
, rtx shift
)
17310 wide
= expand_simple_binop (SImode
, LSHIFTRT
, wide
, shift
,
17311 wide
, 1, OPTAB_LIB_WIDEN
);
17312 emit_move_insn (narrow
, gen_lowpart (GET_MODE (narrow
), wide
));
17315 /* Expand an atomic compare and swap operation. */
17318 rs6000_expand_atomic_compare_and_swap (rtx operands
[])
17320 rtx boolval
, retval
, mem
, oldval
, newval
, cond
;
17321 rtx label1
, label2
, x
, mask
, shift
;
17322 enum machine_mode mode
;
17323 enum memmodel mod_s
, mod_f
;
17326 boolval
= operands
[0];
17327 retval
= operands
[1];
17329 oldval
= operands
[3];
17330 newval
= operands
[4];
17331 is_weak
= (INTVAL (operands
[5]) != 0);
17332 mod_s
= (enum memmodel
) INTVAL (operands
[6]);
17333 mod_f
= (enum memmodel
) INTVAL (operands
[7]);
17334 mode
= GET_MODE (mem
);
17336 mask
= shift
= NULL_RTX
;
17337 if (mode
== QImode
|| mode
== HImode
)
17339 mem
= rs6000_adjust_atomic_subword (mem
, &shift
, &mask
);
17341 /* Shift and mask OLDVAL into position with the word. */
17342 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
17343 oldval
= expand_simple_binop (SImode
, ASHIFT
, oldval
, shift
,
17344 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17346 /* Shift and mask NEWVAL into position within the word. */
17347 newval
= convert_modes (SImode
, mode
, newval
, 1);
17348 newval
= expand_simple_binop (SImode
, ASHIFT
, newval
, shift
,
17349 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17351 /* Prepare to adjust the return value. */
17352 retval
= gen_reg_rtx (SImode
);
17356 rs6000_pre_atomic_barrier (mod_s
);
17358 emit_move_insn (boolval
, const0_rtx
);
17363 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17364 emit_label (XEXP (label1
, 0));
17366 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17368 emit_load_locked (mode
, retval
, mem
);
17373 x
= expand_simple_binop (SImode
, AND
, retval
, mask
,
17374 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17377 x
= gen_rtx_NE (VOIDmode
, x
, oldval
);
17378 x
= rs6000_generate_compare (x
, mode
);
17379 emit_unlikely_jump (x
, label2
);
17383 x
= rs6000_mask_atomic_subword (retval
, newval
, mask
);
17385 cond
= gen_reg_rtx (CCmode
);
17386 emit_store_conditional (mode
, cond
, mem
, x
);
17390 /* ??? It's either this or an unlikely jump over (set bool 1). */
17391 x
= gen_rtx_EQ (SImode
, cond
, const0_rtx
);
17392 emit_insn (gen_rtx_SET (VOIDmode
, boolval
, x
));
17396 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17397 emit_unlikely_jump (x
, label1
);
17398 emit_move_insn (boolval
, const1_rtx
);
17401 if (mod_f
!= MEMMODEL_RELAXED
)
17402 emit_label (XEXP (label2
, 0));
17404 rs6000_post_atomic_barrier (mod_s
);
17406 if (mod_f
== MEMMODEL_RELAXED
)
17407 emit_label (XEXP (label2
, 0));
17410 rs6000_finish_atomic_subword (operands
[1], retval
, shift
);
17413 /* Expand an atomic exchange operation. */
17416 rs6000_expand_atomic_exchange (rtx operands
[])
17418 rtx retval
, mem
, val
, cond
;
17419 enum machine_mode mode
;
17420 enum memmodel model
;
17421 rtx label
, x
, mask
, shift
;
17423 retval
= operands
[0];
17426 model
= (enum memmodel
) INTVAL (operands
[3]);
17427 mode
= GET_MODE (mem
);
17429 mask
= shift
= NULL_RTX
;
17430 if (mode
== QImode
|| mode
== HImode
)
17432 mem
= rs6000_adjust_atomic_subword (mem
, &shift
, &mask
);
17434 /* Shift and mask VAL into position with the word. */
17435 val
= convert_modes (SImode
, mode
, val
, 1);
17436 val
= expand_simple_binop (SImode
, ASHIFT
, val
, shift
,
17437 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17439 /* Prepare to adjust the return value. */
17440 retval
= gen_reg_rtx (SImode
);
17444 rs6000_pre_atomic_barrier (model
);
17446 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17447 emit_label (XEXP (label
, 0));
17449 emit_load_locked (mode
, retval
, mem
);
17453 x
= rs6000_mask_atomic_subword (retval
, val
, mask
);
17455 cond
= gen_reg_rtx (CCmode
);
17456 emit_store_conditional (mode
, cond
, mem
, x
);
17458 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17459 emit_unlikely_jump (x
, label
);
17461 rs6000_post_atomic_barrier (model
);
17464 rs6000_finish_atomic_subword (operands
[0], retval
, shift
);
17467 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17468 to perform. MEM is the memory on which to operate. VAL is the second
17469 operand of the binary operator. BEFORE and AFTER are optional locations to
17470 return the value of MEM either before of after the operation. MODEL_RTX
17471 is a CONST_INT containing the memory model to use. */
17474 rs6000_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
17475 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
17477 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
17478 enum machine_mode mode
= GET_MODE (mem
);
17479 rtx label
, x
, cond
, mask
, shift
;
17480 rtx before
= orig_before
, after
= orig_after
;
17482 mask
= shift
= NULL_RTX
;
17483 if (mode
== QImode
|| mode
== HImode
)
17485 mem
= rs6000_adjust_atomic_subword (mem
, &shift
, &mask
);
17487 /* Shift and mask VAL into position with the word. */
17488 val
= convert_modes (SImode
, mode
, val
, 1);
17489 val
= expand_simple_binop (SImode
, ASHIFT
, val
, shift
,
17490 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17496 /* We've already zero-extended VAL. That is sufficient to
17497 make certain that it does not affect other bits. */
17502 /* If we make certain that all of the other bits in VAL are
17503 set, that will be sufficient to not affect other bits. */
17504 x
= gen_rtx_NOT (SImode
, mask
);
17505 x
= gen_rtx_IOR (SImode
, x
, val
);
17506 emit_insn (gen_rtx_SET (VOIDmode
, val
, x
));
17513 /* These will all affect bits outside the field and need
17514 adjustment via MASK within the loop. */
17518 gcc_unreachable ();
17521 /* Prepare to adjust the return value. */
17522 before
= gen_reg_rtx (SImode
);
17524 after
= gen_reg_rtx (SImode
);
17528 rs6000_pre_atomic_barrier (model
);
17530 label
= gen_label_rtx ();
17531 emit_label (label
);
17532 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
17534 if (before
== NULL_RTX
)
17535 before
= gen_reg_rtx (mode
);
17537 emit_load_locked (mode
, before
, mem
);
17541 x
= expand_simple_binop (mode
, AND
, before
, val
,
17542 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17543 after
= expand_simple_unop (mode
, NOT
, x
, after
, 1);
17547 after
= expand_simple_binop (mode
, code
, before
, val
,
17548 after
, 1, OPTAB_LIB_WIDEN
);
17554 x
= expand_simple_binop (SImode
, AND
, after
, mask
,
17555 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17556 x
= rs6000_mask_atomic_subword (before
, x
, mask
);
17559 cond
= gen_reg_rtx (CCmode
);
17560 emit_store_conditional (mode
, cond
, mem
, x
);
17562 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17563 emit_unlikely_jump (x
, label
);
17565 rs6000_post_atomic_barrier (model
);
17570 rs6000_finish_atomic_subword (orig_before
, before
, shift
);
17572 rs6000_finish_atomic_subword (orig_after
, after
, shift
);
17574 else if (orig_after
&& after
!= orig_after
)
17575 emit_move_insn (orig_after
, after
);
17578 /* Emit instructions to move SRC to DST. Called by splitters for
17579 multi-register moves. It will emit at most one instruction for
17580 each register that is accessed; that is, it won't emit li/lis pairs
17581 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17585 rs6000_split_multireg_move (rtx dst
, rtx src
)
17587 /* The register number of the first register being moved. */
17589 /* The mode that is to be moved. */
17590 enum machine_mode mode
;
17591 /* The mode that the move is being done in, and its size. */
17592 enum machine_mode reg_mode
;
17594 /* The number of registers that will be moved. */
17597 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
17598 mode
= GET_MODE (dst
);
17599 nregs
= hard_regno_nregs
[reg
][mode
];
17600 if (FP_REGNO_P (reg
))
17601 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
17602 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
17603 else if (ALTIVEC_REGNO_P (reg
))
17604 reg_mode
= V16QImode
;
17605 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
17608 reg_mode
= word_mode
;
17609 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
17611 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
17613 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
17615 /* Move register range backwards, if we might have destructive
17618 for (i
= nregs
- 1; i
>= 0; i
--)
17619 emit_insn (gen_rtx_SET (VOIDmode
,
17620 simplify_gen_subreg (reg_mode
, dst
, mode
,
17621 i
* reg_mode_size
),
17622 simplify_gen_subreg (reg_mode
, src
, mode
,
17623 i
* reg_mode_size
)));
17629 bool used_update
= false;
17630 rtx restore_basereg
= NULL_RTX
;
17632 if (MEM_P (src
) && INT_REGNO_P (reg
))
17636 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
17637 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
17640 breg
= XEXP (XEXP (src
, 0), 0);
17641 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
17642 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
17643 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
17644 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
17645 src
= replace_equiv_address (src
, breg
);
17647 else if (! rs6000_offsettable_memref_p (src
))
17649 if (GET_CODE (XEXP (src
, 0)) == PRE_MODIFY
)
17651 rtx basereg
= XEXP (XEXP (src
, 0), 0);
17654 rtx ndst
= simplify_gen_subreg (reg_mode
, dst
, mode
, 0);
17655 emit_insn (gen_rtx_SET (VOIDmode
, ndst
,
17656 gen_rtx_MEM (reg_mode
, XEXP (src
, 0))));
17657 used_update
= true;
17660 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
17661 XEXP (XEXP (src
, 0), 1)));
17662 src
= replace_equiv_address (src
, basereg
);
17666 rtx basereg
= gen_rtx_REG (Pmode
, reg
);
17667 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
17668 src
= replace_equiv_address (src
, basereg
);
17672 breg
= XEXP (src
, 0);
17673 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
17674 breg
= XEXP (breg
, 0);
17676 /* If the base register we are using to address memory is
17677 also a destination reg, then change that register last. */
17679 && REGNO (breg
) >= REGNO (dst
)
17680 && REGNO (breg
) < REGNO (dst
) + nregs
)
17681 j
= REGNO (breg
) - REGNO (dst
);
17683 else if (MEM_P (dst
) && INT_REGNO_P (reg
))
17687 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
17688 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
17691 breg
= XEXP (XEXP (dst
, 0), 0);
17692 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
17693 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
17694 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
17696 /* We have to update the breg before doing the store.
17697 Use store with update, if available. */
17701 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
17702 emit_insn (TARGET_32BIT
17703 ? (TARGET_POWERPC64
17704 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
17705 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
17706 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
17707 used_update
= true;
17710 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
17711 dst
= replace_equiv_address (dst
, breg
);
17713 else if (!rs6000_offsettable_memref_p (dst
)
17714 && GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
17716 if (GET_CODE (XEXP (dst
, 0)) == PRE_MODIFY
)
17718 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
17721 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
17722 emit_insn (gen_rtx_SET (VOIDmode
,
17723 gen_rtx_MEM (reg_mode
, XEXP (dst
, 0)), nsrc
));
17724 used_update
= true;
17727 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
17728 XEXP (XEXP (dst
, 0), 1)));
17729 dst
= replace_equiv_address (dst
, basereg
);
17733 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
17734 rtx offsetreg
= XEXP (XEXP (dst
, 0), 1);
17735 gcc_assert (GET_CODE (XEXP (dst
, 0)) == PLUS
17737 && REG_P (offsetreg
)
17738 && REGNO (basereg
) != REGNO (offsetreg
));
17739 if (REGNO (basereg
) == 0)
17741 rtx tmp
= offsetreg
;
17742 offsetreg
= basereg
;
17745 emit_insn (gen_add3_insn (basereg
, basereg
, offsetreg
));
17746 restore_basereg
= gen_sub3_insn (basereg
, basereg
, offsetreg
);
17747 dst
= replace_equiv_address (dst
, basereg
);
17750 else if (GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
17751 gcc_assert (rs6000_offsettable_memref_p (dst
));
17754 for (i
= 0; i
< nregs
; i
++)
17756 /* Calculate index to next subword. */
17761 /* If compiler already emitted move of first word by
17762 store with update, no need to do anything. */
17763 if (j
== 0 && used_update
)
17766 emit_insn (gen_rtx_SET (VOIDmode
,
17767 simplify_gen_subreg (reg_mode
, dst
, mode
,
17768 j
* reg_mode_size
),
17769 simplify_gen_subreg (reg_mode
, src
, mode
,
17770 j
* reg_mode_size
)));
17772 if (restore_basereg
!= NULL_RTX
)
17773 emit_insn (restore_basereg
);
17778 /* This page contains routines that are used to determine what the
17779 function prologue and epilogue code will do and write them out. */
17781 /* Return the first fixed-point register that is required to be
17782 saved. 32 if none. */
17785 first_reg_to_save (void)
17789 /* Find lowest numbered live register. */
17790 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
17791 if (df_regs_ever_live_p (first_reg
)
17792 && (! call_used_regs
[first_reg
]
17793 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
17794 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
17795 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
17796 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
17801 && crtl
->uses_pic_offset_table
17802 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
17803 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
17809 /* Similar, for FP regs. */
17812 first_fp_reg_to_save (void)
17816 /* Find lowest numbered live register. */
17817 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
17818 if (df_regs_ever_live_p (first_reg
))
17824 /* Similar, for AltiVec regs. */
17827 first_altivec_reg_to_save (void)
17831 /* Stack frame remains as is unless we are in AltiVec ABI. */
17832 if (! TARGET_ALTIVEC_ABI
)
17833 return LAST_ALTIVEC_REGNO
+ 1;
17835 /* On Darwin, the unwind routines are compiled without
17836 TARGET_ALTIVEC, and use save_world to save/restore the
17837 altivec registers when necessary. */
17838 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
17839 && ! TARGET_ALTIVEC
)
17840 return FIRST_ALTIVEC_REGNO
+ 20;
17842 /* Find lowest numbered live register. */
17843 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17844 if (df_regs_ever_live_p (i
))
17850 /* Return a 32-bit mask of the AltiVec registers we need to set in
17851 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17852 the 32-bit word is 0. */
17854 static unsigned int
17855 compute_vrsave_mask (void)
17857 unsigned int i
, mask
= 0;
17859 /* On Darwin, the unwind routines are compiled without
17860 TARGET_ALTIVEC, and use save_world to save/restore the
17861 call-saved altivec registers when necessary. */
17862 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
17863 && ! TARGET_ALTIVEC
)
17866 /* First, find out if we use _any_ altivec registers. */
17867 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17868 if (df_regs_ever_live_p (i
))
17869 mask
|= ALTIVEC_REG_BIT (i
);
17874 /* Next, remove the argument registers from the set. These must
17875 be in the VRSAVE mask set by the caller, so we don't need to add
17876 them in again. More importantly, the mask we compute here is
17877 used to generate CLOBBERs in the set_vrsave insn, and we do not
17878 wish the argument registers to die. */
17879 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
17880 mask
&= ~ALTIVEC_REG_BIT (i
);
17882 /* Similarly, remove the return value from the set. */
17885 diddle_return_value (is_altivec_return_reg
, &yes
);
17887 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
17893 /* For a very restricted set of circumstances, we can cut down the
17894 size of prologues/epilogues by calling our own save/restore-the-world
17898 compute_save_world_info (rs6000_stack_t
*info_ptr
)
17900 info_ptr
->world_save_p
= 1;
17901 info_ptr
->world_save_p
17902 = (WORLD_SAVE_P (info_ptr
)
17903 && DEFAULT_ABI
== ABI_DARWIN
17904 && !cfun
->has_nonlocal_label
17905 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
17906 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
17907 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
17908 && info_ptr
->cr_save_p
);
17910 /* This will not work in conjunction with sibcalls. Make sure there
17911 are none. (This check is expensive, but seldom executed.) */
17912 if (WORLD_SAVE_P (info_ptr
))
17915 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
17916 if ( GET_CODE (insn
) == CALL_INSN
17917 && SIBLING_CALL_P (insn
))
17919 info_ptr
->world_save_p
= 0;
17924 if (WORLD_SAVE_P (info_ptr
))
17926 /* Even if we're not touching VRsave, make sure there's room on the
17927 stack for it, if it looks like we're calling SAVE_WORLD, which
17928 will attempt to save it. */
17929 info_ptr
->vrsave_size
= 4;
17931 /* If we are going to save the world, we need to save the link register too. */
17932 info_ptr
->lr_save_p
= 1;
17934 /* "Save" the VRsave register too if we're saving the world. */
17935 if (info_ptr
->vrsave_mask
== 0)
17936 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
17938 /* Because the Darwin register save/restore routines only handle
17939 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17941 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
17942 && (info_ptr
->first_altivec_reg_save
17943 >= FIRST_SAVED_ALTIVEC_REGNO
));
17950 is_altivec_return_reg (rtx reg
, void *xyes
)
17952 bool *yes
= (bool *) xyes
;
17953 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
17958 /* Determine the strategy for savings/restoring registers. */
17961 SAVRES_MULTIPLE
= 0x1,
17962 SAVE_INLINE_FPRS
= 0x2,
17963 SAVE_INLINE_GPRS
= 0x4,
17964 REST_INLINE_FPRS
= 0x8,
17965 REST_INLINE_GPRS
= 0x10,
17966 SAVE_NOINLINE_GPRS_SAVES_LR
= 0x20,
17967 SAVE_NOINLINE_FPRS_SAVES_LR
= 0x40,
17968 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
= 0x80
17972 rs6000_savres_strategy (rs6000_stack_t
*info
,
17973 bool using_static_chain_p
)
17977 if (TARGET_MULTIPLE
17978 && !TARGET_POWERPC64
17979 && !(TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
)
17980 && info
->first_gp_reg_save
< 31
17981 && no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true))
17982 strategy
|= SAVRES_MULTIPLE
;
17984 if (crtl
->calls_eh_return
17985 || cfun
->machine
->ra_need_lr
17986 || info
->total_size
> 32767)
17987 strategy
|= (SAVE_INLINE_FPRS
| REST_INLINE_FPRS
17988 | SAVE_INLINE_GPRS
| REST_INLINE_GPRS
);
17990 if (info
->first_fp_reg_save
== 64
17991 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
17992 /* The out-of-line FP routines use double-precision stores;
17993 we can't use those routines if we don't have such stores. */
17994 || (TARGET_HARD_FLOAT
&& !TARGET_DOUBLE_FLOAT
)
17995 || !no_global_regs_above (info
->first_fp_reg_save
, /*gpr=*/false))
17996 strategy
|= SAVE_INLINE_FPRS
| REST_INLINE_FPRS
;
17998 if (info
->first_gp_reg_save
== 32
17999 || GP_SAVE_INLINE (info
->first_gp_reg_save
)
18000 || !((strategy
& SAVRES_MULTIPLE
)
18001 || no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true)))
18002 strategy
|= SAVE_INLINE_GPRS
| REST_INLINE_GPRS
;
18004 /* Don't bother to try to save things out-of-line if r11 is occupied
18005 by the static chain. It would require too much fiddling and the
18006 static chain is rarely used anyway. FPRs are saved w.r.t the stack
18007 pointer on Darwin. */
18008 if (using_static_chain_p
)
18009 strategy
|= (DEFAULT_ABI
== ABI_DARWIN
? 0 : SAVE_INLINE_FPRS
)
18010 | SAVE_INLINE_GPRS
;
18012 /* If we are going to use store multiple, then don't even bother
18013 with the out-of-line routines, since the store-multiple
18014 instruction will always be smaller. */
18015 if ((strategy
& SAVRES_MULTIPLE
))
18016 strategy
|= SAVE_INLINE_GPRS
;
18018 /* The situation is more complicated with load multiple. We'd
18019 prefer to use the out-of-line routines for restores, since the
18020 "exit" out-of-line routines can handle the restore of LR and the
18021 frame teardown. However if doesn't make sense to use the
18022 out-of-line routine if that is the only reason we'd need to save
18023 LR, and we can't use the "exit" out-of-line gpr restore if we
18024 have saved some fprs; In those cases it is advantageous to use
18025 load multiple when available. */
18026 if ((strategy
& SAVRES_MULTIPLE
)
18027 && (!info
->lr_save_p
18028 || info
->first_fp_reg_save
!= 64))
18029 strategy
|= REST_INLINE_GPRS
;
18031 /* We can only use load multiple or the out-of-line routines to
18032 restore if we've used store multiple or out-of-line routines
18033 in the prologue, i.e. if we've saved all the registers from
18034 first_gp_reg_save. Otherwise, we risk loading garbage. */
18035 if ((strategy
& (SAVE_INLINE_GPRS
| SAVRES_MULTIPLE
)) == SAVE_INLINE_GPRS
)
18036 strategy
|= REST_INLINE_GPRS
;
18038 /* Saving CR interferes with the exit routines used on the SPE, so
18041 && info
->spe_64bit_regs_used
18042 && info
->cr_save_p
)
18043 strategy
|= REST_INLINE_GPRS
;
18045 #ifdef POWERPC_LINUX
18048 if (!(strategy
& SAVE_INLINE_FPRS
))
18049 strategy
|= SAVE_NOINLINE_FPRS_SAVES_LR
;
18050 else if (!(strategy
& SAVE_INLINE_GPRS
)
18051 && info
->first_fp_reg_save
== 64)
18052 strategy
|= SAVE_NOINLINE_GPRS_SAVES_LR
;
18055 if (TARGET_AIX
&& !(strategy
& REST_INLINE_FPRS
))
18056 strategy
|= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
;
18058 if (TARGET_MACHO
&& !(strategy
& SAVE_INLINE_FPRS
))
18059 strategy
|= SAVE_NOINLINE_FPRS_SAVES_LR
;
18064 /* Calculate the stack information for the current function. This is
18065 complicated by having two separate calling sequences, the AIX calling
18066 sequence and the V.4 calling sequence.
18068 AIX (and Darwin/Mac OS X) stack frames look like:
18070 SP----> +---------------------------------------+
18071 | back chain to caller | 0 0
18072 +---------------------------------------+
18073 | saved CR | 4 8 (8-11)
18074 +---------------------------------------+
18076 +---------------------------------------+
18077 | reserved for compilers | 12 24
18078 +---------------------------------------+
18079 | reserved for binders | 16 32
18080 +---------------------------------------+
18081 | saved TOC pointer | 20 40
18082 +---------------------------------------+
18083 | Parameter save area (P) | 24 48
18084 +---------------------------------------+
18085 | Alloca space (A) | 24+P etc.
18086 +---------------------------------------+
18087 | Local variable space (L) | 24+P+A
18088 +---------------------------------------+
18089 | Float/int conversion temporary (X) | 24+P+A+L
18090 +---------------------------------------+
18091 | Save area for AltiVec registers (W) | 24+P+A+L+X
18092 +---------------------------------------+
18093 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18094 +---------------------------------------+
18095 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18096 +---------------------------------------+
18097 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18098 +---------------------------------------+
18099 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18100 +---------------------------------------+
18101 old SP->| back chain to caller's caller |
18102 +---------------------------------------+
18104 The required alignment for AIX configurations is two words (i.e., 8
18108 V.4 stack frames look like:
18110 SP----> +---------------------------------------+
18111 | back chain to caller | 0
18112 +---------------------------------------+
18113 | caller's saved LR | 4
18114 +---------------------------------------+
18115 | Parameter save area (P) | 8
18116 +---------------------------------------+
18117 | Alloca space (A) | 8+P
18118 +---------------------------------------+
18119 | Varargs save area (V) | 8+P+A
18120 +---------------------------------------+
18121 | Local variable space (L) | 8+P+A+V
18122 +---------------------------------------+
18123 | Float/int conversion temporary (X) | 8+P+A+V+L
18124 +---------------------------------------+
18125 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18126 +---------------------------------------+
18127 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18128 +---------------------------------------+
18129 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18130 +---------------------------------------+
18131 | SPE: area for 64-bit GP registers |
18132 +---------------------------------------+
18133 | SPE alignment padding |
18134 +---------------------------------------+
18135 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18136 +---------------------------------------+
18137 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18138 +---------------------------------------+
18139 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18140 +---------------------------------------+
18141 old SP->| back chain to caller's caller |
18142 +---------------------------------------+
18144 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18145 given. (But note below and in sysv4.h that we require only 8 and
18146 may round up the size of our stack frame anyways. The historical
18147 reason is early versions of powerpc-linux which didn't properly
18148 align the stack at program startup. A happy side-effect is that
18149 -mno-eabi libraries can be used with -meabi programs.)
18151 The EABI configuration defaults to the V.4 layout. However,
18152 the stack alignment requirements may differ. If -mno-eabi is not
18153 given, the required stack alignment is 8 bytes; if -mno-eabi is
18154 given, the required alignment is 16 bytes. (But see V.4 comment
18157 #ifndef ABI_STACK_BOUNDARY
18158 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18161 static rs6000_stack_t
*
18162 rs6000_stack_info (void)
18164 rs6000_stack_t
*info_ptr
= &stack_info
;
18165 int reg_size
= TARGET_32BIT
? 4 : 8;
18169 HOST_WIDE_INT non_fixed_size
;
18170 bool using_static_chain_p
;
18172 if (reload_completed
&& info_ptr
->reload_completed
)
18175 memset (info_ptr
, 0, sizeof (*info_ptr
));
18176 info_ptr
->reload_completed
= reload_completed
;
18180 /* Cache value so we don't rescan instruction chain over and over. */
18181 if (cfun
->machine
->insn_chain_scanned_p
== 0)
18182 cfun
->machine
->insn_chain_scanned_p
18183 = spe_func_has_64bit_regs_p () + 1;
18184 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
18187 /* Select which calling sequence. */
18188 info_ptr
->abi
= DEFAULT_ABI
;
18190 /* Calculate which registers need to be saved & save area size. */
18191 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
18192 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18193 even if it currently looks like we won't. Reload may need it to
18194 get at a constant; if so, it will have already created a constant
18195 pool entry for it. */
18196 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
18197 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
18198 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
18199 && crtl
->uses_const_pool
18200 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18201 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
18203 first_gp
= info_ptr
->first_gp_reg_save
;
18205 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
18207 /* For the SPE, we have an additional upper 32-bits on each GPR.
18208 Ideally we should save the entire 64-bits only when the upper
18209 half is used in SIMD instructions. Since we only record
18210 registers live (not the size they are used in), this proves
18211 difficult because we'd have to traverse the instruction chain at
18212 the right time, taking reload into account. This is a real pain,
18213 so we opt to save the GPRs in 64-bits always if but one register
18214 gets used in 64-bits. Otherwise, all the registers in the frame
18215 get saved in 32-bits.
18217 So... since when we save all GPRs (except the SP) in 64-bits, the
18218 traditional GP save area will be empty. */
18219 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18220 info_ptr
->gp_size
= 0;
18222 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
18223 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
18225 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
18226 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
18227 - info_ptr
->first_altivec_reg_save
);
18229 /* Does this function call anything? */
18230 info_ptr
->calls_p
= (! current_function_is_leaf
18231 || cfun
->machine
->ra_needs_full_frame
);
18233 /* Determine if we need to save the condition code registers. */
18234 if (df_regs_ever_live_p (CR2_REGNO
)
18235 || df_regs_ever_live_p (CR3_REGNO
)
18236 || df_regs_ever_live_p (CR4_REGNO
))
18238 info_ptr
->cr_save_p
= 1;
18239 if (DEFAULT_ABI
== ABI_V4
)
18240 info_ptr
->cr_size
= reg_size
;
18243 /* If the current function calls __builtin_eh_return, then we need
18244 to allocate stack space for registers that will hold data for
18245 the exception handler. */
18246 if (crtl
->calls_eh_return
)
18249 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
18252 /* SPE saves EH registers in 64-bits. */
18253 ehrd_size
= i
* (TARGET_SPE_ABI
18254 && info_ptr
->spe_64bit_regs_used
!= 0
18255 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
18260 /* Determine various sizes. */
18261 info_ptr
->reg_size
= reg_size
;
18262 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
18263 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
18264 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
18265 TARGET_ALTIVEC
? 16 : 8);
18266 if (FRAME_GROWS_DOWNWARD
)
18267 info_ptr
->vars_size
18268 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
18269 + info_ptr
->parm_size
,
18270 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
18271 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
18272 + info_ptr
->parm_size
);
18274 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18275 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
18277 info_ptr
->spe_gp_size
= 0;
18279 if (TARGET_ALTIVEC_ABI
)
18280 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18282 info_ptr
->vrsave_mask
= 0;
18284 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
18285 info_ptr
->vrsave_size
= 4;
18287 info_ptr
->vrsave_size
= 0;
18289 compute_save_world_info (info_ptr
);
18291 /* Calculate the offsets. */
18292 switch (DEFAULT_ABI
)
18296 gcc_unreachable ();
18300 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18301 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18303 if (TARGET_ALTIVEC_ABI
)
18305 info_ptr
->vrsave_save_offset
18306 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
18308 /* Align stack so vector save area is on a quadword boundary.
18309 The padding goes above the vectors. */
18310 if (info_ptr
->altivec_size
!= 0)
18311 info_ptr
->altivec_padding_size
18312 = info_ptr
->vrsave_save_offset
& 0xF;
18314 info_ptr
->altivec_padding_size
= 0;
18316 info_ptr
->altivec_save_offset
18317 = info_ptr
->vrsave_save_offset
18318 - info_ptr
->altivec_padding_size
18319 - info_ptr
->altivec_size
;
18320 gcc_assert (info_ptr
->altivec_size
== 0
18321 || info_ptr
->altivec_save_offset
% 16 == 0);
18323 /* Adjust for AltiVec case. */
18324 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
18327 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
18328 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
18329 info_ptr
->lr_save_offset
= 2*reg_size
;
18333 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18334 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18335 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
18337 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18339 /* Align stack so SPE GPR save area is aligned on a
18340 double-word boundary. */
18341 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
18342 info_ptr
->spe_padding_size
18343 = 8 - (-info_ptr
->cr_save_offset
% 8);
18345 info_ptr
->spe_padding_size
= 0;
18347 info_ptr
->spe_gp_save_offset
18348 = info_ptr
->cr_save_offset
18349 - info_ptr
->spe_padding_size
18350 - info_ptr
->spe_gp_size
;
18352 /* Adjust for SPE case. */
18353 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
18355 else if (TARGET_ALTIVEC_ABI
)
18357 info_ptr
->vrsave_save_offset
18358 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
18360 /* Align stack so vector save area is on a quadword boundary. */
18361 if (info_ptr
->altivec_size
!= 0)
18362 info_ptr
->altivec_padding_size
18363 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
18365 info_ptr
->altivec_padding_size
= 0;
18367 info_ptr
->altivec_save_offset
18368 = info_ptr
->vrsave_save_offset
18369 - info_ptr
->altivec_padding_size
18370 - info_ptr
->altivec_size
;
18372 /* Adjust for AltiVec case. */
18373 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
18376 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
18377 info_ptr
->ehrd_offset
-= ehrd_size
;
18378 info_ptr
->lr_save_offset
= reg_size
;
18382 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
18383 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
18384 + info_ptr
->gp_size
18385 + info_ptr
->altivec_size
18386 + info_ptr
->altivec_padding_size
18387 + info_ptr
->spe_gp_size
18388 + info_ptr
->spe_padding_size
18390 + info_ptr
->cr_size
18391 + info_ptr
->vrsave_size
,
18394 non_fixed_size
= (info_ptr
->vars_size
18395 + info_ptr
->parm_size
18396 + info_ptr
->save_size
);
18398 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
18399 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
18401 /* Determine if we need to save the link register. */
18402 if (info_ptr
->calls_p
18403 || (DEFAULT_ABI
== ABI_AIX
18405 && !TARGET_PROFILE_KERNEL
)
18406 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
18407 #ifdef TARGET_RELOCATABLE
18408 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
18410 || rs6000_ra_ever_killed ())
18411 info_ptr
->lr_save_p
= 1;
18413 using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
18414 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
18415 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
18416 info_ptr
->savres_strategy
= rs6000_savres_strategy (info_ptr
,
18417 using_static_chain_p
);
18419 if (!(info_ptr
->savres_strategy
& SAVE_INLINE_GPRS
)
18420 || !(info_ptr
->savres_strategy
& SAVE_INLINE_FPRS
)
18421 || !(info_ptr
->savres_strategy
& REST_INLINE_GPRS
)
18422 || !(info_ptr
->savres_strategy
& REST_INLINE_FPRS
))
18423 info_ptr
->lr_save_p
= 1;
18425 if (info_ptr
->lr_save_p
)
18426 df_set_regs_ever_live (LR_REGNO
, true);
18428 /* Determine if we need to allocate any stack frame:
18430 For AIX we need to push the stack if a frame pointer is needed
18431 (because the stack might be dynamically adjusted), if we are
18432 debugging, if we make calls, or if the sum of fp_save, gp_save,
18433 and local variables are more than the space needed to save all
18434 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18435 + 18*8 = 288 (GPR13 reserved).
18437 For V.4 we don't have the stack cushion that AIX uses, but assume
18438 that the debugger can handle stackless frames. */
18440 if (info_ptr
->calls_p
)
18441 info_ptr
->push_p
= 1;
18443 else if (DEFAULT_ABI
== ABI_V4
)
18444 info_ptr
->push_p
= non_fixed_size
!= 0;
18446 else if (frame_pointer_needed
)
18447 info_ptr
->push_p
= 1;
18449 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
18450 info_ptr
->push_p
= 1;
18453 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
18455 /* Zero offsets if we're not saving those registers. */
18456 if (info_ptr
->fp_size
== 0)
18457 info_ptr
->fp_save_offset
= 0;
18459 if (info_ptr
->gp_size
== 0)
18460 info_ptr
->gp_save_offset
= 0;
18462 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
18463 info_ptr
->altivec_save_offset
= 0;
18465 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
18466 info_ptr
->vrsave_save_offset
= 0;
18468 if (! TARGET_SPE_ABI
18469 || info_ptr
->spe_64bit_regs_used
== 0
18470 || info_ptr
->spe_gp_size
== 0)
18471 info_ptr
->spe_gp_save_offset
= 0;
18473 if (! info_ptr
->lr_save_p
)
18474 info_ptr
->lr_save_offset
= 0;
18476 if (! info_ptr
->cr_save_p
)
18477 info_ptr
->cr_save_offset
= 0;
18482 /* Return true if the current function uses any GPRs in 64-bit SIMD
18486 spe_func_has_64bit_regs_p (void)
18490 /* Functions that save and restore all the call-saved registers will
18491 need to save/restore the registers in 64-bits. */
18492 if (crtl
->calls_eh_return
18493 || cfun
->calls_setjmp
18494 || crtl
->has_nonlocal_goto
)
18497 insns
= get_insns ();
18499 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
18505 /* FIXME: This should be implemented with attributes...
18507 (set_attr "spe64" "true")....then,
18508 if (get_spe64(insn)) return true;
18510 It's the only reliable way to do the stuff below. */
18512 i
= PATTERN (insn
);
18513 if (GET_CODE (i
) == SET
)
18515 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
18517 if (SPE_VECTOR_MODE (mode
))
18519 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
18529 debug_stack_info (rs6000_stack_t
*info
)
18531 const char *abi_string
;
18534 info
= rs6000_stack_info ();
18536 fprintf (stderr
, "\nStack information for function %s:\n",
18537 ((current_function_decl
&& DECL_NAME (current_function_decl
))
18538 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
18543 default: abi_string
= "Unknown"; break;
18544 case ABI_NONE
: abi_string
= "NONE"; break;
18545 case ABI_AIX
: abi_string
= "AIX"; break;
18546 case ABI_DARWIN
: abi_string
= "Darwin"; break;
18547 case ABI_V4
: abi_string
= "V.4"; break;
18550 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
18552 if (TARGET_ALTIVEC_ABI
)
18553 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
18555 if (TARGET_SPE_ABI
)
18556 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
18558 if (info
->first_gp_reg_save
!= 32)
18559 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
18561 if (info
->first_fp_reg_save
!= 64)
18562 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
18564 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
18565 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
18566 info
->first_altivec_reg_save
);
18568 if (info
->lr_save_p
)
18569 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
18571 if (info
->cr_save_p
)
18572 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
18574 if (info
->vrsave_mask
)
18575 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
18578 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
18581 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
18583 if (info
->gp_save_offset
)
18584 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
18586 if (info
->fp_save_offset
)
18587 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
18589 if (info
->altivec_save_offset
)
18590 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
18591 info
->altivec_save_offset
);
18593 if (info
->spe_gp_save_offset
)
18594 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
18595 info
->spe_gp_save_offset
);
18597 if (info
->vrsave_save_offset
)
18598 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
18599 info
->vrsave_save_offset
);
18601 if (info
->lr_save_offset
)
18602 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
18604 if (info
->cr_save_offset
)
18605 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
18607 if (info
->varargs_save_offset
)
18608 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
18610 if (info
->total_size
)
18611 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
18614 if (info
->vars_size
)
18615 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
18618 if (info
->parm_size
)
18619 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
18621 if (info
->fixed_size
)
18622 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
18625 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
18627 if (info
->spe_gp_size
)
18628 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
18631 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
18633 if (info
->altivec_size
)
18634 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
18636 if (info
->vrsave_size
)
18637 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
18639 if (info
->altivec_padding_size
)
18640 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
18641 info
->altivec_padding_size
);
18643 if (info
->spe_padding_size
)
18644 fprintf (stderr
, "\tspe_padding_size = %5d\n",
18645 info
->spe_padding_size
);
18648 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
18650 if (info
->save_size
)
18651 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
18653 if (info
->reg_size
!= 4)
18654 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
18656 fprintf (stderr
, "\tsave-strategy = %04x\n", info
->savres_strategy
);
18658 fprintf (stderr
, "\n");
18662 rs6000_return_addr (int count
, rtx frame
)
18664 /* Currently we don't optimize very well between prolog and body
18665 code and for PIC code the code can be actually quite bad, so
18666 don't try to be too clever here. */
18667 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
18669 cfun
->machine
->ra_needs_full_frame
= 1;
18676 plus_constant (copy_to_reg
18677 (gen_rtx_MEM (Pmode
,
18678 memory_address (Pmode
, frame
))),
18679 RETURN_ADDRESS_OFFSET
)));
18682 cfun
->machine
->ra_need_lr
= 1;
18683 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
18686 /* Say whether a function is a candidate for sibcall handling or not. */
18689 rs6000_function_ok_for_sibcall (tree decl
, tree exp
)
18694 fntype
= TREE_TYPE (decl
);
18696 fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp
)));
18698 /* We can't do it if the called function has more vector parameters
18699 than the current function; there's nowhere to put the VRsave code. */
18700 if (TARGET_ALTIVEC_ABI
18701 && TARGET_ALTIVEC_VRSAVE
18702 && !(decl
&& decl
== current_function_decl
))
18704 function_args_iterator args_iter
;
18708 /* Functions with vector parameters are required to have a
18709 prototype, so the argument type info must be available
18711 FOREACH_FUNCTION_ARGS(fntype
, type
, args_iter
)
18712 if (TREE_CODE (type
) == VECTOR_TYPE
18713 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type
)))
18716 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl
), type
, args_iter
)
18717 if (TREE_CODE (type
) == VECTOR_TYPE
18718 && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type
)))
18725 /* Under the AIX ABI we can't allow calls to non-local functions,
18726 because the callee may have a different TOC pointer to the
18727 caller and there's no way to ensure we restore the TOC when we
18728 return. With the secure-plt SYSV ABI we can't make non-local
18729 calls when -fpic/PIC because the plt call stubs use r30. */
18730 if (DEFAULT_ABI
== ABI_DARWIN
18731 || (DEFAULT_ABI
== ABI_AIX
18733 && !DECL_EXTERNAL (decl
)
18734 && (*targetm
.binds_local_p
) (decl
))
18735 || (DEFAULT_ABI
== ABI_V4
18736 && (!TARGET_SECURE_PLT
18739 && (*targetm
.binds_local_p
) (decl
)))))
18741 tree attr_list
= TYPE_ATTRIBUTES (fntype
);
18743 if (!lookup_attribute ("longcall", attr_list
)
18744 || lookup_attribute ("shortcall", attr_list
))
18751 /* NULL if INSN insn is valid within a low-overhead loop.
18752 Otherwise return why doloop cannot be applied.
18753 PowerPC uses the COUNT register for branch on table instructions. */
18755 static const char *
18756 rs6000_invalid_within_doloop (const_rtx insn
)
18759 return "Function call in the loop.";
18762 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
18763 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
18764 return "Computed branch in the loop.";
18770 rs6000_ra_ever_killed (void)
18776 if (cfun
->is_thunk
)
18779 if (cfun
->machine
->lr_save_state
)
18780 return cfun
->machine
->lr_save_state
- 1;
18782 /* regs_ever_live has LR marked as used if any sibcalls are present,
18783 but this should not force saving and restoring in the
18784 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18785 clobbers LR, so that is inappropriate. */
18787 /* Also, the prologue can generate a store into LR that
18788 doesn't really count, like this:
18791 bcl to set PIC register
18795 When we're called from the epilogue, we need to avoid counting
18796 this as a store. */
18798 push_topmost_sequence ();
18799 top
= get_insns ();
18800 pop_topmost_sequence ();
18801 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
18803 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
18809 if (!SIBLING_CALL_P (insn
))
18812 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
18814 else if (set_of (reg
, insn
) != NULL_RTX
18815 && !prologue_epilogue_contains (insn
))
18822 /* Emit instructions needed to load the TOC register.
18823 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18824 a constant pool; or for SVR4 -fpic. */
18827 rs6000_emit_load_toc_table (int fromprolog
)
18830 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
18832 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
18835 rtx lab
, tmp1
, tmp2
, got
;
18837 lab
= gen_label_rtx ();
18838 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (lab
));
18839 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18841 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
18843 got
= rs6000_got_sym ();
18844 tmp1
= tmp2
= dest
;
18847 tmp1
= gen_reg_rtx (Pmode
);
18848 tmp2
= gen_reg_rtx (Pmode
);
18850 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
18851 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
18852 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
18853 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
18855 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
18857 emit_insn (gen_load_toc_v4_pic_si ());
18858 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
18860 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
18863 rtx temp0
= (fromprolog
18864 ? gen_rtx_REG (Pmode
, 0)
18865 : gen_reg_rtx (Pmode
));
18871 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
18872 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18874 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
18875 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18877 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
18878 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
18879 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
18885 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
18886 lab
= gen_label_rtx ();
18887 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
, lab
));
18888 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
18889 if (TARGET_LINK_STACK
)
18890 emit_insn (gen_addsi3 (dest
, dest
, GEN_INT (4)));
18891 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
18893 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
18895 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
18897 /* This is for AIX code running in non-PIC ELF32. */
18900 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
18901 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18903 emit_insn (gen_elf_high (dest
, realsym
));
18904 emit_insn (gen_elf_low (dest
, dest
, realsym
));
18908 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
18911 emit_insn (gen_load_toc_aix_si (dest
));
18913 emit_insn (gen_load_toc_aix_di (dest
));
18917 /* Emit instructions to restore the link register after determining where
18918 its value has been stored. */
18921 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
18923 rs6000_stack_t
*info
= rs6000_stack_info ();
18926 operands
[0] = source
;
18927 operands
[1] = scratch
;
18929 if (info
->lr_save_p
)
18931 rtx frame_rtx
= stack_pointer_rtx
;
18932 HOST_WIDE_INT sp_offset
= 0;
18935 if (frame_pointer_needed
18936 || cfun
->calls_alloca
18937 || info
->total_size
> 32767)
18939 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
18940 emit_move_insn (operands
[1], tmp
);
18941 frame_rtx
= operands
[1];
18943 else if (info
->push_p
)
18944 sp_offset
= info
->total_size
;
18946 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
18947 tmp
= gen_frame_mem (Pmode
, tmp
);
18948 emit_move_insn (tmp
, operands
[0]);
18951 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
18953 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18954 state of lr_save_p so any change from here on would be a bug. In
18955 particular, stop rs6000_ra_ever_killed from considering the SET
18956 of lr we may have added just above. */
18957 cfun
->machine
->lr_save_state
= info
->lr_save_p
+ 1;
18960 static GTY(()) alias_set_type set
= -1;
18963 get_TOC_alias_set (void)
18966 set
= new_alias_set ();
18970 /* This returns nonzero if the current function uses the TOC. This is
18971 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18972 is generated by the ABI_V4 load_toc_* patterns. */
18979 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
18982 rtx pat
= PATTERN (insn
);
18985 if (GET_CODE (pat
) == PARALLEL
)
18986 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18988 rtx sub
= XVECEXP (pat
, 0, i
);
18989 if (GET_CODE (sub
) == USE
)
18991 sub
= XEXP (sub
, 0);
18992 if (GET_CODE (sub
) == UNSPEC
18993 && XINT (sub
, 1) == UNSPEC_TOC
)
19003 create_TOC_reference (rtx symbol
, rtx largetoc_reg
)
19005 rtx tocrel
, tocreg
;
19007 if (TARGET_DEBUG_ADDR
)
19009 if (GET_CODE (symbol
) == SYMBOL_REF
)
19010 fprintf (stderr
, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19014 fprintf (stderr
, "\ncreate_TOC_reference, code %s:\n",
19015 GET_RTX_NAME (GET_CODE (symbol
)));
19016 debug_rtx (symbol
);
19020 if (!can_create_pseudo_p ())
19021 df_set_regs_ever_live (TOC_REGISTER
, true);
19023 tocrel
= gen_rtx_CONST (Pmode
,
19024 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
),
19026 tocreg
= gen_rtx_REG (Pmode
, TOC_REGISTER
);
19027 if (TARGET_CMODEL
!= CMODEL_SMALL
)
19029 rtx hi
= gen_rtx_CONST (Pmode
,
19030 gen_rtx_PLUS (Pmode
, tocreg
,
19031 gen_rtx_HIGH (Pmode
, tocrel
)));
19032 if (largetoc_reg
!= NULL
)
19034 emit_move_insn (largetoc_reg
, hi
);
19037 return gen_rtx_LO_SUM (Pmode
, hi
, copy_rtx (tocrel
));
19040 return gen_rtx_PLUS (Pmode
, tocreg
, tocrel
);
19043 /* Issue assembly directives that create a reference to the given DWARF
19044 FRAME_TABLE_LABEL from the current function section. */
19046 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label
)
19048 fprintf (asm_out_file
, "\t.ref %s\n",
19049 TARGET_STRIP_NAME_ENCODING (frame_table_label
));
19052 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19053 and the change to the stack pointer. */
19056 rs6000_emit_stack_tie (void)
19058 rtx mem
= gen_frame_mem (BLKmode
,
19059 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
19061 emit_insn (gen_stack_tie (mem
));
19064 /* Emit the correct code for allocating stack space, as insns.
19065 If COPY_REG, make sure a copy of the old frame is left there.
19066 The generated code may use hard register 0 as a temporary. */
19069 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, rtx copy_reg
)
19072 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19073 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
19074 rtx todec
= gen_int_mode (-size
, Pmode
);
19077 if (INTVAL (todec
) != -size
)
19079 warning (0, "stack frame too large");
19080 emit_insn (gen_trap ());
19084 if (crtl
->limit_stack
)
19086 if (REG_P (stack_limit_rtx
)
19087 && REGNO (stack_limit_rtx
) > 1
19088 && REGNO (stack_limit_rtx
) <= 31)
19090 emit_insn (gen_add3_insn (tmp_reg
, stack_limit_rtx
, GEN_INT (size
)));
19091 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19094 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
19096 && DEFAULT_ABI
== ABI_V4
)
19098 rtx toload
= gen_rtx_CONST (VOIDmode
,
19099 gen_rtx_PLUS (Pmode
,
19103 emit_insn (gen_elf_high (tmp_reg
, toload
));
19104 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
19105 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19109 warning (0, "stack limit expression is not supported");
19113 emit_move_insn (copy_reg
, stack_reg
);
19117 /* Need a note here so that try_split doesn't get confused. */
19118 if (get_last_insn () == NULL_RTX
)
19119 emit_note (NOTE_INSN_DELETED
);
19120 insn
= emit_move_insn (tmp_reg
, todec
);
19121 try_split (PATTERN (insn
), insn
, 0);
19125 insn
= emit_insn (TARGET_32BIT
19126 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
19128 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
19129 todec
, stack_reg
));
19130 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19131 it now and set the alias set/attributes. The above gen_*_update
19132 calls will generate a PARALLEL with the MEM set being the first
19134 par
= PATTERN (insn
);
19135 gcc_assert (GET_CODE (par
) == PARALLEL
);
19136 set
= XVECEXP (par
, 0, 0);
19137 gcc_assert (GET_CODE (set
) == SET
);
19138 mem
= SET_DEST (set
);
19139 gcc_assert (MEM_P (mem
));
19140 MEM_NOTRAP_P (mem
) = 1;
19141 set_mem_alias_set (mem
, get_frame_alias_set ());
19143 RTX_FRAME_RELATED_P (insn
) = 1;
19144 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
19145 gen_rtx_SET (VOIDmode
, stack_reg
,
19146 gen_rtx_PLUS (Pmode
, stack_reg
,
19147 GEN_INT (-size
))));
19150 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19152 #if PROBE_INTERVAL > 32768
19153 #error Cannot use indexed addressing mode for stack probing
19156 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19157 inclusive. These are offsets from the current stack pointer. */
19160 rs6000_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
19162 /* See if we have a constant small number of probes to generate. If so,
19163 that's the easy case. */
19164 if (first
+ size
<= 32768)
19168 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19169 it exceeds SIZE. If only one probe is needed, this will not
19170 generate any code. Then probe at FIRST + SIZE. */
19171 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
19172 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ i
)));
19174 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ size
)));
19177 /* Otherwise, do the same as above, but in a loop. Note that we must be
19178 extra careful with variables wrapping around because we might be at
19179 the very top (or the very bottom) of the address space and we have
19180 to be able to handle this case properly; in particular, we use an
19181 equality test for the loop condition. */
19184 HOST_WIDE_INT rounded_size
;
19185 rtx r12
= gen_rtx_REG (Pmode
, 12);
19186 rtx r0
= gen_rtx_REG (Pmode
, 0);
19188 /* Sanity check for the addressing mode we're going to use. */
19189 gcc_assert (first
<= 32768);
19191 /* Step 1: round SIZE to the previous multiple of the interval. */
19193 rounded_size
= size
& -PROBE_INTERVAL
;
19196 /* Step 2: compute initial and final value of the loop counter. */
19198 /* TEST_ADDR = SP + FIRST. */
19199 emit_insn (gen_rtx_SET (VOIDmode
, r12
,
19200 plus_constant (stack_pointer_rtx
, -first
)));
19202 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19203 if (rounded_size
> 32768)
19205 emit_move_insn (r0
, GEN_INT (-rounded_size
));
19206 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19207 gen_rtx_PLUS (Pmode
, r12
, r0
)));
19210 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19211 plus_constant (r12
, -rounded_size
)));
19214 /* Step 3: the loop
19216 while (TEST_ADDR != LAST_ADDR)
19218 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19222 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19223 until it is equal to ROUNDED_SIZE. */
19226 emit_insn (gen_probe_stack_rangedi (r12
, r12
, r0
));
19228 emit_insn (gen_probe_stack_rangesi (r12
, r12
, r0
));
19231 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19232 that SIZE is equal to ROUNDED_SIZE. */
19234 if (size
!= rounded_size
)
19235 emit_stack_probe (plus_constant (r12
, rounded_size
- size
));
19239 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19240 absolute addresses. */
19243 output_probe_stack_range (rtx reg1
, rtx reg2
)
19245 static int labelno
= 0;
19246 char loop_lab
[32], end_lab
[32];
19249 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
);
19250 ASM_GENERATE_INTERNAL_LABEL (end_lab
, "LPSRE", labelno
++);
19252 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
19254 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19258 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops
);
19260 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops
);
19262 fputs ("\tbeq 0,", asm_out_file
);
19263 assemble_name_raw (asm_out_file
, end_lab
);
19264 fputc ('\n', asm_out_file
);
19266 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19267 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
19268 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops
);
19270 /* Probe at TEST_ADDR and branch. */
19271 xops
[1] = gen_rtx_REG (Pmode
, 0);
19272 output_asm_insn ("{st|stw} %1,0(%0)", xops
);
19273 fprintf (asm_out_file
, "\tb ");
19274 assemble_name_raw (asm_out_file
, loop_lab
);
19275 fputc ('\n', asm_out_file
);
19277 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, end_lab
);
19282 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19283 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19284 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19285 deduce these equivalences by itself so it wasn't necessary to hold
19286 its hand so much. */
19289 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
19290 rtx reg2
, rtx rreg
)
19294 /* copy_rtx will not make unique copies of registers, so we need to
19295 ensure we don't have unwanted sharing here. */
19297 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19300 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19302 real
= copy_rtx (PATTERN (insn
));
19304 if (reg2
!= NULL_RTX
)
19305 real
= replace_rtx (real
, reg2
, rreg
);
19307 real
= replace_rtx (real
, reg
,
19308 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
19309 STACK_POINTER_REGNUM
),
19312 /* We expect that 'real' is either a SET or a PARALLEL containing
19313 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19314 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19316 if (GET_CODE (real
) == SET
)
19320 temp
= simplify_rtx (SET_SRC (set
));
19322 SET_SRC (set
) = temp
;
19323 temp
= simplify_rtx (SET_DEST (set
));
19325 SET_DEST (set
) = temp
;
19326 if (GET_CODE (SET_DEST (set
)) == MEM
)
19328 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19330 XEXP (SET_DEST (set
), 0) = temp
;
19337 gcc_assert (GET_CODE (real
) == PARALLEL
);
19338 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
19339 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
19341 rtx set
= XVECEXP (real
, 0, i
);
19343 temp
= simplify_rtx (SET_SRC (set
));
19345 SET_SRC (set
) = temp
;
19346 temp
= simplify_rtx (SET_DEST (set
));
19348 SET_DEST (set
) = temp
;
19349 if (GET_CODE (SET_DEST (set
)) == MEM
)
19351 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19353 XEXP (SET_DEST (set
), 0) = temp
;
19355 RTX_FRAME_RELATED_P (set
) = 1;
19359 RTX_FRAME_RELATED_P (insn
) = 1;
19360 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
19365 /* Returns an insn that has a vrsave set operation with the
19366 appropriate CLOBBERs. */
19369 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
19372 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
19373 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
19376 = gen_rtx_SET (VOIDmode
,
19378 gen_rtx_UNSPEC_VOLATILE (SImode
,
19379 gen_rtvec (2, reg
, vrsave
),
19380 UNSPECV_SET_VRSAVE
));
19384 /* We need to clobber the registers in the mask so the scheduler
19385 does not move sets to VRSAVE before sets of AltiVec registers.
19387 However, if the function receives nonlocal gotos, reload will set
19388 all call saved registers live. We will end up with:
19390 (set (reg 999) (mem))
19391 (parallel [ (set (reg vrsave) (unspec blah))
19392 (clobber (reg 999))])
19394 The clobber will cause the store into reg 999 to be dead, and
19395 flow will attempt to delete an epilogue insn. In this case, we
19396 need an unspec use/set of the register. */
19398 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
19399 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
19401 if (!epiloguep
|| call_used_regs
[i
])
19402 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
19403 gen_rtx_REG (V4SImode
, i
));
19406 rtx reg
= gen_rtx_REG (V4SImode
, i
);
19409 = gen_rtx_SET (VOIDmode
,
19411 gen_rtx_UNSPEC (V4SImode
,
19412 gen_rtvec (1, reg
), 27));
19416 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
19418 for (i
= 0; i
< nclobs
; ++i
)
19419 XVECEXP (insn
, 0, i
) = clobs
[i
];
19424 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19425 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19428 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
19429 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
19431 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
19432 rtx replacea
, replaceb
;
19434 int_rtx
= GEN_INT (offset
);
19436 /* Some cases that need register indexed addressing. */
19437 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
19438 || (TARGET_VSX
&& ALTIVEC_OR_VSX_VECTOR_MODE (mode
))
19439 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
19441 && SPE_VECTOR_MODE (mode
)
19442 && !SPE_CONST_OFFSET_OK (offset
)))
19444 /* Whomever calls us must make sure r11 is available in the
19445 flow path of instructions in the prologue. */
19446 offset_rtx
= gen_rtx_REG (Pmode
, 11);
19447 emit_move_insn (offset_rtx
, int_rtx
);
19449 replacea
= offset_rtx
;
19450 replaceb
= int_rtx
;
19454 offset_rtx
= int_rtx
;
19455 replacea
= NULL_RTX
;
19456 replaceb
= NULL_RTX
;
19459 reg
= gen_rtx_REG (mode
, regno
);
19460 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
19461 mem
= gen_frame_mem (mode
, addr
);
19463 insn
= emit_move_insn (mem
, reg
);
19465 return rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
19468 /* Emit an offset memory reference suitable for a frame store, while
19469 converting to a valid addressing mode. */
19472 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
19474 rtx int_rtx
, offset_rtx
;
19476 int_rtx
= GEN_INT (offset
);
19478 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
19479 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
19481 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
19482 emit_move_insn (offset_rtx
, int_rtx
);
19485 offset_rtx
= int_rtx
;
19487 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
19490 /* Look for user-defined global regs. We should not save and restore these,
19491 and cannot use stmw/lmw if there are any in its range. */
19494 no_global_regs_above (int first
, bool gpr
)
19497 int last
= gpr
? 32 : 64;
19498 for (i
= first
; i
< last
; i
++)
19499 if (global_regs
[i
])
19504 #ifndef TARGET_FIX_AND_CONTINUE
19505 #define TARGET_FIX_AND_CONTINUE 0
19508 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19509 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19510 #define LAST_SAVRES_REGISTER 31
19511 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19513 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
19515 /* Temporary holding space for an out-of-line register save/restore
19517 static char savres_routine_name
[30];
19519 /* Return the name for an out-of-line register save/restore routine.
19520 We are saving/restoring GPRs if GPR is true. */
19523 rs6000_savres_routine_name (rs6000_stack_t
*info
, int regno
,
19524 bool savep
, bool gpr
, bool lr
)
19526 const char *prefix
= "";
19527 const char *suffix
= "";
19529 /* Different targets are supposed to define
19530 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19531 routine name could be defined with:
19533 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19535 This is a nice idea in practice, but in reality, things are
19536 complicated in several ways:
19538 - ELF targets have save/restore routines for GPRs.
19540 - SPE targets use different prefixes for 32/64-bit registers, and
19541 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19543 - PPC64 ELF targets have routines for save/restore of GPRs that
19544 differ in what they do with the link register, so having a set
19545 prefix doesn't work. (We only use one of the save routines at
19546 the moment, though.)
19548 - PPC32 elf targets have "exit" versions of the restore routines
19549 that restore the link register and can save some extra space.
19550 These require an extra suffix. (There are also "tail" versions
19551 of the restore routines and "GOT" versions of the save routines,
19552 but we don't generate those at present. Same problems apply,
19555 We deal with all this by synthesizing our own prefix/suffix and
19556 using that for the simple sprintf call shown above. */
19559 /* No floating point saves on the SPE. */
19563 prefix
= info
->spe_64bit_regs_used
? "_save64gpr_" : "_save32gpr_";
19565 prefix
= info
->spe_64bit_regs_used
? "_rest64gpr_" : "_rest32gpr_";
19570 else if (DEFAULT_ABI
== ABI_V4
)
19576 prefix
= savep
? "_savegpr_" : "_restgpr_";
19578 prefix
= savep
? "_savefpr_" : "_restfpr_";
19583 else if (DEFAULT_ABI
== ABI_AIX
)
19585 #ifndef POWERPC_LINUX
19586 /* No out-of-line save/restore routines for GPRs on AIX. */
19587 gcc_assert (!TARGET_AIX
|| !gpr
);
19593 ? (lr
? "_savegpr0_" : "_savegpr1_")
19594 : (lr
? "_restgpr0_" : "_restgpr1_"));
19595 #ifdef POWERPC_LINUX
19597 prefix
= (savep
? "_savefpr_" : "_restfpr_");
19601 prefix
= savep
? SAVE_FP_PREFIX
: RESTORE_FP_PREFIX
;
19602 suffix
= savep
? SAVE_FP_SUFFIX
: RESTORE_FP_SUFFIX
;
19606 if (DEFAULT_ABI
== ABI_DARWIN
)
19608 /* The Darwin approach is (slightly) different, in order to be
19609 compatible with code generated by the system toolchain. There is a
19610 single symbol for the start of save sequence, and the code here
19611 embeds an offset into that code on the basis of the first register
19613 prefix
= savep
? "save" : "rest" ;
19615 sprintf (savres_routine_name
, "*%sGPR%s%s%.0d ; %s r%d-r31",
19616 prefix
, (lr
? "x" : ""), (regno
== 13 ? "" : "+"),
19617 (regno
-13) * 4, prefix
, regno
);
19619 sprintf (savres_routine_name
, "*%sFP%s%.0d ; %s f%d-f31",
19620 prefix
, (regno
== 14 ? "" : "+"), (regno
-14) * 4, prefix
, regno
);
19623 sprintf (savres_routine_name
, "%s%d%s", prefix
, regno
, suffix
);
19625 return savres_routine_name
;
19628 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19629 We are saving/restoring GPRs if GPR is true. */
19632 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
,
19635 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
19637 int select
= ((savep
? 1 : 0) << 2
19639 /* On the SPE, we never have any FPRs, but we do have
19640 32/64-bit versions of the routines. */
19641 ? (info
->spe_64bit_regs_used
? 1 : 0)
19642 : (gpr
? 1 : 0)) << 1)
19645 /* Don't generate bogus routine names. */
19646 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
19647 && regno
<= LAST_SAVRES_REGISTER
);
19649 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
19655 name
= rs6000_savres_routine_name (info
, regno
, savep
, gpr
, lr
);
19657 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
19658 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
19659 SYMBOL_REF_FLAGS (sym
) |= SYMBOL_FLAG_FUNCTION
;
19665 /* Emit a sequence of insns, including a stack tie if needed, for
19666 resetting the stack pointer. If SAVRES is true, then don't reset the
19667 stack pointer, but move the base of the frame into r11 for use by
19668 out-of-line register restore routines. */
19671 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
19672 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
19673 int sp_offset
, bool savres
)
19675 /* This blockage is needed so that sched doesn't decide to move
19676 the sp change before the register restores. */
19677 if (DEFAULT_ABI
== ABI_V4
19679 && info
->spe_64bit_regs_used
!= 0
19680 && info
->first_gp_reg_save
!= 32))
19681 rs6000_emit_stack_tie ();
19683 if (frame_reg_rtx
!= sp_reg_rtx
)
19685 if (sp_offset
!= 0)
19687 rtx dest_reg
= savres
? gen_rtx_REG (Pmode
, 11) : sp_reg_rtx
;
19688 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
,
19689 GEN_INT (sp_offset
)));
19694 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
19696 else if (sp_offset
!= 0)
19698 /* If we are restoring registers out-of-line, we will be using the
19699 "exit" variants of the restore routines, which will reset the
19700 stack for us. But we do need to point r11 into the right place
19701 for those routines. */
19702 rtx dest_reg
= (savres
19703 ? gen_rtx_REG (Pmode
, 11)
19706 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
19707 GEN_INT (sp_offset
)));
19714 /* Construct a parallel rtx describing the effect of a call to an
19715 out-of-line register save/restore routine, and emit the insn
19716 or jump_insn as appropriate. */
19719 rs6000_emit_savres_rtx (rs6000_stack_t
*info
,
19720 rtx frame_reg_rtx
, int save_area_offset
,
19721 enum machine_mode reg_mode
,
19722 bool savep
, bool gpr
, bool lr
)
19725 int offset
, start_reg
, end_reg
, n_regs
, use_reg
;
19726 int reg_size
= GET_MODE_SIZE (reg_mode
);
19733 ? info
->first_gp_reg_save
19734 : info
->first_fp_reg_save
);
19735 end_reg
= gpr
? 32 : 64;
19736 n_regs
= end_reg
- start_reg
;
19737 p
= rtvec_alloc ((lr
? 4 : 3) + n_regs
);
19740 RTVEC_ELT (p
, offset
++) = ret_rtx
;
19742 RTVEC_ELT (p
, offset
++)
19743 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, LR_REGNO
));
19745 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, lr
);
19746 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
19747 use_reg
= DEFAULT_ABI
== ABI_AIX
? (gpr
&& !lr
? 12 : 1)
19748 : DEFAULT_ABI
== ABI_DARWIN
&& !gpr
? 1
19750 RTVEC_ELT (p
, offset
++)
19751 = gen_rtx_USE (VOIDmode
,
19752 gen_rtx_REG (Pmode
, use_reg
));
19754 for (i
= 0; i
< end_reg
- start_reg
; i
++)
19756 rtx addr
, reg
, mem
;
19757 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
19758 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19759 GEN_INT (save_area_offset
+ reg_size
*i
));
19760 mem
= gen_frame_mem (reg_mode
, addr
);
19762 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
19764 savep
? reg
: mem
);
19769 rtx addr
, reg
, mem
;
19770 reg
= gen_rtx_REG (Pmode
, 0);
19771 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19772 GEN_INT (info
->lr_save_offset
));
19773 mem
= gen_frame_mem (Pmode
, addr
);
19774 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19777 par
= gen_rtx_PARALLEL (VOIDmode
, p
);
19781 insn
= emit_jump_insn (par
);
19782 JUMP_LABEL (insn
) = ret_rtx
;
19785 insn
= emit_insn (par
);
19789 /* Determine whether the gp REG is really used. */
19792 rs6000_reg_live_or_pic_offset_p (int reg
)
19794 /* If the function calls eh_return, claim used all the registers that would
19795 be checked for liveness otherwise. This is required for the PIC offset
19796 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19797 register allocation purposes in this case. */
19799 return (((crtl
->calls_eh_return
|| df_regs_ever_live_p (reg
))
19800 && (!call_used_regs
[reg
]
19801 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
19802 && !TARGET_SINGLE_PIC_BASE
19803 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
19804 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
19805 && !TARGET_SINGLE_PIC_BASE
19806 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
19807 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
19810 /* Emit function prologue as insns. */
19813 rs6000_emit_prologue (void)
19815 rs6000_stack_t
*info
= rs6000_stack_info ();
19816 enum machine_mode reg_mode
= Pmode
;
19817 int reg_size
= TARGET_32BIT
? 4 : 8;
19818 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19819 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
19820 rtx frame_reg_rtx
= sp_reg_rtx
;
19821 rtx cr_save_rtx
= NULL_RTX
;
19824 int saving_FPRs_inline
;
19825 int saving_GPRs_inline
;
19826 int using_store_multiple
;
19827 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
19828 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
19829 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
19830 HOST_WIDE_INT sp_offset
= 0;
19832 if (flag_stack_usage_info
)
19833 current_function_static_stack_size
= info
->total_size
;
19835 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
&& info
->total_size
)
19836 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT
, info
->total_size
);
19838 if (TARGET_FIX_AND_CONTINUE
)
19840 /* gdb on darwin arranges to forward a function from the old
19841 address by modifying the first 5 instructions of the function
19842 to branch to the overriding function. This is necessary to
19843 permit function pointers that point to the old function to
19844 actually forward to the new function. */
19845 emit_insn (gen_nop ());
19846 emit_insn (gen_nop ());
19847 emit_insn (gen_nop ());
19848 emit_insn (gen_nop ());
19849 emit_insn (gen_nop ());
19852 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
19854 reg_mode
= V2SImode
;
19858 strategy
= info
->savres_strategy
;
19859 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
19860 saving_FPRs_inline
= strategy
& SAVE_INLINE_FPRS
;
19861 saving_GPRs_inline
= strategy
& SAVE_INLINE_GPRS
;
19863 /* For V.4, update stack before we do any saving and set back pointer. */
19864 if (! WORLD_SAVE_P (info
)
19866 && (DEFAULT_ABI
== ABI_V4
19867 || crtl
->calls_eh_return
))
19869 bool need_r11
= (TARGET_SPE
19870 ? (!saving_GPRs_inline
19871 && info
->spe_64bit_regs_used
== 0)
19872 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
19873 rtx copy_reg
= need_r11
? gen_rtx_REG (Pmode
, 11) : NULL
;
19875 if (info
->total_size
< 32767)
19876 sp_offset
= info
->total_size
;
19878 frame_reg_rtx
= copy_reg
;
19879 else if (info
->cr_save_p
19881 || info
->first_fp_reg_save
< 64
19882 || info
->first_gp_reg_save
< 32
19883 || info
->altivec_size
!= 0
19884 || info
->vrsave_mask
!= 0
19885 || crtl
->calls_eh_return
)
19887 copy_reg
= frame_ptr_rtx
;
19888 frame_reg_rtx
= copy_reg
;
19892 /* The prologue won't be saving any regs so there is no need
19893 to set up a frame register to access any frame save area.
19894 We also won't be using sp_offset anywhere below, but set
19895 the correct value anyway to protect against future
19896 changes to this function. */
19897 sp_offset
= info
->total_size
;
19899 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
19900 if (frame_reg_rtx
!= sp_reg_rtx
)
19901 rs6000_emit_stack_tie ();
19904 /* Handle world saves specially here. */
19905 if (WORLD_SAVE_P (info
))
19912 /* save_world expects lr in r0. */
19913 reg0
= gen_rtx_REG (Pmode
, 0);
19914 if (info
->lr_save_p
)
19916 insn
= emit_move_insn (reg0
,
19917 gen_rtx_REG (Pmode
, LR_REGNO
));
19918 RTX_FRAME_RELATED_P (insn
) = 1;
19921 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19922 assumptions about the offsets of various bits of the stack
19924 gcc_assert (info
->gp_save_offset
== -220
19925 && info
->fp_save_offset
== -144
19926 && info
->lr_save_offset
== 8
19927 && info
->cr_save_offset
== 4
19930 && (!crtl
->calls_eh_return
19931 || info
->ehrd_offset
== -432)
19932 && info
->vrsave_save_offset
== -224
19933 && info
->altivec_save_offset
== -416);
19935 treg
= gen_rtx_REG (SImode
, 11);
19936 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
19938 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19939 in R11. It also clobbers R12, so beware! */
19941 /* Preserve CR2 for save_world prologues */
19943 sz
+= 32 - info
->first_gp_reg_save
;
19944 sz
+= 64 - info
->first_fp_reg_save
;
19945 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
19946 p
= rtvec_alloc (sz
);
19948 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
19949 gen_rtx_REG (SImode
,
19951 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
19952 gen_rtx_SYMBOL_REF (Pmode
,
19954 /* We do floats first so that the instruction pattern matches
19956 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
19958 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19959 ? DFmode
: SFmode
),
19960 info
->first_fp_reg_save
+ i
);
19961 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19962 GEN_INT (info
->fp_save_offset
19963 + sp_offset
+ 8 * i
));
19964 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19965 ? DFmode
: SFmode
), addr
);
19967 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19969 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
19971 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
19972 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19973 GEN_INT (info
->altivec_save_offset
19974 + sp_offset
+ 16 * i
));
19975 rtx mem
= gen_frame_mem (V4SImode
, addr
);
19977 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19979 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
19981 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
19982 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19983 GEN_INT (info
->gp_save_offset
19984 + sp_offset
+ reg_size
* i
));
19985 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19987 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19991 /* CR register traditionally saved as CR2. */
19992 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
19993 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19994 GEN_INT (info
->cr_save_offset
19996 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19998 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20000 /* Explain about use of R0. */
20001 if (info
->lr_save_p
)
20003 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20004 GEN_INT (info
->lr_save_offset
20006 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20008 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
20010 /* Explain what happens to the stack pointer. */
20012 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
20013 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
20016 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20017 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20018 treg
, GEN_INT (-info
->total_size
));
20019 sp_offset
= info
->total_size
;
20022 /* If we use the link register, get it into r0. */
20023 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
20025 rtx addr
, reg
, mem
;
20027 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
20028 gen_rtx_REG (Pmode
, LR_REGNO
));
20029 RTX_FRAME_RELATED_P (insn
) = 1;
20031 if (!(strategy
& (SAVE_NOINLINE_GPRS_SAVES_LR
20032 | SAVE_NOINLINE_FPRS_SAVES_LR
)))
20034 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20035 GEN_INT (info
->lr_save_offset
+ sp_offset
));
20036 reg
= gen_rtx_REG (Pmode
, 0);
20037 mem
= gen_rtx_MEM (Pmode
, addr
);
20038 /* This should not be of rs6000_sr_alias_set, because of
20039 __builtin_return_address. */
20041 insn
= emit_move_insn (mem
, reg
);
20042 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20043 NULL_RTX
, NULL_RTX
);
20047 /* If we need to save CR, put it into r12 or r11. */
20048 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
20053 = gen_rtx_REG (SImode
, DEFAULT_ABI
== ABI_AIX
&& !saving_GPRs_inline
20055 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20056 RTX_FRAME_RELATED_P (insn
) = 1;
20057 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20058 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20059 But that's OK. All we have to do is specify that _one_ condition
20060 code register is saved in this stack slot. The thrower's epilogue
20061 will then restore all the call-saved registers.
20062 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20063 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
20064 gen_rtx_REG (SImode
, CR2_REGNO
));
20065 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20068 /* Do any required saving of fpr's. If only one or two to save, do
20069 it ourselves. Otherwise, call function. */
20070 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
20073 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20074 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
20075 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
20076 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
20077 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20079 info
->first_fp_reg_save
+ i
,
20080 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
20083 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
20085 insn
= rs6000_emit_savres_rtx (info
, frame_reg_rtx
,
20086 info
->fp_save_offset
+ sp_offset
,
20088 /*savep=*/true, /*gpr=*/false,
20090 & SAVE_NOINLINE_FPRS_SAVES_LR
)
20092 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20093 NULL_RTX
, NULL_RTX
);
20096 /* Save GPRs. This is done as a PARALLEL if we are using
20097 the store-multiple instructions. */
20098 if (!WORLD_SAVE_P (info
)
20100 && info
->spe_64bit_regs_used
!= 0
20101 && info
->first_gp_reg_save
!= 32)
20104 rtx spe_save_area_ptr
;
20106 /* Determine whether we can address all of the registers that need
20107 to be saved with an offset from the stack pointer that fits in
20108 the small const field for SPE memory instructions. */
20109 int spe_regs_addressable_via_sp
20110 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
20111 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
20112 && saving_GPRs_inline
);
20115 if (spe_regs_addressable_via_sp
)
20117 spe_save_area_ptr
= frame_reg_rtx
;
20118 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
20122 /* Make r11 point to the start of the SPE save area. We need
20123 to be careful here if r11 is holding the static chain. If
20124 it is, then temporarily save it in r0. We would use r0 as
20125 our base register here, but using r0 as a base register in
20126 loads and stores means something different from what we
20128 int ool_adjust
= (saving_GPRs_inline
20130 : (info
->first_gp_reg_save
20131 - (FIRST_SAVRES_REGISTER
+1))*8);
20132 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
20133 + sp_offset
- ool_adjust
);
20135 if (using_static_chain_p
)
20137 rtx r0
= gen_rtx_REG (Pmode
, 0);
20138 gcc_assert (info
->first_gp_reg_save
> 11);
20140 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
20143 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
20144 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
20146 GEN_INT (offset
)));
20147 /* We need to make sure the move to r11 gets noted for
20148 properly outputting unwind information. */
20149 if (!saving_GPRs_inline
)
20150 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
20151 NULL_RTX
, NULL_RTX
);
20155 if (saving_GPRs_inline
)
20157 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20158 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20160 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20161 rtx offset
, addr
, mem
;
20163 /* We're doing all this to ensure that the offset fits into
20164 the immediate offset of 'evstdd'. */
20165 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
20167 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
20168 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
20169 mem
= gen_rtx_MEM (V2SImode
, addr
);
20171 insn
= emit_move_insn (mem
, reg
);
20173 rs6000_frame_related (insn
, spe_save_area_ptr
,
20174 info
->spe_gp_save_offset
20175 + sp_offset
+ reg_size
* i
,
20176 offset
, const0_rtx
);
20181 insn
= rs6000_emit_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
20183 /*savep=*/true, /*gpr=*/true,
20185 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20186 NULL_RTX
, NULL_RTX
);
20190 /* Move the static chain pointer back. */
20191 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
20192 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
20194 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
20196 if (DEFAULT_ABI
== ABI_DARWIN
)
20198 rtx dest_reg
= gen_rtx_REG (reg_mode
, 11);
20199 if (info
->first_fp_reg_save
== 64)
20200 /* we only need a copy, no fprs were saved. */
20201 emit_move_insn (dest_reg
, frame_reg_rtx
);
20204 rtx offset
= GEN_INT (sp_offset
20205 + (-8 * (64-info
->first_fp_reg_save
)));
20206 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
20209 /* Need to adjust r11 (r12) if we saved any FPRs. */
20210 else if (info
->first_fp_reg_save
!= 64)
20212 rtx dest_reg
= gen_rtx_REG (reg_mode
, DEFAULT_ABI
== ABI_AIX
20214 rtx offset
= GEN_INT (sp_offset
20215 + (-8 * (64-info
->first_fp_reg_save
)));
20216 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
20219 insn
= rs6000_emit_savres_rtx (info
, frame_reg_rtx
,
20220 info
->gp_save_offset
+ sp_offset
,
20222 /*savep=*/true, /*gpr=*/true,
20224 & SAVE_NOINLINE_GPRS_SAVES_LR
)
20226 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20227 NULL_RTX
, NULL_RTX
);
20229 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
20233 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
20234 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20236 rtx addr
, reg
, mem
;
20237 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20238 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20239 GEN_INT (info
->gp_save_offset
20242 mem
= gen_frame_mem (reg_mode
, addr
);
20244 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20246 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20247 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20248 NULL_RTX
, NULL_RTX
);
20250 else if (!WORLD_SAVE_P (info
))
20253 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20254 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20256 rtx addr
, reg
, mem
;
20257 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20259 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20260 GEN_INT (info
->gp_save_offset
20263 mem
= gen_frame_mem (reg_mode
, addr
);
20265 insn
= emit_move_insn (mem
, reg
);
20266 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20267 NULL_RTX
, NULL_RTX
);
20271 /* ??? There's no need to emit actual instructions here, but it's the
20272 easiest way to get the frame unwind information emitted. */
20273 if (crtl
->calls_eh_return
)
20275 unsigned int i
, regno
;
20279 regno
= EH_RETURN_DATA_REGNO (i
);
20280 if (regno
== INVALID_REGNUM
)
20283 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
20284 info
->ehrd_offset
+ sp_offset
20285 + reg_size
* (int) i
,
20290 /* In AIX ABI we need to make sure r2 is really saved. */
20291 if (TARGET_AIX
&& crtl
->calls_eh_return
)
20293 rtx tmp_reg
, tmp_reg_si
, hi
, lo
, compare_result
, toc_save_done
, jump
;
20294 rtx save_insn
, join_insn
, note
;
20295 long toc_restore_insn
;
20297 gcc_assert (frame_reg_rtx
== frame_ptr_rtx
20298 || frame_reg_rtx
== sp_reg_rtx
);
20299 tmp_reg
= gen_rtx_REG (Pmode
, 11);
20300 tmp_reg_si
= gen_rtx_REG (SImode
, 11);
20301 if (using_static_chain_p
)
20302 emit_move_insn (gen_rtx_REG (Pmode
, 0), tmp_reg
);
20303 gcc_assert (saving_GPRs_inline
&& saving_FPRs_inline
);
20304 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, LR_REGNO
));
20305 /* Peek at instruction to which this function returns. If it's
20306 restoring r2, then we know we've already saved r2. We can't
20307 unconditionally save r2 because the value we have will already
20308 be updated if we arrived at this function via a plt call or
20309 toc adjusting stub. */
20310 emit_move_insn (tmp_reg_si
, gen_rtx_MEM (SImode
, tmp_reg
));
20311 toc_restore_insn
= TARGET_32BIT
? 0x80410014 : 0xE8410028;
20312 hi
= gen_int_mode (toc_restore_insn
& ~0xffff, SImode
);
20313 emit_insn (gen_xorsi3 (tmp_reg_si
, tmp_reg_si
, hi
));
20314 compare_result
= gen_rtx_REG (CCUNSmode
, CR0_REGNO
);
20315 validate_condition_mode (EQ
, CCUNSmode
);
20316 lo
= gen_int_mode (toc_restore_insn
& 0xffff, SImode
);
20317 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
20318 gen_rtx_COMPARE (CCUNSmode
, tmp_reg_si
, lo
)));
20319 toc_save_done
= gen_label_rtx ();
20320 jump
= gen_rtx_IF_THEN_ELSE (VOIDmode
,
20321 gen_rtx_EQ (VOIDmode
, compare_result
,
20323 gen_rtx_LABEL_REF (VOIDmode
, toc_save_done
),
20325 jump
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, jump
));
20326 JUMP_LABEL (jump
) = toc_save_done
;
20327 LABEL_NUSES (toc_save_done
) += 1;
20329 save_insn
= emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
,
20330 TOC_REGNUM
, sp_offset
+ 5 * reg_size
,
20333 emit_label (toc_save_done
);
20335 /* ??? If we leave SAVE_INSN as marked as saving R2, then we'll
20336 have a CFG that has different saves along different paths.
20337 Move the note to a dummy blockage insn, which describes that
20338 R2 is unconditionally saved after the label. */
20339 /* ??? An alternate representation might be a special insn pattern
20340 containing both the branch and the store. That might let the
20341 code that minimizes the number of DW_CFA_advance opcodes better
20342 freedom in placing the annotations. */
20343 note
= find_reg_note (save_insn
, REG_FRAME_RELATED_EXPR
, NULL
);
20345 remove_note (save_insn
, note
);
20346 RTX_FRAME_RELATED_P (save_insn
) = 0;
20348 join_insn
= emit_insn (gen_blockage ());
20349 REG_NOTES (join_insn
) = note
;
20350 RTX_FRAME_RELATED_P (join_insn
) = 1;
20352 if (using_static_chain_p
)
20353 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, 0));
20356 /* Save CR if we use any that must be preserved. */
20357 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
20359 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20360 GEN_INT (info
->cr_save_offset
+ sp_offset
));
20361 rtx mem
= gen_frame_mem (SImode
, addr
);
20362 /* See the large comment above about why CR2_REGNO is used. */
20363 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
20365 /* If r12 was used to hold the original sp, copy cr into r0 now
20367 if (REGNO (frame_reg_rtx
) == 12)
20371 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
20372 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20373 RTX_FRAME_RELATED_P (insn
) = 1;
20374 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
20375 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20377 insn
= emit_move_insn (mem
, cr_save_rtx
);
20379 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20380 NULL_RTX
, NULL_RTX
);
20383 /* Update stack and set back pointer unless this is V.4,
20384 for which it was done previously. */
20385 if (!WORLD_SAVE_P (info
) && info
->push_p
20386 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
20388 rtx copy_reg
= NULL
;
20390 if (info
->total_size
< 32767)
20391 sp_offset
= info
->total_size
;
20392 else if (info
->altivec_size
!= 0
20393 || info
->vrsave_mask
!= 0)
20395 copy_reg
= frame_ptr_rtx
;
20396 frame_reg_rtx
= copy_reg
;
20399 sp_offset
= info
->total_size
;
20400 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20401 if (frame_reg_rtx
!= sp_reg_rtx
)
20402 rs6000_emit_stack_tie ();
20405 /* Set frame pointer, if needed. */
20406 if (frame_pointer_needed
)
20408 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
20410 RTX_FRAME_RELATED_P (insn
) = 1;
20413 /* Save AltiVec registers if needed. Save here because the red zone does
20414 not include AltiVec registers. */
20415 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
20419 /* There should be a non inline version of this, for when we
20420 are saving lots of vector registers. */
20421 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20422 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20424 rtx areg
, savereg
, mem
;
20427 offset
= info
->altivec_save_offset
+ sp_offset
20428 + 16 * (i
- info
->first_altivec_reg_save
);
20430 savereg
= gen_rtx_REG (V4SImode
, i
);
20432 areg
= gen_rtx_REG (Pmode
, 0);
20433 emit_move_insn (areg
, GEN_INT (offset
));
20435 /* AltiVec addressing mode is [reg+reg]. */
20436 mem
= gen_frame_mem (V4SImode
,
20437 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
20439 insn
= emit_move_insn (mem
, savereg
);
20441 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20442 areg
, GEN_INT (offset
));
20446 /* VRSAVE is a bit vector representing which AltiVec registers
20447 are used. The OS uses this to determine which vector
20448 registers to save on a context switch. We need to save
20449 VRSAVE on the stack frame, add whatever AltiVec registers we
20450 used in this function, and do the corresponding magic in the
20453 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
20454 && info
->vrsave_mask
!= 0)
20456 rtx reg
, mem
, vrsave
;
20459 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20460 as frame_reg_rtx and r11 as the static chain pointer for
20461 nested functions. */
20462 reg
= gen_rtx_REG (SImode
, 0);
20463 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
20465 emit_insn (gen_get_vrsave_internal (reg
));
20467 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
20469 if (!WORLD_SAVE_P (info
))
20472 offset
= info
->vrsave_save_offset
+ sp_offset
;
20473 mem
= gen_frame_mem (SImode
,
20474 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20475 GEN_INT (offset
)));
20476 insn
= emit_move_insn (mem
, reg
);
20479 /* Include the registers in the mask. */
20480 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
20482 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
20485 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20486 if (!TARGET_SINGLE_PIC_BASE
20487 && ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
20488 || (DEFAULT_ABI
== ABI_V4
20489 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
20490 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))))
20492 /* If emit_load_toc_table will use the link register, we need to save
20493 it. We use R12 for this purpose because emit_load_toc_table
20494 can use register 0. This allows us to use a plain 'blr' to return
20495 from the procedure more often. */
20496 int save_LR_around_toc_setup
= (TARGET_ELF
20497 && DEFAULT_ABI
!= ABI_AIX
20499 && ! info
->lr_save_p
20500 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
20501 if (save_LR_around_toc_setup
)
20503 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20505 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
20506 RTX_FRAME_RELATED_P (insn
) = 1;
20508 rs6000_emit_load_toc_table (TRUE
);
20510 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
20511 add_reg_note (insn
, REG_CFA_RESTORE
, lr
);
20512 RTX_FRAME_RELATED_P (insn
) = 1;
20515 rs6000_emit_load_toc_table (TRUE
);
20519 if (!TARGET_SINGLE_PIC_BASE
20520 && DEFAULT_ABI
== ABI_DARWIN
20521 && flag_pic
&& crtl
->uses_pic_offset_table
)
20523 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20524 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
20526 /* Save and restore LR locally around this call (in R0). */
20527 if (!info
->lr_save_p
)
20528 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
20530 emit_insn (gen_load_macho_picbase (src
));
20532 emit_move_insn (gen_rtx_REG (Pmode
,
20533 RS6000_PIC_OFFSET_TABLE_REGNUM
),
20536 if (!info
->lr_save_p
)
20537 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
20541 /* If we need to, save the TOC register after doing the stack setup.
20542 Do not emit eh frame info for this save. The unwinder wants info,
20543 conceptually attached to instructions in this function, about
20544 register values in the caller of this function. This R2 may have
20545 already been changed from the value in the caller.
20546 We don't attempt to write accurate DWARF EH frame info for R2
20547 because code emitted by gcc for a (non-pointer) function call
20548 doesn't save and restore R2. Instead, R2 is managed out-of-line
20549 by a linker generated plt call stub when the function resides in
20550 a shared library. This behaviour is costly to describe in DWARF,
20551 both in terms of the size of DWARF info and the time taken in the
20552 unwinder to interpret it. R2 changes, apart from the
20553 calls_eh_return case earlier in this function, are handled by
20554 linux-unwind.h frob_update_context. */
20555 if (rs6000_save_toc_in_prologue_p ())
20557 rtx addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, GEN_INT (5 * reg_size
));
20558 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20559 emit_move_insn (mem
, gen_rtx_REG (reg_mode
, TOC_REGNUM
));
20563 /* Write function prologue. */
20566 rs6000_output_function_prologue (FILE *file
,
20567 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
20569 rs6000_stack_t
*info
= rs6000_stack_info ();
20571 if (TARGET_DEBUG_STACK
)
20572 debug_stack_info (info
);
20574 /* Write .extern for any function we will call to save and restore
20576 if (info
->first_fp_reg_save
< 64
20580 int regno
= info
->first_fp_reg_save
- 32;
20582 if ((info
->savres_strategy
& SAVE_INLINE_FPRS
) == 0)
20584 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/true,
20585 /*gpr=*/false, /*lr=*/false);
20586 fprintf (file
, "\t.extern %s\n", name
);
20588 if ((info
->savres_strategy
& REST_INLINE_FPRS
) == 0)
20590 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/false,
20591 /*gpr=*/false, /*lr=*/true);
20592 fprintf (file
, "\t.extern %s\n", name
);
20596 /* Write .extern for AIX common mode routines, if needed. */
20597 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
20599 fputs ("\t.extern __mulh\n", file
);
20600 fputs ("\t.extern __mull\n", file
);
20601 fputs ("\t.extern __divss\n", file
);
20602 fputs ("\t.extern __divus\n", file
);
20603 fputs ("\t.extern __quoss\n", file
);
20604 fputs ("\t.extern __quous\n", file
);
20605 common_mode_defined
= 1;
20608 rs6000_pic_labelno
++;
20611 /* Non-zero if vmx regs are restored before the frame pop, zero if
20612 we restore after the pop when possible. */
20613 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20615 /* Reload CR from REG. */
20618 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
20623 if (using_mfcr_multiple
)
20625 for (i
= 0; i
< 8; i
++)
20626 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20628 gcc_assert (count
);
20631 if (using_mfcr_multiple
&& count
> 1)
20636 p
= rtvec_alloc (count
);
20639 for (i
= 0; i
< 8; i
++)
20640 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20642 rtvec r
= rtvec_alloc (2);
20643 RTVEC_ELT (r
, 0) = reg
;
20644 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
20645 RTVEC_ELT (p
, ndx
) =
20646 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
20647 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
20650 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20651 gcc_assert (ndx
== count
);
20654 for (i
= 0; i
< 8; i
++)
20655 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20657 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
20663 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20664 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20665 below stack pointer not cloberred by signals. */
20668 offset_below_red_zone_p (HOST_WIDE_INT offset
)
20670 return offset
< (DEFAULT_ABI
== ABI_V4
20672 : TARGET_32BIT
? -220 : -288);
20675 /* Append CFA_RESTORES to any existing REG_NOTES on the last insn. */
20678 emit_cfa_restores (rtx cfa_restores
)
20680 rtx insn
= get_last_insn ();
20681 rtx
*loc
= ®_NOTES (insn
);
20684 loc
= &XEXP (*loc
, 1);
20685 *loc
= cfa_restores
;
20686 RTX_FRAME_RELATED_P (insn
) = 1;
20689 /* Emit function epilogue as insns. */
20692 rs6000_emit_epilogue (int sibcall
)
20694 rs6000_stack_t
*info
;
20695 int restoring_GPRs_inline
;
20696 int restoring_FPRs_inline
;
20697 int using_load_multiple
;
20698 int using_mtcr_multiple
;
20699 int use_backchain_to_restore_sp
;
20703 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
20704 rtx frame_reg_rtx
= sp_reg_rtx
;
20705 rtx cfa_restores
= NULL_RTX
;
20707 rtx cr_save_reg
= NULL_RTX
;
20708 enum machine_mode reg_mode
= Pmode
;
20709 int reg_size
= TARGET_32BIT
? 4 : 8;
20712 info
= rs6000_stack_info ();
20714 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
20716 reg_mode
= V2SImode
;
20720 strategy
= info
->savres_strategy
;
20721 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
20722 restoring_FPRs_inline
= sibcall
|| (strategy
& REST_INLINE_FPRS
);
20723 restoring_GPRs_inline
= sibcall
|| (strategy
& REST_INLINE_GPRS
);
20724 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
20725 || rs6000_cpu
== PROCESSOR_PPC603
20726 || rs6000_cpu
== PROCESSOR_PPC750
20728 /* Restore via the backchain when we have a large frame, since this
20729 is more efficient than an addis, addi pair. The second condition
20730 here will not trigger at the moment; We don't actually need a
20731 frame pointer for alloca, but the generic parts of the compiler
20732 give us one anyway. */
20733 use_backchain_to_restore_sp
= (info
->total_size
> 32767 - info
->lr_save_offset
20734 || (cfun
->calls_alloca
20735 && !frame_pointer_needed
));
20736 restore_lr
= (info
->lr_save_p
20737 && (restoring_FPRs_inline
20738 || (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
))
20739 && (restoring_GPRs_inline
20740 || info
->first_fp_reg_save
< 64));
20742 if (WORLD_SAVE_P (info
))
20746 const char *alloc_rname
;
20749 /* eh_rest_world_r10 will return to the location saved in the LR
20750 stack slot (which is not likely to be our caller.)
20751 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20752 rest_world is similar, except any R10 parameter is ignored.
20753 The exception-handling stuff that was here in 2.95 is no
20754 longer necessary. */
20758 + 32 - info
->first_gp_reg_save
20759 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
20760 + 63 + 1 - info
->first_fp_reg_save
);
20762 strcpy (rname
, ((crtl
->calls_eh_return
) ?
20763 "*eh_rest_world_r10" : "*rest_world"));
20764 alloc_rname
= ggc_strdup (rname
);
20767 RTVEC_ELT (p
, j
++) = ret_rtx
;
20768 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
20769 gen_rtx_REG (Pmode
,
20772 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
20773 /* The instruction pattern requires a clobber here;
20774 it is shared with the restVEC helper. */
20776 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
20779 /* CR register traditionally saved as CR2. */
20780 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
20781 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20782 GEN_INT (info
->cr_save_offset
));
20783 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20785 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20787 if (flag_shrink_wrap
)
20789 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
,
20790 gen_rtx_REG (Pmode
, LR_REGNO
),
20792 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
20796 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20798 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20799 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20800 GEN_INT (info
->gp_save_offset
20802 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20804 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20805 if (flag_shrink_wrap
)
20806 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
20808 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
20810 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
20811 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20812 GEN_INT (info
->altivec_save_offset
20814 rtx mem
= gen_frame_mem (V4SImode
, addr
);
20816 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20817 if (flag_shrink_wrap
)
20818 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
20820 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
20822 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20823 ? DFmode
: SFmode
),
20824 info
->first_fp_reg_save
+ i
);
20825 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20826 GEN_INT (info
->fp_save_offset
20828 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20829 ? DFmode
: SFmode
), addr
);
20831 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20832 if (flag_shrink_wrap
)
20833 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
20836 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
20838 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
20840 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
20842 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
20844 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
20845 insn
= emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20847 if (flag_shrink_wrap
)
20849 REG_NOTES (insn
) = cfa_restores
;
20850 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
20851 RTX_FRAME_RELATED_P (insn
) = 1;
20856 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20858 sp_offset
= info
->total_size
;
20860 /* Restore AltiVec registers if we must do so before adjusting the
20862 if (TARGET_ALTIVEC_ABI
20863 && info
->altivec_size
!= 0
20864 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20865 || (DEFAULT_ABI
!= ABI_V4
20866 && offset_below_red_zone_p (info
->altivec_save_offset
))))
20870 if (use_backchain_to_restore_sp
)
20872 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20873 emit_move_insn (frame_reg_rtx
,
20874 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20877 else if (frame_pointer_needed
)
20878 frame_reg_rtx
= hard_frame_pointer_rtx
;
20880 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20881 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20883 rtx addr
, areg
, mem
, reg
;
20885 areg
= gen_rtx_REG (Pmode
, 0);
20887 (areg
, GEN_INT (info
->altivec_save_offset
20889 + 16 * (i
- info
->first_altivec_reg_save
)));
20891 /* AltiVec addressing mode is [reg+reg]. */
20892 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
20893 mem
= gen_frame_mem (V4SImode
, addr
);
20895 reg
= gen_rtx_REG (V4SImode
, i
);
20896 emit_move_insn (reg
, mem
);
20897 if (flag_shrink_wrap
20898 || offset_below_red_zone_p (info
->altivec_save_offset
20899 + (i
- info
->first_altivec_reg_save
)
20901 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
20906 /* Restore VRSAVE if we must do so before adjusting the stack. */
20908 && TARGET_ALTIVEC_VRSAVE
20909 && info
->vrsave_mask
!= 0
20910 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20911 || (DEFAULT_ABI
!= ABI_V4
20912 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
20914 rtx addr
, mem
, reg
;
20916 if (frame_reg_rtx
== sp_reg_rtx
)
20918 if (use_backchain_to_restore_sp
)
20920 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20921 emit_move_insn (frame_reg_rtx
,
20922 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20925 else if (frame_pointer_needed
)
20926 frame_reg_rtx
= hard_frame_pointer_rtx
;
20929 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20930 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
20931 mem
= gen_frame_mem (SImode
, addr
);
20932 reg
= gen_rtx_REG (SImode
, 12);
20933 emit_move_insn (reg
, mem
);
20935 emit_insn (generate_set_vrsave (reg
, info
, 1));
20939 /* If we have a large stack frame, restore the old stack pointer
20940 using the backchain. */
20941 if (use_backchain_to_restore_sp
)
20943 if (frame_reg_rtx
== sp_reg_rtx
)
20945 /* Under V.4, don't reset the stack pointer until after we're done
20946 loading the saved registers. */
20947 if (DEFAULT_ABI
== ABI_V4
)
20948 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20950 insn
= emit_move_insn (frame_reg_rtx
,
20951 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20954 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20955 && DEFAULT_ABI
== ABI_V4
)
20956 /* frame_reg_rtx has been set up by the altivec restore. */
20960 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
20961 frame_reg_rtx
= sp_reg_rtx
;
20964 /* If we have a frame pointer, we can restore the old stack pointer
20966 else if (frame_pointer_needed
)
20968 frame_reg_rtx
= sp_reg_rtx
;
20969 if (DEFAULT_ABI
== ABI_V4
)
20970 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20971 /* Prevent reordering memory accesses against stack pointer restore. */
20972 else if (cfun
->calls_alloca
20973 || offset_below_red_zone_p (-info
->total_size
))
20975 rtx mem1
= gen_rtx_MEM (BLKmode
, hard_frame_pointer_rtx
);
20976 rtx mem2
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
20977 MEM_NOTRAP_P (mem1
) = 1;
20978 MEM_NOTRAP_P (mem2
) = 1;
20979 emit_insn (gen_frame_tie (mem1
, mem2
));
20982 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
20983 GEN_INT (info
->total_size
)));
20986 else if (info
->push_p
20987 && DEFAULT_ABI
!= ABI_V4
20988 && !crtl
->calls_eh_return
)
20990 /* Prevent reordering memory accesses against stack pointer restore. */
20991 if (cfun
->calls_alloca
20992 || offset_below_red_zone_p (-info
->total_size
))
20994 rtx mem
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
20995 MEM_NOTRAP_P (mem
) = 1;
20996 emit_insn (gen_stack_tie (mem
));
20998 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
20999 GEN_INT (info
->total_size
)));
21002 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
21006 REG_NOTES (insn
) = cfa_restores
;
21007 cfa_restores
= NULL_RTX
;
21009 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21010 RTX_FRAME_RELATED_P (insn
) = 1;
21013 /* Restore AltiVec registers if we have not done so already. */
21014 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21015 && TARGET_ALTIVEC_ABI
21016 && info
->altivec_size
!= 0
21017 && (DEFAULT_ABI
== ABI_V4
21018 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
21022 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21023 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21025 rtx addr
, areg
, mem
, reg
;
21027 areg
= gen_rtx_REG (Pmode
, 0);
21029 (areg
, GEN_INT (info
->altivec_save_offset
21031 + 16 * (i
- info
->first_altivec_reg_save
)));
21033 /* AltiVec addressing mode is [reg+reg]. */
21034 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
21035 mem
= gen_frame_mem (V4SImode
, addr
);
21037 reg
= gen_rtx_REG (V4SImode
, i
);
21038 emit_move_insn (reg
, mem
);
21039 if (DEFAULT_ABI
== ABI_V4
|| flag_shrink_wrap
)
21040 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21045 /* Restore VRSAVE if we have not done so already. */
21046 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21048 && TARGET_ALTIVEC_VRSAVE
21049 && info
->vrsave_mask
!= 0
21050 && (DEFAULT_ABI
== ABI_V4
21051 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
21053 rtx addr
, mem
, reg
;
21055 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21056 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
21057 mem
= gen_frame_mem (SImode
, addr
);
21058 reg
= gen_rtx_REG (SImode
, 12);
21059 emit_move_insn (reg
, mem
);
21061 emit_insn (generate_set_vrsave (reg
, info
, 1));
21064 /* Get the old lr if we saved it. If we are restoring registers
21065 out-of-line, then the out-of-line routines can do this for us. */
21066 if (restore_lr
&& restoring_GPRs_inline
)
21068 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21069 info
->lr_save_offset
+ sp_offset
);
21071 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21074 /* Get the old cr if we saved it. */
21075 if (info
->cr_save_p
)
21077 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21078 GEN_INT (info
->cr_save_offset
+ sp_offset
));
21079 rtx mem
= gen_frame_mem (SImode
, addr
);
21081 cr_save_reg
= gen_rtx_REG (SImode
,
21082 DEFAULT_ABI
== ABI_AIX
21083 && !restoring_GPRs_inline
21084 && info
->first_fp_reg_save
< 64
21086 emit_move_insn (cr_save_reg
, mem
);
21089 /* Set LR here to try to overlap restores below. */
21090 if (restore_lr
&& restoring_GPRs_inline
)
21091 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21092 gen_rtx_REG (Pmode
, 0));
21094 /* Load exception handler data registers, if needed. */
21095 if (crtl
->calls_eh_return
)
21097 unsigned int i
, regno
;
21101 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21102 GEN_INT (sp_offset
+ 5 * reg_size
));
21103 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21105 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
21112 regno
= EH_RETURN_DATA_REGNO (i
);
21113 if (regno
== INVALID_REGNUM
)
21116 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
21117 info
->ehrd_offset
+ sp_offset
21118 + reg_size
* (int) i
);
21120 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
21124 /* Restore GPRs. This is done as a PARALLEL if we are using
21125 the load-multiple instructions. */
21127 && info
->spe_64bit_regs_used
21128 && info
->first_gp_reg_save
!= 32)
21130 /* Determine whether we can address all of the registers that need
21131 to be saved with an offset from the stack pointer that fits in
21132 the small const field for SPE memory instructions. */
21133 int spe_regs_addressable_via_sp
21134 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
21135 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
21136 && restoring_GPRs_inline
);
21139 if (spe_regs_addressable_via_sp
)
21140 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
21143 rtx old_frame_reg_rtx
= frame_reg_rtx
;
21144 /* Make r11 point to the start of the SPE save area. We worried about
21145 not clobbering it when we were saving registers in the prologue.
21146 There's no need to worry here because the static chain is passed
21147 anew to every function. */
21148 int ool_adjust
= (restoring_GPRs_inline
21150 : (info
->first_gp_reg_save
21151 - (FIRST_SAVRES_REGISTER
+ 1)) * 8);
21153 if (frame_reg_rtx
== sp_reg_rtx
)
21154 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21155 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
21156 GEN_INT (info
->spe_gp_save_offset
21159 /* Keep the invariant that frame_reg_rtx + sp_offset points
21160 at the top of the stack frame. */
21161 sp_offset
= -info
->spe_gp_save_offset
;
21166 if (restoring_GPRs_inline
)
21168 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21169 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21171 rtx offset
, addr
, mem
, reg
;
21173 /* We're doing all this to ensure that the immediate offset
21174 fits into the immediate field of 'evldd'. */
21175 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
21177 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
21178 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
21179 mem
= gen_rtx_MEM (V2SImode
, addr
);
21180 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21182 emit_move_insn (reg
, mem
);
21186 rs6000_emit_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
21188 /*savep=*/false, /*gpr=*/true,
21191 else if (!restoring_GPRs_inline
)
21193 /* We are jumping to an out-of-line function. */
21194 bool can_use_exit
= info
->first_fp_reg_save
== 64;
21196 /* Emit stack reset code if we need it. */
21199 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21200 sp_offset
, can_use_exit
);
21201 if (DEFAULT_ABI
== ABI_DARWIN
)
21202 /* we only need a copy, no fprs were saved. */
21203 emit_move_insn (gen_rtx_REG (reg_mode
, 11), frame_reg_rtx
);
21205 if (info
->cr_save_p
)
21206 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21210 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode
, DEFAULT_ABI
== ABI_AIX
21213 GEN_INT (sp_offset
- info
->fp_size
)));
21214 if (REGNO (frame_reg_rtx
) == 11)
21215 sp_offset
+= info
->fp_size
;
21218 rs6000_emit_savres_rtx (info
, frame_reg_rtx
,
21219 info
->gp_save_offset
, reg_mode
,
21220 /*savep=*/false, /*gpr=*/true,
21221 /*lr=*/can_use_exit
);
21223 else if (using_load_multiple
)
21226 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
21227 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21229 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21230 GEN_INT (info
->gp_save_offset
21233 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21234 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21236 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21238 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21242 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21243 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21245 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21246 GEN_INT (info
->gp_save_offset
21249 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21250 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21252 emit_move_insn (reg
, mem
);
21256 if (DEFAULT_ABI
== ABI_V4
|| flag_shrink_wrap
)
21258 /* If the frame pointer was used then we can't delay emitting
21259 a REG_CFA_DEF_CFA note. This must happen on the insn that
21260 restores the frame pointer, r31. We may have already emitted
21261 a REG_CFA_DEF_CFA note, but that's OK; A duplicate is
21262 discarded by dwarf2cfi.c/dwarf2out.c, and in any case would
21263 be harmless if emitted. */
21264 if (frame_pointer_needed
)
21266 insn
= get_last_insn ();
21267 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21268 plus_constant (frame_reg_rtx
, sp_offset
));
21269 RTX_FRAME_RELATED_P (insn
) = 1;
21272 /* Set up cfa_restores. We always need these when
21273 shrink-wrapping. If not shrink-wrapping then we only need
21274 the cfa_restore when the stack location is no longer valid.
21275 The cfa_restores must be emitted on or before the insn that
21276 invalidates the stack, and of course must not be emitted
21277 before the insn that actually does the restore. The latter
21278 is why the LR cfa_restore condition below is a little
21279 complicated. It's also why it is a bad idea to emit the
21280 cfa_restores as a group on the last instruction here that
21281 actually does a restore: That insn may be reordered with
21282 respect to others doing restores. */
21283 if (info
->cr_save_p
)
21284 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
,
21285 gen_rtx_REG (SImode
, CR2_REGNO
),
21287 if (flag_shrink_wrap
21289 || (info
->lr_save_p
21290 && !restoring_GPRs_inline
21291 && info
->first_fp_reg_save
== 64)))
21292 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
,
21293 gen_rtx_REG (Pmode
, LR_REGNO
),
21296 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
21297 if (!restoring_GPRs_inline
21298 || using_load_multiple
21299 || rs6000_reg_live_or_pic_offset_p (i
))
21301 rtx reg
= gen_rtx_REG (reg_mode
, i
);
21303 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
21307 if (!restoring_GPRs_inline
21308 && info
->first_fp_reg_save
== 64)
21310 /* We are jumping to an out-of-line function. */
21312 emit_cfa_restores (cfa_restores
);
21316 if (restore_lr
&& !restoring_GPRs_inline
)
21318 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21319 info
->lr_save_offset
+ sp_offset
);
21321 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21322 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21323 gen_rtx_REG (Pmode
, 0));
21326 /* Restore fpr's if we need to do it without calling a function. */
21327 if (restoring_FPRs_inline
)
21328 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21329 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+ i
)
21330 && !call_used_regs
[info
->first_fp_reg_save
+ i
]))
21332 rtx addr
, mem
, reg
;
21333 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21334 GEN_INT (info
->fp_save_offset
21337 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21338 ? DFmode
: SFmode
), addr
);
21339 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21340 ? DFmode
: SFmode
),
21341 info
->first_fp_reg_save
+ i
);
21343 emit_move_insn (reg
, mem
);
21344 if (DEFAULT_ABI
== ABI_V4
|| flag_shrink_wrap
)
21345 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
21348 /* If we saved cr, restore it here. Just those that were used. */
21349 if (info
->cr_save_p
)
21350 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21352 /* If this is V.4, unwind the stack pointer after all of the loads
21354 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21355 sp_offset
, !restoring_FPRs_inline
);
21360 REG_NOTES (insn
) = cfa_restores
;
21361 cfa_restores
= NULL_RTX
;
21363 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21364 RTX_FRAME_RELATED_P (insn
) = 1;
21367 if (crtl
->calls_eh_return
)
21369 rtx sa
= EH_RETURN_STACKADJ_RTX
;
21370 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
21376 bool lr
= (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
) == 0;
21377 if (! restoring_FPRs_inline
)
21379 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
21380 RTVEC_ELT (p
, 0) = ret_rtx
;
21386 /* We can't hang the cfa_restores off a simple return,
21387 since the shrink-wrap code sometimes uses an existing
21388 return. This means there might be a path from
21389 pre-prologue code to this return, and dwarf2cfi code
21390 wants the eh_frame unwinder state to be the same on
21391 all paths to any point. So we need to emit the
21392 cfa_restores before the return. For -m64 we really
21393 don't need epilogue cfa_restores at all, except for
21394 this irritating dwarf2cfi with shrink-wrap
21395 requirement; The stack red-zone means eh_frame info
21396 from the prologue telling the unwinder to restore
21397 from the stack is perfectly good right to the end of
21399 emit_insn (gen_blockage ());
21400 emit_cfa_restores (cfa_restores
);
21401 cfa_restores
= NULL_RTX
;
21403 p
= rtvec_alloc (2);
21404 RTVEC_ELT (p
, 0) = simple_return_rtx
;
21407 RTVEC_ELT (p
, 1) = ((restoring_FPRs_inline
|| !lr
)
21408 ? gen_rtx_USE (VOIDmode
,
21409 gen_rtx_REG (Pmode
, LR_REGNO
))
21410 : gen_rtx_CLOBBER (VOIDmode
,
21411 gen_rtx_REG (Pmode
, LR_REGNO
)));
21413 /* If we have to restore more than two FP registers, branch to the
21414 restore function. It will return to our caller. */
21415 if (! restoring_FPRs_inline
)
21420 if ((DEFAULT_ABI
== ABI_V4
|| flag_shrink_wrap
)
21422 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
,
21423 gen_rtx_REG (Pmode
, LR_REGNO
),
21426 sym
= rs6000_savres_routine_sym (info
,
21430 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
21431 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
21432 gen_rtx_REG (Pmode
,
21433 DEFAULT_ABI
== ABI_AIX
21435 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21437 rtx addr
, mem
, reg
;
21439 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
21440 GEN_INT (info
->fp_save_offset
+ 8 * i
));
21441 mem
= gen_frame_mem (DFmode
, addr
);
21442 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
21444 RTVEC_ELT (p
, i
+ 4) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21445 if (DEFAULT_ABI
== ABI_V4
|| flag_shrink_wrap
)
21446 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21451 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21457 /* Ensure the cfa_restores are hung off an insn that won't
21458 be reordered above other restores. */
21459 emit_insn (gen_blockage ());
21461 emit_cfa_restores (cfa_restores
);
21465 /* Write function epilogue. */
21468 rs6000_output_function_epilogue (FILE *file
,
21469 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
21472 macho_branch_islands ();
21473 /* Mach-O doesn't support labels at the end of objects, so if
21474 it looks like we might want one, insert a NOP. */
21476 rtx insn
= get_last_insn ();
21477 rtx deleted_debug_label
= NULL_RTX
;
21480 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
21482 /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
21483 notes only, instead set their CODE_LABEL_NUMBER to -1,
21484 otherwise there would be code generation differences
21485 in between -g and -g0. */
21486 if (NOTE_P (insn
) && NOTE_KIND (insn
) == NOTE_INSN_DELETED_DEBUG_LABEL
)
21487 deleted_debug_label
= insn
;
21488 insn
= PREV_INSN (insn
);
21493 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
21494 fputs ("\tnop\n", file
);
21495 else if (deleted_debug_label
)
21496 for (insn
= deleted_debug_label
; insn
; insn
= NEXT_INSN (insn
))
21497 if (NOTE_KIND (insn
) == NOTE_INSN_DELETED_DEBUG_LABEL
)
21498 CODE_LABEL_NUMBER (insn
) = -1;
21502 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21505 We don't output a traceback table if -finhibit-size-directive was
21506 used. The documentation for -finhibit-size-directive reads
21507 ``don't output a @code{.size} assembler directive, or anything
21508 else that would cause trouble if the function is split in the
21509 middle, and the two halves are placed at locations far apart in
21510 memory.'' The traceback table has this property, since it
21511 includes the offset from the start of the function to the
21512 traceback table itself.
21514 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21515 different traceback table. */
21516 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
21517 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
21519 const char *fname
= NULL
;
21520 const char *language_string
= lang_hooks
.name
;
21521 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
21523 int optional_tbtab
;
21524 rs6000_stack_t
*info
= rs6000_stack_info ();
21526 if (rs6000_traceback
== traceback_full
)
21527 optional_tbtab
= 1;
21528 else if (rs6000_traceback
== traceback_part
)
21529 optional_tbtab
= 0;
21531 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
21533 if (optional_tbtab
)
21535 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
21536 while (*fname
== '.') /* V.4 encodes . in the name */
21539 /* Need label immediately before tbtab, so we can compute
21540 its offset from the function start. */
21541 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
21542 ASM_OUTPUT_LABEL (file
, fname
);
21545 /* The .tbtab pseudo-op can only be used for the first eight
21546 expressions, since it can't handle the possibly variable
21547 length fields that follow. However, if you omit the optional
21548 fields, the assembler outputs zeros for all optional fields
21549 anyways, giving each variable length field is minimum length
21550 (as defined in sys/debug.h). Thus we can not use the .tbtab
21551 pseudo-op at all. */
21553 /* An all-zero word flags the start of the tbtab, for debuggers
21554 that have to find it by searching forward from the entry
21555 point or from the current pc. */
21556 fputs ("\t.long 0\n", file
);
21558 /* Tbtab format type. Use format type 0. */
21559 fputs ("\t.byte 0,", file
);
21561 /* Language type. Unfortunately, there does not seem to be any
21562 official way to discover the language being compiled, so we
21563 use language_string.
21564 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21565 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21566 a number, so for now use 9. LTO and Go aren't assigned numbers
21567 either, so for now use 0. */
21568 if (! strcmp (language_string
, "GNU C")
21569 || ! strcmp (language_string
, "GNU GIMPLE")
21570 || ! strcmp (language_string
, "GNU Go"))
21572 else if (! strcmp (language_string
, "GNU F77")
21573 || ! strcmp (language_string
, "GNU Fortran"))
21575 else if (! strcmp (language_string
, "GNU Pascal"))
21577 else if (! strcmp (language_string
, "GNU Ada"))
21579 else if (! strcmp (language_string
, "GNU C++")
21580 || ! strcmp (language_string
, "GNU Objective-C++"))
21582 else if (! strcmp (language_string
, "GNU Java"))
21584 else if (! strcmp (language_string
, "GNU Objective-C"))
21587 gcc_unreachable ();
21588 fprintf (file
, "%d,", i
);
21590 /* 8 single bit fields: global linkage (not set for C extern linkage,
21591 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21592 from start of procedure stored in tbtab, internal function, function
21593 has controlled storage, function has no toc, function uses fp,
21594 function logs/aborts fp operations. */
21595 /* Assume that fp operations are used if any fp reg must be saved. */
21596 fprintf (file
, "%d,",
21597 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
21599 /* 6 bitfields: function is interrupt handler, name present in
21600 proc table, function calls alloca, on condition directives
21601 (controls stack walks, 3 bits), saves condition reg, saves
21603 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21604 set up as a frame pointer, even when there is no alloca call. */
21605 fprintf (file
, "%d,",
21606 ((optional_tbtab
<< 6)
21607 | ((optional_tbtab
& frame_pointer_needed
) << 5)
21608 | (info
->cr_save_p
<< 1)
21609 | (info
->lr_save_p
)));
21611 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21613 fprintf (file
, "%d,",
21614 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
21616 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21617 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
21619 if (optional_tbtab
)
21621 /* Compute the parameter info from the function decl argument
21624 int next_parm_info_bit
= 31;
21626 for (decl
= DECL_ARGUMENTS (current_function_decl
);
21627 decl
; decl
= DECL_CHAIN (decl
))
21629 rtx parameter
= DECL_INCOMING_RTL (decl
);
21630 enum machine_mode mode
= GET_MODE (parameter
);
21632 if (GET_CODE (parameter
) == REG
)
21634 if (SCALAR_FLOAT_MODE_P (mode
))
21655 gcc_unreachable ();
21658 /* If only one bit will fit, don't or in this entry. */
21659 if (next_parm_info_bit
> 0)
21660 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
21661 next_parm_info_bit
-= 2;
21665 fixed_parms
+= ((GET_MODE_SIZE (mode
)
21666 + (UNITS_PER_WORD
- 1))
21668 next_parm_info_bit
-= 1;
21674 /* Number of fixed point parameters. */
21675 /* This is actually the number of words of fixed point parameters; thus
21676 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21677 fprintf (file
, "%d,", fixed_parms
);
21679 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21681 /* This is actually the number of fp registers that hold parameters;
21682 and thus the maximum value is 13. */
21683 /* Set parameters on stack bit if parameters are not in their original
21684 registers, regardless of whether they are on the stack? Xlc
21685 seems to set the bit when not optimizing. */
21686 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
21688 if (! optional_tbtab
)
21691 /* Optional fields follow. Some are variable length. */
21693 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21694 11 double float. */
21695 /* There is an entry for each parameter in a register, in the order that
21696 they occur in the parameter list. Any intervening arguments on the
21697 stack are ignored. If the list overflows a long (max possible length
21698 34 bits) then completely leave off all elements that don't fit. */
21699 /* Only emit this long if there was at least one parameter. */
21700 if (fixed_parms
|| float_parms
)
21701 fprintf (file
, "\t.long %d\n", parm_info
);
21703 /* Offset from start of code to tb table. */
21704 fputs ("\t.long ", file
);
21705 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
21706 RS6000_OUTPUT_BASENAME (file
, fname
);
21708 rs6000_output_function_entry (file
, fname
);
21711 /* Interrupt handler mask. */
21712 /* Omit this long, since we never set the interrupt handler bit
21715 /* Number of CTL (controlled storage) anchors. */
21716 /* Omit this long, since the has_ctl bit is never set above. */
21718 /* Displacement into stack of each CTL anchor. */
21719 /* Omit this list of longs, because there are no CTL anchors. */
21721 /* Length of function name. */
21724 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
21726 /* Function name. */
21727 assemble_string (fname
, strlen (fname
));
21729 /* Register for alloca automatic storage; this is always reg 31.
21730 Only emit this if the alloca bit was set above. */
21731 if (frame_pointer_needed
)
21732 fputs ("\t.byte 31\n", file
);
21734 fputs ("\t.align 2\n", file
);
21738 /* A C compound statement that outputs the assembler code for a thunk
21739 function, used to implement C++ virtual function calls with
21740 multiple inheritance. The thunk acts as a wrapper around a virtual
21741 function, adjusting the implicit object parameter before handing
21742 control off to the real function.
21744 First, emit code to add the integer DELTA to the location that
21745 contains the incoming first argument. Assume that this argument
21746 contains a pointer, and is the one used to pass the `this' pointer
21747 in C++. This is the incoming argument *before* the function
21748 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21749 values of all other incoming arguments.
21751 After the addition, emit code to jump to FUNCTION, which is a
21752 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21753 not touch the return address. Hence returning from FUNCTION will
21754 return to whoever called the current `thunk'.
21756 The effect must be as if FUNCTION had been called directly with the
21757 adjusted first argument. This macro is responsible for emitting
21758 all of the code for a thunk function; output_function_prologue()
21759 and output_function_epilogue() are not invoked.
21761 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21762 been extracted from it.) It might possibly be useful on some
21763 targets, but probably not.
21765 If you do not define this macro, the target-independent code in the
21766 C++ frontend will generate a less efficient heavyweight thunk that
21767 calls FUNCTION instead of jumping to it. The generic approach does
21768 not support varargs. */
21771 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
21772 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
21775 rtx this_rtx
, insn
, funexp
;
21777 reload_completed
= 1;
21778 epilogue_completed
= 1;
21780 /* Mark the end of the (empty) prologue. */
21781 emit_note (NOTE_INSN_PROLOGUE_END
);
21783 /* Find the "this" pointer. If the function returns a structure,
21784 the structure return pointer is in r3. */
21785 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
21786 this_rtx
= gen_rtx_REG (Pmode
, 4);
21788 this_rtx
= gen_rtx_REG (Pmode
, 3);
21790 /* Apply the constant offset, if required. */
21792 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
21794 /* Apply the offset from the vtable, if required. */
21797 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
21798 rtx tmp
= gen_rtx_REG (Pmode
, 12);
21800 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
21801 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
21803 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
21804 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
21808 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
21810 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
21812 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
21815 /* Generate a tail call to the target function. */
21816 if (!TREE_USED (function
))
21818 assemble_external (function
);
21819 TREE_USED (function
) = 1;
21821 funexp
= XEXP (DECL_RTL (function
), 0);
21822 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
21825 if (MACHOPIC_INDIRECT
)
21826 funexp
= machopic_indirect_call_target (funexp
);
21829 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21830 generate sibcall RTL explicitly. */
21831 insn
= emit_call_insn (
21832 gen_rtx_PARALLEL (VOIDmode
,
21834 gen_rtx_CALL (VOIDmode
,
21835 funexp
, const0_rtx
),
21836 gen_rtx_USE (VOIDmode
, const0_rtx
),
21837 gen_rtx_USE (VOIDmode
,
21838 gen_rtx_REG (SImode
,
21840 simple_return_rtx
)));
21841 SIBLING_CALL_P (insn
) = 1;
21844 /* Run just enough of rest_of_compilation to get the insns emitted.
21845 There's not really enough bulk here to make other passes such as
21846 instruction scheduling worth while. Note that use_thunk calls
21847 assemble_start_function and assemble_end_function. */
21848 insn
= get_insns ();
21849 insn_locators_alloc ();
21850 shorten_branches (insn
);
21851 final_start_function (insn
, file
, 1);
21852 final (insn
, file
, 1);
21853 final_end_function ();
21855 reload_completed
= 0;
21856 epilogue_completed
= 0;
21859 /* A quick summary of the various types of 'constant-pool tables'
21862 Target Flags Name One table per
21863 AIX (none) AIX TOC object file
21864 AIX -mfull-toc AIX TOC object file
21865 AIX -mminimal-toc AIX minimal TOC translation unit
21866 SVR4/EABI (none) SVR4 SDATA object file
21867 SVR4/EABI -fpic SVR4 pic object file
21868 SVR4/EABI -fPIC SVR4 PIC translation unit
21869 SVR4/EABI -mrelocatable EABI TOC function
21870 SVR4/EABI -maix AIX TOC object file
21871 SVR4/EABI -maix -mminimal-toc
21872 AIX minimal TOC translation unit
21874 Name Reg. Set by entries contains:
21875 made by addrs? fp? sum?
21877 AIX TOC 2 crt0 as Y option option
21878 AIX minimal TOC 30 prolog gcc Y Y option
21879 SVR4 SDATA 13 crt0 gcc N Y N
21880 SVR4 pic 30 prolog ld Y not yet N
21881 SVR4 PIC 30 prolog gcc Y option option
21882 EABI TOC 30 prolog gcc Y option option
21886 /* Hash functions for the hash table. */
21889 rs6000_hash_constant (rtx k
)
21891 enum rtx_code code
= GET_CODE (k
);
21892 enum machine_mode mode
= GET_MODE (k
);
21893 unsigned result
= (code
<< 3) ^ mode
;
21894 const char *format
;
21897 format
= GET_RTX_FORMAT (code
);
21898 flen
= strlen (format
);
21904 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
21907 if (mode
!= VOIDmode
)
21908 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
21920 for (; fidx
< flen
; fidx
++)
21921 switch (format
[fidx
])
21926 const char *str
= XSTR (k
, fidx
);
21927 len
= strlen (str
);
21928 result
= result
* 613 + len
;
21929 for (i
= 0; i
< len
; i
++)
21930 result
= result
* 613 + (unsigned) str
[i
];
21935 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
21939 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
21942 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
21943 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
21947 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
21948 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
21955 gcc_unreachable ();
21962 toc_hash_function (const void *hash_entry
)
21964 const struct toc_hash_struct
*thc
=
21965 (const struct toc_hash_struct
*) hash_entry
;
21966 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
21969 /* Compare H1 and H2 for equivalence. */
21972 toc_hash_eq (const void *h1
, const void *h2
)
21974 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
21975 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
21977 if (((const struct toc_hash_struct
*) h1
)->key_mode
21978 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
21981 return rtx_equal_p (r1
, r2
);
21984 /* These are the names given by the C++ front-end to vtables, and
21985 vtable-like objects. Ideally, this logic should not be here;
21986 instead, there should be some programmatic way of inquiring as
21987 to whether or not an object is a vtable. */
21989 #define VTABLE_NAME_P(NAME) \
21990 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21991 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21992 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21993 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21994 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21996 #ifdef NO_DOLLAR_IN_LABEL
21997 /* Return a GGC-allocated character string translating dollar signs in
21998 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22001 rs6000_xcoff_strip_dollar (const char *name
)
22007 q
= (const char *) strchr (name
, '$');
22009 if (q
== 0 || q
== name
)
22012 len
= strlen (name
);
22013 strip
= XALLOCAVEC (char, len
+ 1);
22014 strcpy (strip
, name
);
22015 p
= strip
+ (q
- name
);
22019 p
= strchr (p
+ 1, '$');
22022 return ggc_alloc_string (strip
, len
);
22027 rs6000_output_symbol_ref (FILE *file
, rtx x
)
22029 /* Currently C++ toc references to vtables can be emitted before it
22030 is decided whether the vtable is public or private. If this is
22031 the case, then the linker will eventually complain that there is
22032 a reference to an unknown section. Thus, for vtables only,
22033 we emit the TOC reference to reference the symbol and not the
22035 const char *name
= XSTR (x
, 0);
22037 if (VTABLE_NAME_P (name
))
22039 RS6000_OUTPUT_BASENAME (file
, name
);
22042 assemble_name (file
, name
);
22045 /* Output a TOC entry. We derive the entry name from what is being
22049 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
22052 const char *name
= buf
;
22054 HOST_WIDE_INT offset
= 0;
22056 gcc_assert (!TARGET_NO_TOC
);
22058 /* When the linker won't eliminate them, don't output duplicate
22059 TOC entries (this happens on AIX if there is any kind of TOC,
22060 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22062 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
22064 struct toc_hash_struct
*h
;
22067 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22068 time because GGC is not initialized at that point. */
22069 if (toc_hash_table
== NULL
)
22070 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
22071 toc_hash_eq
, NULL
);
22073 h
= ggc_alloc_toc_hash_struct ();
22075 h
->key_mode
= mode
;
22076 h
->labelno
= labelno
;
22078 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
22079 if (*found
== NULL
)
22081 else /* This is indeed a duplicate.
22082 Set this label equal to that label. */
22084 fputs ("\t.set ", file
);
22085 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22086 fprintf (file
, "%d,", labelno
);
22087 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22088 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
22094 /* If we're going to put a double constant in the TOC, make sure it's
22095 aligned properly when strict alignment is on. */
22096 if (GET_CODE (x
) == CONST_DOUBLE
22097 && STRICT_ALIGNMENT
22098 && GET_MODE_BITSIZE (mode
) >= 64
22099 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
22100 ASM_OUTPUT_ALIGN (file
, 3);
22103 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
22105 /* Handle FP constants specially. Note that if we have a minimal
22106 TOC, things we put here aren't actually in the TOC, so we can allow
22108 if (GET_CODE (x
) == CONST_DOUBLE
&&
22109 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
22111 REAL_VALUE_TYPE rv
;
22114 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22115 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22116 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
22118 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
22122 if (TARGET_MINIMAL_TOC
)
22123 fputs (DOUBLE_INT_ASM_OP
, file
);
22125 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22126 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22127 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22128 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
22129 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22130 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22135 if (TARGET_MINIMAL_TOC
)
22136 fputs ("\t.long ", file
);
22138 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22139 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22140 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22141 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22142 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22143 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22147 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22148 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
22150 REAL_VALUE_TYPE rv
;
22153 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22155 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22156 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
22158 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
22162 if (TARGET_MINIMAL_TOC
)
22163 fputs (DOUBLE_INT_ASM_OP
, file
);
22165 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22166 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22167 fprintf (file
, "0x%lx%08lx\n",
22168 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22173 if (TARGET_MINIMAL_TOC
)
22174 fputs ("\t.long ", file
);
22176 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22177 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22178 fprintf (file
, "0x%lx,0x%lx\n",
22179 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22183 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22184 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
22186 REAL_VALUE_TYPE rv
;
22189 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22190 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22191 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
22193 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
22197 if (TARGET_MINIMAL_TOC
)
22198 fputs (DOUBLE_INT_ASM_OP
, file
);
22200 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22201 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
22206 if (TARGET_MINIMAL_TOC
)
22207 fputs ("\t.long ", file
);
22209 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22210 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
22214 else if (GET_MODE (x
) == VOIDmode
22215 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
22217 unsigned HOST_WIDE_INT low
;
22218 HOST_WIDE_INT high
;
22220 if (GET_CODE (x
) == CONST_DOUBLE
)
22222 low
= CONST_DOUBLE_LOW (x
);
22223 high
= CONST_DOUBLE_HIGH (x
);
22226 #if HOST_BITS_PER_WIDE_INT == 32
22229 high
= (low
& 0x80000000) ? ~0 : 0;
22233 low
= INTVAL (x
) & 0xffffffff;
22234 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
22238 /* TOC entries are always Pmode-sized, but since this
22239 is a bigendian machine then if we're putting smaller
22240 integer constants in the TOC we have to pad them.
22241 (This is still a win over putting the constants in
22242 a separate constant pool, because then we'd have
22243 to have both a TOC entry _and_ the actual constant.)
22245 For a 32-bit target, CONST_INT values are loaded and shifted
22246 entirely within `low' and can be stored in one TOC entry. */
22248 /* It would be easy to make this work, but it doesn't now. */
22249 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
22251 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
22253 #if HOST_BITS_PER_WIDE_INT == 32
22254 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
22255 POINTER_SIZE
, &low
, &high
, 0);
22258 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
22259 high
= (HOST_WIDE_INT
) low
>> 32;
22266 if (TARGET_MINIMAL_TOC
)
22267 fputs (DOUBLE_INT_ASM_OP
, file
);
22269 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22270 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22271 fprintf (file
, "0x%lx%08lx\n",
22272 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22277 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
22279 if (TARGET_MINIMAL_TOC
)
22280 fputs ("\t.long ", file
);
22282 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22283 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22284 fprintf (file
, "0x%lx,0x%lx\n",
22285 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22289 if (TARGET_MINIMAL_TOC
)
22290 fputs ("\t.long ", file
);
22292 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
22293 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
22299 if (GET_CODE (x
) == CONST
)
22301 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
22302 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
22304 base
= XEXP (XEXP (x
, 0), 0);
22305 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
22308 switch (GET_CODE (base
))
22311 name
= XSTR (base
, 0);
22315 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
22316 CODE_LABEL_NUMBER (XEXP (base
, 0)));
22320 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
22324 gcc_unreachable ();
22327 if (TARGET_MINIMAL_TOC
)
22328 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
22331 fputs ("\t.tc ", file
);
22332 RS6000_OUTPUT_BASENAME (file
, name
);
22335 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
22337 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
22339 fputs ("[TC],", file
);
22342 /* Currently C++ toc references to vtables can be emitted before it
22343 is decided whether the vtable is public or private. If this is
22344 the case, then the linker will eventually complain that there is
22345 a TOC reference to an unknown section. Thus, for vtables only,
22346 we emit the TOC reference to reference the symbol and not the
22348 if (VTABLE_NAME_P (name
))
22350 RS6000_OUTPUT_BASENAME (file
, name
);
22352 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
22353 else if (offset
> 0)
22354 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
22357 output_addr_const (file
, x
);
22361 /* Output an assembler pseudo-op to write an ASCII string of N characters
22362 starting at P to FILE.
22364 On the RS/6000, we have to do this using the .byte operation and
22365 write out special characters outside the quoted string.
22366 Also, the assembler is broken; very long strings are truncated,
22367 so we must artificially break them up early. */
22370 output_ascii (FILE *file
, const char *p
, int n
)
22373 int i
, count_string
;
22374 const char *for_string
= "\t.byte \"";
22375 const char *for_decimal
= "\t.byte ";
22376 const char *to_close
= NULL
;
22379 for (i
= 0; i
< n
; i
++)
22382 if (c
>= ' ' && c
< 0177)
22385 fputs (for_string
, file
);
22388 /* Write two quotes to get one. */
22396 for_decimal
= "\"\n\t.byte ";
22400 if (count_string
>= 512)
22402 fputs (to_close
, file
);
22404 for_string
= "\t.byte \"";
22405 for_decimal
= "\t.byte ";
22413 fputs (for_decimal
, file
);
22414 fprintf (file
, "%d", c
);
22416 for_string
= "\n\t.byte \"";
22417 for_decimal
= ", ";
22423 /* Now close the string if we have written one. Then end the line. */
22425 fputs (to_close
, file
);
22428 /* Generate a unique section name for FILENAME for a section type
22429 represented by SECTION_DESC. Output goes into BUF.
22431 SECTION_DESC can be any string, as long as it is different for each
22432 possible section type.
22434 We name the section in the same manner as xlc. The name begins with an
22435 underscore followed by the filename (after stripping any leading directory
22436 names) with the last period replaced by the string SECTION_DESC. If
22437 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22441 rs6000_gen_section_name (char **buf
, const char *filename
,
22442 const char *section_desc
)
22444 const char *q
, *after_last_slash
, *last_period
= 0;
22448 after_last_slash
= filename
;
22449 for (q
= filename
; *q
; q
++)
22452 after_last_slash
= q
+ 1;
22453 else if (*q
== '.')
22457 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
22458 *buf
= (char *) xmalloc (len
);
22463 for (q
= after_last_slash
; *q
; q
++)
22465 if (q
== last_period
)
22467 strcpy (p
, section_desc
);
22468 p
+= strlen (section_desc
);
22472 else if (ISALNUM (*q
))
22476 if (last_period
== 0)
22477 strcpy (p
, section_desc
);
22482 /* Emit profile function. */
22485 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
22487 /* Non-standard profiling for kernels, which just saves LR then calls
22488 _mcount without worrying about arg saves. The idea is to change
22489 the function prologue as little as possible as it isn't easy to
22490 account for arg save/restore code added just for _mcount. */
22491 if (TARGET_PROFILE_KERNEL
)
22494 if (DEFAULT_ABI
== ABI_AIX
)
22496 #ifndef NO_PROFILE_COUNTERS
22497 # define NO_PROFILE_COUNTERS 0
22499 if (NO_PROFILE_COUNTERS
)
22500 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22501 LCT_NORMAL
, VOIDmode
, 0);
22505 const char *label_name
;
22508 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22509 label_name
= ggc_strdup ((*targetm
.strip_name_encoding
) (buf
));
22510 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
22512 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22513 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
22516 else if (DEFAULT_ABI
== ABI_DARWIN
)
22518 const char *mcount_name
= RS6000_MCOUNT
;
22519 int caller_addr_regno
= LR_REGNO
;
22521 /* Be conservative and always set this, at least for now. */
22522 crtl
->uses_pic_offset_table
= 1;
22525 /* For PIC code, set up a stub and collect the caller's address
22526 from r0, which is where the prologue puts it. */
22527 if (MACHOPIC_INDIRECT
22528 && crtl
->uses_pic_offset_table
)
22529 caller_addr_regno
= 0;
22531 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
22532 LCT_NORMAL
, VOIDmode
, 1,
22533 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
22537 /* Write function profiler code. */
22540 output_function_profiler (FILE *file
, int labelno
)
22544 switch (DEFAULT_ABI
)
22547 gcc_unreachable ();
22552 warning (0, "no profiling of 64-bit code for this ABI");
22555 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22556 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
22557 if (NO_PROFILE_COUNTERS
)
22559 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22560 reg_names
[0], reg_names
[1]);
22562 else if (TARGET_SECURE_PLT
&& flag_pic
)
22564 if (TARGET_LINK_STACK
)
22567 get_ppc476_thunk_name (name
);
22568 asm_fprintf (file
, "\tbl %s\n", name
);
22571 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n");
22572 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22573 reg_names
[0], reg_names
[1]);
22574 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
22575 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
22576 reg_names
[12], reg_names
[12]);
22577 assemble_name (file
, buf
);
22578 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
22579 assemble_name (file
, buf
);
22580 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
22582 else if (flag_pic
== 1)
22584 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
22585 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22586 reg_names
[0], reg_names
[1]);
22587 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
22588 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
22589 assemble_name (file
, buf
);
22590 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
22592 else if (flag_pic
> 1)
22594 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22595 reg_names
[0], reg_names
[1]);
22596 /* Now, we need to get the address of the label. */
22597 if (TARGET_LINK_STACK
)
22600 get_ppc476_thunk_name (name
);
22601 asm_fprintf (file
, "\tbl %s\n\tb 1f\n\t.long ", name
);
22602 assemble_name (file
, buf
);
22603 fputs ("-.\n1:", file
);
22604 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
22605 asm_fprintf (file
, "\taddi %s,%s,4\n",
22606 reg_names
[11], reg_names
[11]);
22610 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
22611 assemble_name (file
, buf
);
22612 fputs ("-.\n1:", file
);
22613 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
22615 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
22616 reg_names
[0], reg_names
[11]);
22617 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
22618 reg_names
[0], reg_names
[0], reg_names
[11]);
22622 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
22623 assemble_name (file
, buf
);
22624 fputs ("@ha\n", file
);
22625 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22626 reg_names
[0], reg_names
[1]);
22627 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
22628 assemble_name (file
, buf
);
22629 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
22632 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22633 fprintf (file
, "\tbl %s%s\n",
22634 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
22639 if (!TARGET_PROFILE_KERNEL
)
22641 /* Don't do anything, done in output_profile_hook (). */
22645 gcc_assert (!TARGET_32BIT
);
22647 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
22648 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
22650 if (cfun
->static_chain_decl
!= NULL
)
22652 asm_fprintf (file
, "\tstd %s,24(%s)\n",
22653 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
22654 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
22655 asm_fprintf (file
, "\tld %s,24(%s)\n",
22656 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
22659 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
22667 /* The following variable value is the last issued insn. */
22669 static rtx last_scheduled_insn
;
22671 /* The following variable helps to balance issuing of load and
22672 store instructions */
22674 static int load_store_pendulum
;
22676 /* Power4 load update and store update instructions are cracked into a
22677 load or store and an integer insn which are executed in the same cycle.
22678 Branches have their own dispatch slot which does not count against the
22679 GCC issue rate, but it changes the program flow so there are no other
22680 instructions to issue in this cycle. */
22683 rs6000_variable_issue_1 (rtx insn
, int more
)
22685 last_scheduled_insn
= insn
;
22686 if (GET_CODE (PATTERN (insn
)) == USE
22687 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22689 cached_can_issue_more
= more
;
22690 return cached_can_issue_more
;
22693 if (insn_terminates_group_p (insn
, current_group
))
22695 cached_can_issue_more
= 0;
22696 return cached_can_issue_more
;
22699 /* If no reservation, but reach here */
22700 if (recog_memoized (insn
) < 0)
22703 if (rs6000_sched_groups
)
22705 if (is_microcoded_insn (insn
))
22706 cached_can_issue_more
= 0;
22707 else if (is_cracked_insn (insn
))
22708 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
22710 cached_can_issue_more
= more
- 1;
22712 return cached_can_issue_more
;
22715 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
22718 cached_can_issue_more
= more
- 1;
22719 return cached_can_issue_more
;
22723 rs6000_variable_issue (FILE *stream
, int verbose
, rtx insn
, int more
)
22725 int r
= rs6000_variable_issue_1 (insn
, more
);
22727 fprintf (stream
, "// rs6000_variable_issue (more = %d) = %d\n", more
, r
);
22731 /* Adjust the cost of a scheduling dependency. Return the new cost of
22732 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22735 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
22737 enum attr_type attr_type
;
22739 if (! recog_memoized (insn
))
22742 switch (REG_NOTE_KIND (link
))
22746 /* Data dependency; DEP_INSN writes a register that INSN reads
22747 some cycles later. */
22749 /* Separate a load from a narrower, dependent store. */
22750 if (rs6000_sched_groups
22751 && GET_CODE (PATTERN (insn
)) == SET
22752 && GET_CODE (PATTERN (dep_insn
)) == SET
22753 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
22754 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
22755 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
22756 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
22759 attr_type
= get_attr_type (insn
);
22764 /* Tell the first scheduling pass about the latency between
22765 a mtctr and bctr (and mtlr and br/blr). The first
22766 scheduling pass will not know about this latency since
22767 the mtctr instruction, which has the latency associated
22768 to it, will be generated by reload. */
22769 return TARGET_POWER
? 5 : 4;
22771 /* Leave some extra cycles between a compare and its
22772 dependent branch, to inhibit expensive mispredicts. */
22773 if ((rs6000_cpu_attr
== CPU_PPC603
22774 || rs6000_cpu_attr
== CPU_PPC604
22775 || rs6000_cpu_attr
== CPU_PPC604E
22776 || rs6000_cpu_attr
== CPU_PPC620
22777 || rs6000_cpu_attr
== CPU_PPC630
22778 || rs6000_cpu_attr
== CPU_PPC750
22779 || rs6000_cpu_attr
== CPU_PPC7400
22780 || rs6000_cpu_attr
== CPU_PPC7450
22781 || rs6000_cpu_attr
== CPU_POWER4
22782 || rs6000_cpu_attr
== CPU_POWER5
22783 || rs6000_cpu_attr
== CPU_POWER7
22784 || rs6000_cpu_attr
== CPU_CELL
)
22785 && recog_memoized (dep_insn
)
22786 && (INSN_CODE (dep_insn
) >= 0))
22788 switch (get_attr_type (dep_insn
))
22792 case TYPE_DELAYED_COMPARE
:
22793 case TYPE_IMUL_COMPARE
:
22794 case TYPE_LMUL_COMPARE
:
22795 case TYPE_FPCOMPARE
:
22796 case TYPE_CR_LOGICAL
:
22797 case TYPE_DELAYED_CR
:
22806 case TYPE_STORE_UX
:
22808 case TYPE_FPSTORE_U
:
22809 case TYPE_FPSTORE_UX
:
22810 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22811 && recog_memoized (dep_insn
)
22812 && (INSN_CODE (dep_insn
) >= 0))
22815 if (GET_CODE (PATTERN (insn
)) != SET
)
22816 /* If this happens, we have to extend this to schedule
22817 optimally. Return default for now. */
22820 /* Adjust the cost for the case where the value written
22821 by a fixed point operation is used as the address
22822 gen value on a store. */
22823 switch (get_attr_type (dep_insn
))
22830 if (! store_data_bypass_p (dep_insn
, insn
))
22834 case TYPE_LOAD_EXT
:
22835 case TYPE_LOAD_EXT_U
:
22836 case TYPE_LOAD_EXT_UX
:
22837 case TYPE_VAR_SHIFT_ROTATE
:
22838 case TYPE_VAR_DELAYED_COMPARE
:
22840 if (! store_data_bypass_p (dep_insn
, insn
))
22846 case TYPE_FAST_COMPARE
:
22849 case TYPE_INSERT_WORD
:
22850 case TYPE_INSERT_DWORD
:
22851 case TYPE_FPLOAD_U
:
22852 case TYPE_FPLOAD_UX
:
22854 case TYPE_STORE_UX
:
22855 case TYPE_FPSTORE_U
:
22856 case TYPE_FPSTORE_UX
:
22858 if (! store_data_bypass_p (dep_insn
, insn
))
22866 case TYPE_IMUL_COMPARE
:
22867 case TYPE_LMUL_COMPARE
:
22869 if (! store_data_bypass_p (dep_insn
, insn
))
22875 if (! store_data_bypass_p (dep_insn
, insn
))
22881 if (! store_data_bypass_p (dep_insn
, insn
))
22894 case TYPE_LOAD_EXT
:
22895 case TYPE_LOAD_EXT_U
:
22896 case TYPE_LOAD_EXT_UX
:
22897 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22898 && recog_memoized (dep_insn
)
22899 && (INSN_CODE (dep_insn
) >= 0))
22902 /* Adjust the cost for the case where the value written
22903 by a fixed point instruction is used within the address
22904 gen portion of a subsequent load(u)(x) */
22905 switch (get_attr_type (dep_insn
))
22912 if (set_to_load_agen (dep_insn
, insn
))
22916 case TYPE_LOAD_EXT
:
22917 case TYPE_LOAD_EXT_U
:
22918 case TYPE_LOAD_EXT_UX
:
22919 case TYPE_VAR_SHIFT_ROTATE
:
22920 case TYPE_VAR_DELAYED_COMPARE
:
22922 if (set_to_load_agen (dep_insn
, insn
))
22928 case TYPE_FAST_COMPARE
:
22931 case TYPE_INSERT_WORD
:
22932 case TYPE_INSERT_DWORD
:
22933 case TYPE_FPLOAD_U
:
22934 case TYPE_FPLOAD_UX
:
22936 case TYPE_STORE_UX
:
22937 case TYPE_FPSTORE_U
:
22938 case TYPE_FPSTORE_UX
:
22940 if (set_to_load_agen (dep_insn
, insn
))
22948 case TYPE_IMUL_COMPARE
:
22949 case TYPE_LMUL_COMPARE
:
22951 if (set_to_load_agen (dep_insn
, insn
))
22957 if (set_to_load_agen (dep_insn
, insn
))
22963 if (set_to_load_agen (dep_insn
, insn
))
22974 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22975 && recog_memoized (dep_insn
)
22976 && (INSN_CODE (dep_insn
) >= 0)
22977 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
22984 /* Fall out to return default cost. */
22988 case REG_DEP_OUTPUT
:
22989 /* Output dependency; DEP_INSN writes a register that INSN writes some
22991 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22992 && recog_memoized (dep_insn
)
22993 && (INSN_CODE (dep_insn
) >= 0))
22995 attr_type
= get_attr_type (insn
);
23000 if (get_attr_type (dep_insn
) == TYPE_FP
)
23004 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
23012 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23017 gcc_unreachable ();
23023 /* Debug version of rs6000_adjust_cost. */
23026 rs6000_debug_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
23028 int ret
= rs6000_adjust_cost (insn
, link
, dep_insn
, cost
);
23034 switch (REG_NOTE_KIND (link
))
23036 default: dep
= "unknown depencency"; break;
23037 case REG_DEP_TRUE
: dep
= "data dependency"; break;
23038 case REG_DEP_OUTPUT
: dep
= "output dependency"; break;
23039 case REG_DEP_ANTI
: dep
= "anti depencency"; break;
23043 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23044 "%s, insn:\n", ret
, cost
, dep
);
23052 /* The function returns a true if INSN is microcoded.
23053 Return false otherwise. */
23056 is_microcoded_insn (rtx insn
)
23058 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23059 || GET_CODE (PATTERN (insn
)) == USE
23060 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23063 if (rs6000_cpu_attr
== CPU_CELL
)
23064 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
23066 if (rs6000_sched_groups
)
23068 enum attr_type type
= get_attr_type (insn
);
23069 if (type
== TYPE_LOAD_EXT_U
23070 || type
== TYPE_LOAD_EXT_UX
23071 || type
== TYPE_LOAD_UX
23072 || type
== TYPE_STORE_UX
23073 || type
== TYPE_MFCR
)
23080 /* The function returns true if INSN is cracked into 2 instructions
23081 by the processor (and therefore occupies 2 issue slots). */
23084 is_cracked_insn (rtx insn
)
23086 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23087 || GET_CODE (PATTERN (insn
)) == USE
23088 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23091 if (rs6000_sched_groups
)
23093 enum attr_type type
= get_attr_type (insn
);
23094 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
23095 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
23096 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
23097 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
23098 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
23099 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
23100 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
23101 || type
== TYPE_INSERT_WORD
)
23108 /* The function returns true if INSN can be issued only from
23109 the branch slot. */
23112 is_branch_slot_insn (rtx insn
)
23114 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23115 || GET_CODE (PATTERN (insn
)) == USE
23116 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23119 if (rs6000_sched_groups
)
23121 enum attr_type type
= get_attr_type (insn
);
23122 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
23130 /* The function returns true if out_inst sets a value that is
23131 used in the address generation computation of in_insn */
23133 set_to_load_agen (rtx out_insn
, rtx in_insn
)
23135 rtx out_set
, in_set
;
23137 /* For performance reasons, only handle the simple case where
23138 both loads are a single_set. */
23139 out_set
= single_set (out_insn
);
23142 in_set
= single_set (in_insn
);
23144 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
23150 /* The function returns true if the target storage location of
23151 out_insn is adjacent to the target storage location of in_insn */
23152 /* Return 1 if memory locations are adjacent. */
23155 adjacent_mem_locations (rtx insn1
, rtx insn2
)
23158 rtx a
= get_store_dest (PATTERN (insn1
));
23159 rtx b
= get_store_dest (PATTERN (insn2
));
23161 if ((GET_CODE (XEXP (a
, 0)) == REG
23162 || (GET_CODE (XEXP (a
, 0)) == PLUS
23163 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
23164 && (GET_CODE (XEXP (b
, 0)) == REG
23165 || (GET_CODE (XEXP (b
, 0)) == PLUS
23166 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
23168 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
23171 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
23173 reg0
= XEXP (XEXP (a
, 0), 0);
23174 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
23177 reg0
= XEXP (a
, 0);
23179 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
23181 reg1
= XEXP (XEXP (b
, 0), 0);
23182 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
23185 reg1
= XEXP (b
, 0);
23187 val_diff
= val1
- val0
;
23189 return ((REGNO (reg0
) == REGNO (reg1
))
23190 && ((MEM_SIZE_KNOWN_P (a
) && val_diff
== MEM_SIZE (a
))
23191 || (MEM_SIZE_KNOWN_P (b
) && val_diff
== -MEM_SIZE (b
))));
23197 /* A C statement (sans semicolon) to update the integer scheduling
23198 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23199 INSN earlier, reduce the priority to execute INSN later. Do not
23200 define this macro if you do not need to adjust the scheduling
23201 priorities of insns. */
23204 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
23206 /* On machines (like the 750) which have asymmetric integer units,
23207 where one integer unit can do multiply and divides and the other
23208 can't, reduce the priority of multiply/divide so it is scheduled
23209 before other integer operations. */
23212 if (! INSN_P (insn
))
23215 if (GET_CODE (PATTERN (insn
)) == USE
)
23218 switch (rs6000_cpu_attr
) {
23220 switch (get_attr_type (insn
))
23227 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
23228 priority
, priority
);
23229 if (priority
>= 0 && priority
< 0x01000000)
23236 if (insn_must_be_first_in_group (insn
)
23237 && reload_completed
23238 && current_sched_info
->sched_max_insns_priority
23239 && rs6000_sched_restricted_insns_priority
)
23242 /* Prioritize insns that can be dispatched only in the first
23244 if (rs6000_sched_restricted_insns_priority
== 1)
23245 /* Attach highest priority to insn. This means that in
23246 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23247 precede 'priority' (critical path) considerations. */
23248 return current_sched_info
->sched_max_insns_priority
;
23249 else if (rs6000_sched_restricted_insns_priority
== 2)
23250 /* Increase priority of insn by a minimal amount. This means that in
23251 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23252 considerations precede dispatch-slot restriction considerations. */
23253 return (priority
+ 1);
23256 if (rs6000_cpu
== PROCESSOR_POWER6
23257 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
23258 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
23259 /* Attach highest priority to insn if the scheduler has just issued two
23260 stores and this instruction is a load, or two loads and this instruction
23261 is a store. Power6 wants loads and stores scheduled alternately
23263 return current_sched_info
->sched_max_insns_priority
;
23268 /* Return true if the instruction is nonpipelined on the Cell. */
23270 is_nonpipeline_insn (rtx insn
)
23272 enum attr_type type
;
23273 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23274 || GET_CODE (PATTERN (insn
)) == USE
23275 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23278 type
= get_attr_type (insn
);
23279 if (type
== TYPE_IMUL
23280 || type
== TYPE_IMUL2
23281 || type
== TYPE_IMUL3
23282 || type
== TYPE_LMUL
23283 || type
== TYPE_IDIV
23284 || type
== TYPE_LDIV
23285 || type
== TYPE_SDIV
23286 || type
== TYPE_DDIV
23287 || type
== TYPE_SSQRT
23288 || type
== TYPE_DSQRT
23289 || type
== TYPE_MFCR
23290 || type
== TYPE_MFCRF
23291 || type
== TYPE_MFJMPR
)
23299 /* Return how many instructions the machine can issue per cycle. */
23302 rs6000_issue_rate (void)
23304 /* Unless scheduling for register pressure, use issue rate of 1 for
23305 first scheduling pass to decrease degradation. */
23306 if (!reload_completed
&& !flag_sched_pressure
)
23309 switch (rs6000_cpu_attr
) {
23310 case CPU_RIOS1
: /* ? */
23312 case CPU_PPC601
: /* ? */
23321 case CPU_PPCE300C2
:
23322 case CPU_PPCE300C3
:
23323 case CPU_PPCE500MC
:
23324 case CPU_PPCE500MC64
:
23344 /* Return how many instructions to look ahead for better insn
23348 rs6000_use_sched_lookahead (void)
23350 if (rs6000_cpu_attr
== CPU_PPC8540
)
23352 if (rs6000_cpu_attr
== CPU_CELL
)
23353 return (reload_completed
? 8 : 0);
23357 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23359 rs6000_use_sched_lookahead_guard (rtx insn
)
23361 if (rs6000_cpu_attr
!= CPU_CELL
)
23364 if (insn
== NULL_RTX
|| !INSN_P (insn
))
23367 if (!reload_completed
23368 || is_nonpipeline_insn (insn
)
23369 || is_microcoded_insn (insn
))
23375 /* Determine is PAT refers to memory. */
23378 is_mem_ref (rtx pat
)
23384 /* stack_tie does not produce any real memory traffic. */
23385 if (GET_CODE (pat
) == UNSPEC
23386 && XINT (pat
, 1) == UNSPEC_TIE
)
23389 if (GET_CODE (pat
) == MEM
)
23392 /* Recursively process the pattern. */
23393 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
23395 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
23398 ret
|= is_mem_ref (XEXP (pat
, i
));
23399 else if (fmt
[i
] == 'E')
23400 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
23401 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
23407 /* Determine if PAT is a PATTERN of a load insn. */
23410 is_load_insn1 (rtx pat
)
23412 if (!pat
|| pat
== NULL_RTX
)
23415 if (GET_CODE (pat
) == SET
)
23416 return is_mem_ref (SET_SRC (pat
));
23418 if (GET_CODE (pat
) == PARALLEL
)
23422 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23423 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
23430 /* Determine if INSN loads from memory. */
23433 is_load_insn (rtx insn
)
23435 if (!insn
|| !INSN_P (insn
))
23438 if (GET_CODE (insn
) == CALL_INSN
)
23441 return is_load_insn1 (PATTERN (insn
));
23444 /* Determine if PAT is a PATTERN of a store insn. */
23447 is_store_insn1 (rtx pat
)
23449 if (!pat
|| pat
== NULL_RTX
)
23452 if (GET_CODE (pat
) == SET
)
23453 return is_mem_ref (SET_DEST (pat
));
23455 if (GET_CODE (pat
) == PARALLEL
)
23459 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23460 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
23467 /* Determine if INSN stores to memory. */
23470 is_store_insn (rtx insn
)
23472 if (!insn
|| !INSN_P (insn
))
23475 return is_store_insn1 (PATTERN (insn
));
23478 /* Return the dest of a store insn. */
23481 get_store_dest (rtx pat
)
23483 gcc_assert (is_store_insn1 (pat
));
23485 if (GET_CODE (pat
) == SET
)
23486 return SET_DEST (pat
);
23487 else if (GET_CODE (pat
) == PARALLEL
)
23491 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23493 rtx inner_pat
= XVECEXP (pat
, 0, i
);
23494 if (GET_CODE (inner_pat
) == SET
23495 && is_mem_ref (SET_DEST (inner_pat
)))
23499 /* We shouldn't get here, because we should have either a simple
23500 store insn or a store with update which are covered above. */
23504 /* Returns whether the dependence between INSN and NEXT is considered
23505 costly by the given target. */
23508 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
23513 /* If the flag is not enabled - no dependence is considered costly;
23514 allow all dependent insns in the same group.
23515 This is the most aggressive option. */
23516 if (rs6000_sched_costly_dep
== no_dep_costly
)
23519 /* If the flag is set to 1 - a dependence is always considered costly;
23520 do not allow dependent instructions in the same group.
23521 This is the most conservative option. */
23522 if (rs6000_sched_costly_dep
== all_deps_costly
)
23525 insn
= DEP_PRO (dep
);
23526 next
= DEP_CON (dep
);
23528 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
23529 && is_load_insn (next
)
23530 && is_store_insn (insn
))
23531 /* Prevent load after store in the same group. */
23534 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
23535 && is_load_insn (next
)
23536 && is_store_insn (insn
)
23537 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
23538 /* Prevent load after store in the same group if it is a true
23542 /* The flag is set to X; dependences with latency >= X are considered costly,
23543 and will not be scheduled in the same group. */
23544 if (rs6000_sched_costly_dep
<= max_dep_latency
23545 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
23551 /* Return the next insn after INSN that is found before TAIL is reached,
23552 skipping any "non-active" insns - insns that will not actually occupy
23553 an issue slot. Return NULL_RTX if such an insn is not found. */
23556 get_next_active_insn (rtx insn
, rtx tail
)
23558 if (insn
== NULL_RTX
|| insn
== tail
)
23563 insn
= NEXT_INSN (insn
);
23564 if (insn
== NULL_RTX
|| insn
== tail
)
23569 || (NONJUMP_INSN_P (insn
)
23570 && GET_CODE (PATTERN (insn
)) != USE
23571 && GET_CODE (PATTERN (insn
)) != CLOBBER
23572 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
23578 /* We are about to begin issuing insns for this clock cycle. */
23581 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
23582 rtx
*ready ATTRIBUTE_UNUSED
,
23583 int *pn_ready ATTRIBUTE_UNUSED
,
23584 int clock_var ATTRIBUTE_UNUSED
)
23586 int n_ready
= *pn_ready
;
23589 fprintf (dump
, "// rs6000_sched_reorder :\n");
23591 /* Reorder the ready list, if the second to last ready insn
23592 is a nonepipeline insn. */
23593 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
23595 if (is_nonpipeline_insn (ready
[n_ready
- 1])
23596 && (recog_memoized (ready
[n_ready
- 2]) > 0))
23597 /* Simply swap first two insns. */
23599 rtx tmp
= ready
[n_ready
- 1];
23600 ready
[n_ready
- 1] = ready
[n_ready
- 2];
23601 ready
[n_ready
- 2] = tmp
;
23605 if (rs6000_cpu
== PROCESSOR_POWER6
)
23606 load_store_pendulum
= 0;
23608 return rs6000_issue_rate ();
23611 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23614 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
23615 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
23618 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
23620 /* For Power6, we need to handle some special cases to try and keep the
23621 store queue from overflowing and triggering expensive flushes.
23623 This code monitors how load and store instructions are being issued
23624 and skews the ready list one way or the other to increase the likelihood
23625 that a desired instruction is issued at the proper time.
23627 A couple of things are done. First, we maintain a "load_store_pendulum"
23628 to track the current state of load/store issue.
23630 - If the pendulum is at zero, then no loads or stores have been
23631 issued in the current cycle so we do nothing.
23633 - If the pendulum is 1, then a single load has been issued in this
23634 cycle and we attempt to locate another load in the ready list to
23637 - If the pendulum is -2, then two stores have already been
23638 issued in this cycle, so we increase the priority of the first load
23639 in the ready list to increase it's likelihood of being chosen first
23642 - If the pendulum is -1, then a single store has been issued in this
23643 cycle and we attempt to locate another store in the ready list to
23644 issue with it, preferring a store to an adjacent memory location to
23645 facilitate store pairing in the store queue.
23647 - If the pendulum is 2, then two loads have already been
23648 issued in this cycle, so we increase the priority of the first store
23649 in the ready list to increase it's likelihood of being chosen first
23652 - If the pendulum < -2 or > 2, then do nothing.
23654 Note: This code covers the most common scenarios. There exist non
23655 load/store instructions which make use of the LSU and which
23656 would need to be accounted for to strictly model the behavior
23657 of the machine. Those instructions are currently unaccounted
23658 for to help minimize compile time overhead of this code.
23660 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
23666 if (is_store_insn (last_scheduled_insn
))
23667 /* Issuing a store, swing the load_store_pendulum to the left */
23668 load_store_pendulum
--;
23669 else if (is_load_insn (last_scheduled_insn
))
23670 /* Issuing a load, swing the load_store_pendulum to the right */
23671 load_store_pendulum
++;
23673 return cached_can_issue_more
;
23675 /* If the pendulum is balanced, or there is only one instruction on
23676 the ready list, then all is well, so return. */
23677 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
23678 return cached_can_issue_more
;
23680 if (load_store_pendulum
== 1)
23682 /* A load has been issued in this cycle. Scan the ready list
23683 for another load to issue with it */
23688 if (is_load_insn (ready
[pos
]))
23690 /* Found a load. Move it to the head of the ready list,
23691 and adjust it's priority so that it is more likely to
23694 for (i
=pos
; i
<*pn_ready
-1; i
++)
23695 ready
[i
] = ready
[i
+ 1];
23696 ready
[*pn_ready
-1] = tmp
;
23698 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23699 INSN_PRIORITY (tmp
)++;
23705 else if (load_store_pendulum
== -2)
23707 /* Two stores have been issued in this cycle. Increase the
23708 priority of the first load in the ready list to favor it for
23709 issuing in the next cycle. */
23714 if (is_load_insn (ready
[pos
])
23716 && INSN_PRIORITY_KNOWN (ready
[pos
]))
23718 INSN_PRIORITY (ready
[pos
])++;
23720 /* Adjust the pendulum to account for the fact that a load
23721 was found and increased in priority. This is to prevent
23722 increasing the priority of multiple loads */
23723 load_store_pendulum
--;
23730 else if (load_store_pendulum
== -1)
23732 /* A store has been issued in this cycle. Scan the ready list for
23733 another store to issue with it, preferring a store to an adjacent
23735 int first_store_pos
= -1;
23741 if (is_store_insn (ready
[pos
]))
23743 /* Maintain the index of the first store found on the
23745 if (first_store_pos
== -1)
23746 first_store_pos
= pos
;
23748 if (is_store_insn (last_scheduled_insn
)
23749 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
23751 /* Found an adjacent store. Move it to the head of the
23752 ready list, and adjust it's priority so that it is
23753 more likely to stay there */
23755 for (i
=pos
; i
<*pn_ready
-1; i
++)
23756 ready
[i
] = ready
[i
+ 1];
23757 ready
[*pn_ready
-1] = tmp
;
23759 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23760 INSN_PRIORITY (tmp
)++;
23762 first_store_pos
= -1;
23770 if (first_store_pos
>= 0)
23772 /* An adjacent store wasn't found, but a non-adjacent store was,
23773 so move the non-adjacent store to the front of the ready
23774 list, and adjust its priority so that it is more likely to
23776 tmp
= ready
[first_store_pos
];
23777 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
23778 ready
[i
] = ready
[i
+ 1];
23779 ready
[*pn_ready
-1] = tmp
;
23780 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23781 INSN_PRIORITY (tmp
)++;
23784 else if (load_store_pendulum
== 2)
23786 /* Two loads have been issued in this cycle. Increase the priority
23787 of the first store in the ready list to favor it for issuing in
23793 if (is_store_insn (ready
[pos
])
23795 && INSN_PRIORITY_KNOWN (ready
[pos
]))
23797 INSN_PRIORITY (ready
[pos
])++;
23799 /* Adjust the pendulum to account for the fact that a store
23800 was found and increased in priority. This is to prevent
23801 increasing the priority of multiple stores */
23802 load_store_pendulum
++;
23811 return cached_can_issue_more
;
23814 /* Return whether the presence of INSN causes a dispatch group termination
23815 of group WHICH_GROUP.
23817 If WHICH_GROUP == current_group, this function will return true if INSN
23818 causes the termination of the current group (i.e, the dispatch group to
23819 which INSN belongs). This means that INSN will be the last insn in the
23820 group it belongs to.
23822 If WHICH_GROUP == previous_group, this function will return true if INSN
23823 causes the termination of the previous group (i.e, the dispatch group that
23824 precedes the group to which INSN belongs). This means that INSN will be
23825 the first insn in the group it belongs to). */
23828 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
23835 first
= insn_must_be_first_in_group (insn
);
23836 last
= insn_must_be_last_in_group (insn
);
23841 if (which_group
== current_group
)
23843 else if (which_group
== previous_group
)
23851 insn_must_be_first_in_group (rtx insn
)
23853 enum attr_type type
;
23856 || GET_CODE (insn
) == NOTE
23857 || DEBUG_INSN_P (insn
)
23858 || GET_CODE (PATTERN (insn
)) == USE
23859 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23862 switch (rs6000_cpu
)
23864 case PROCESSOR_POWER5
:
23865 if (is_cracked_insn (insn
))
23867 case PROCESSOR_POWER4
:
23868 if (is_microcoded_insn (insn
))
23871 if (!rs6000_sched_groups
)
23874 type
= get_attr_type (insn
);
23881 case TYPE_DELAYED_CR
:
23882 case TYPE_CR_LOGICAL
:
23896 case PROCESSOR_POWER6
:
23897 type
= get_attr_type (insn
);
23901 case TYPE_INSERT_DWORD
:
23905 case TYPE_VAR_SHIFT_ROTATE
:
23912 case TYPE_INSERT_WORD
:
23913 case TYPE_DELAYED_COMPARE
:
23914 case TYPE_IMUL_COMPARE
:
23915 case TYPE_LMUL_COMPARE
:
23916 case TYPE_FPCOMPARE
:
23927 case TYPE_LOAD_EXT_UX
:
23929 case TYPE_STORE_UX
:
23930 case TYPE_FPLOAD_U
:
23931 case TYPE_FPLOAD_UX
:
23932 case TYPE_FPSTORE_U
:
23933 case TYPE_FPSTORE_UX
:
23939 case PROCESSOR_POWER7
:
23940 type
= get_attr_type (insn
);
23944 case TYPE_CR_LOGICAL
:
23951 case TYPE_DELAYED_COMPARE
:
23952 case TYPE_VAR_DELAYED_COMPARE
:
23958 case TYPE_LOAD_EXT
:
23959 case TYPE_LOAD_EXT_U
:
23960 case TYPE_LOAD_EXT_UX
:
23962 case TYPE_STORE_UX
:
23963 case TYPE_FPLOAD_U
:
23964 case TYPE_FPLOAD_UX
:
23965 case TYPE_FPSTORE_U
:
23966 case TYPE_FPSTORE_UX
:
23982 insn_must_be_last_in_group (rtx insn
)
23984 enum attr_type type
;
23987 || GET_CODE (insn
) == NOTE
23988 || DEBUG_INSN_P (insn
)
23989 || GET_CODE (PATTERN (insn
)) == USE
23990 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23993 switch (rs6000_cpu
) {
23994 case PROCESSOR_POWER4
:
23995 case PROCESSOR_POWER5
:
23996 if (is_microcoded_insn (insn
))
23999 if (is_branch_slot_insn (insn
))
24003 case PROCESSOR_POWER6
:
24004 type
= get_attr_type (insn
);
24011 case TYPE_VAR_SHIFT_ROTATE
:
24018 case TYPE_DELAYED_COMPARE
:
24019 case TYPE_IMUL_COMPARE
:
24020 case TYPE_LMUL_COMPARE
:
24021 case TYPE_FPCOMPARE
:
24035 case PROCESSOR_POWER7
:
24036 type
= get_attr_type (insn
);
24044 case TYPE_LOAD_EXT_U
:
24045 case TYPE_LOAD_EXT_UX
:
24046 case TYPE_STORE_UX
:
24059 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24060 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24063 is_costly_group (rtx
*group_insns
, rtx next_insn
)
24066 int issue_rate
= rs6000_issue_rate ();
24068 for (i
= 0; i
< issue_rate
; i
++)
24070 sd_iterator_def sd_it
;
24072 rtx insn
= group_insns
[i
];
24077 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
24079 rtx next
= DEP_CON (dep
);
24081 if (next
== next_insn
24082 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
24090 /* Utility of the function redefine_groups.
24091 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24092 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24093 to keep it "far" (in a separate group) from GROUP_INSNS, following
24094 one of the following schemes, depending on the value of the flag
24095 -minsert_sched_nops = X:
24096 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24097 in order to force NEXT_INSN into a separate group.
24098 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24099 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24100 insertion (has a group just ended, how many vacant issue slots remain in the
24101 last group, and how many dispatch groups were encountered so far). */
24104 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
24105 rtx next_insn
, bool *group_end
, int can_issue_more
,
24110 int issue_rate
= rs6000_issue_rate ();
24111 bool end
= *group_end
;
24114 if (next_insn
== NULL_RTX
|| DEBUG_INSN_P (next_insn
))
24115 return can_issue_more
;
24117 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
24118 return can_issue_more
;
24120 force
= is_costly_group (group_insns
, next_insn
);
24122 return can_issue_more
;
24124 if (sched_verbose
> 6)
24125 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
24126 *group_count
,can_issue_more
);
24128 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
24131 can_issue_more
= 0;
24133 /* Since only a branch can be issued in the last issue_slot, it is
24134 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24135 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24136 in this case the last nop will start a new group and the branch
24137 will be forced to the new group. */
24138 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
24141 while (can_issue_more
> 0)
24144 emit_insn_before (nop
, next_insn
);
24152 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
24154 int n_nops
= rs6000_sched_insert_nops
;
24156 /* Nops can't be issued from the branch slot, so the effective
24157 issue_rate for nops is 'issue_rate - 1'. */
24158 if (can_issue_more
== 0)
24159 can_issue_more
= issue_rate
;
24161 if (can_issue_more
== 0)
24163 can_issue_more
= issue_rate
- 1;
24166 for (i
= 0; i
< issue_rate
; i
++)
24168 group_insns
[i
] = 0;
24175 emit_insn_before (nop
, next_insn
);
24176 if (can_issue_more
== issue_rate
- 1) /* new group begins */
24179 if (can_issue_more
== 0)
24181 can_issue_more
= issue_rate
- 1;
24184 for (i
= 0; i
< issue_rate
; i
++)
24186 group_insns
[i
] = 0;
24192 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24195 /* Is next_insn going to start a new group? */
24198 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24199 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24200 || (can_issue_more
< issue_rate
&&
24201 insn_terminates_group_p (next_insn
, previous_group
)));
24202 if (*group_end
&& end
)
24205 if (sched_verbose
> 6)
24206 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
24207 *group_count
, can_issue_more
);
24208 return can_issue_more
;
24211 return can_issue_more
;
24214 /* This function tries to synch the dispatch groups that the compiler "sees"
24215 with the dispatch groups that the processor dispatcher is expected to
24216 form in practice. It tries to achieve this synchronization by forcing the
24217 estimated processor grouping on the compiler (as opposed to the function
24218 'pad_goups' which tries to force the scheduler's grouping on the processor).
24220 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24221 examines the (estimated) dispatch groups that will be formed by the processor
24222 dispatcher. It marks these group boundaries to reflect the estimated
24223 processor grouping, overriding the grouping that the scheduler had marked.
24224 Depending on the value of the flag '-minsert-sched-nops' this function can
24225 force certain insns into separate groups or force a certain distance between
24226 them by inserting nops, for example, if there exists a "costly dependence"
24229 The function estimates the group boundaries that the processor will form as
24230 follows: It keeps track of how many vacant issue slots are available after
24231 each insn. A subsequent insn will start a new group if one of the following
24233 - no more vacant issue slots remain in the current dispatch group.
24234 - only the last issue slot, which is the branch slot, is vacant, but the next
24235 insn is not a branch.
24236 - only the last 2 or less issue slots, including the branch slot, are vacant,
24237 which means that a cracked insn (which occupies two issue slots) can't be
24238 issued in this group.
24239 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24240 start a new group. */
24243 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24245 rtx insn
, next_insn
;
24247 int can_issue_more
;
24250 int group_count
= 0;
24254 issue_rate
= rs6000_issue_rate ();
24255 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
24256 for (i
= 0; i
< issue_rate
; i
++)
24258 group_insns
[i
] = 0;
24260 can_issue_more
= issue_rate
;
24262 insn
= get_next_active_insn (prev_head_insn
, tail
);
24265 while (insn
!= NULL_RTX
)
24267 slot
= (issue_rate
- can_issue_more
);
24268 group_insns
[slot
] = insn
;
24270 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24271 if (insn_terminates_group_p (insn
, current_group
))
24272 can_issue_more
= 0;
24274 next_insn
= get_next_active_insn (insn
, tail
);
24275 if (next_insn
== NULL_RTX
)
24276 return group_count
+ 1;
24278 /* Is next_insn going to start a new group? */
24280 = (can_issue_more
== 0
24281 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24282 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24283 || (can_issue_more
< issue_rate
&&
24284 insn_terminates_group_p (next_insn
, previous_group
)));
24286 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
24287 next_insn
, &group_end
, can_issue_more
,
24293 can_issue_more
= 0;
24294 for (i
= 0; i
< issue_rate
; i
++)
24296 group_insns
[i
] = 0;
24300 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
24301 PUT_MODE (next_insn
, VOIDmode
);
24302 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
24303 PUT_MODE (next_insn
, TImode
);
24306 if (can_issue_more
== 0)
24307 can_issue_more
= issue_rate
;
24310 return group_count
;
24313 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24314 dispatch group boundaries that the scheduler had marked. Pad with nops
24315 any dispatch groups which have vacant issue slots, in order to force the
24316 scheduler's grouping on the processor dispatcher. The function
24317 returns the number of dispatch groups found. */
24320 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24322 rtx insn
, next_insn
;
24325 int can_issue_more
;
24327 int group_count
= 0;
24329 /* Initialize issue_rate. */
24330 issue_rate
= rs6000_issue_rate ();
24331 can_issue_more
= issue_rate
;
24333 insn
= get_next_active_insn (prev_head_insn
, tail
);
24334 next_insn
= get_next_active_insn (insn
, tail
);
24336 while (insn
!= NULL_RTX
)
24339 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24341 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
24343 if (next_insn
== NULL_RTX
)
24348 /* If the scheduler had marked group termination at this location
24349 (between insn and next_insn), and neither insn nor next_insn will
24350 force group termination, pad the group with nops to force group
24353 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24354 && !insn_terminates_group_p (insn
, current_group
)
24355 && !insn_terminates_group_p (next_insn
, previous_group
))
24357 if (!is_branch_slot_insn (next_insn
))
24360 while (can_issue_more
)
24363 emit_insn_before (nop
, next_insn
);
24368 can_issue_more
= issue_rate
;
24373 next_insn
= get_next_active_insn (insn
, tail
);
24376 return group_count
;
24379 /* We're beginning a new block. Initialize data structures as necessary. */
24382 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
24383 int sched_verbose ATTRIBUTE_UNUSED
,
24384 int max_ready ATTRIBUTE_UNUSED
)
24386 last_scheduled_insn
= NULL_RTX
;
24387 load_store_pendulum
= 0;
24390 /* The following function is called at the end of scheduling BB.
24391 After reload, it inserts nops at insn group bundling. */
24394 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
24399 fprintf (dump
, "=== Finishing schedule.\n");
24401 if (reload_completed
&& rs6000_sched_groups
)
24403 /* Do not run sched_finish hook when selective scheduling enabled. */
24404 if (sel_sched_p ())
24407 if (rs6000_sched_insert_nops
== sched_finish_none
)
24410 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24411 n_groups
= pad_groups (dump
, sched_verbose
,
24412 current_sched_info
->prev_head
,
24413 current_sched_info
->next_tail
);
24415 n_groups
= redefine_groups (dump
, sched_verbose
,
24416 current_sched_info
->prev_head
,
24417 current_sched_info
->next_tail
);
24419 if (sched_verbose
>= 6)
24421 fprintf (dump
, "ngroups = %d\n", n_groups
);
24422 print_rtl (dump
, current_sched_info
->prev_head
);
24423 fprintf (dump
, "Done finish_sched\n");
24428 struct _rs6000_sched_context
24430 short cached_can_issue_more
;
24431 rtx last_scheduled_insn
;
24432 int load_store_pendulum
;
24435 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
24436 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
24438 /* Allocate store for new scheduling context. */
24440 rs6000_alloc_sched_context (void)
24442 return xmalloc (sizeof (rs6000_sched_context_def
));
24445 /* If CLEAN_P is true then initializes _SC with clean data,
24446 and from the global context otherwise. */
24448 rs6000_init_sched_context (void *_sc
, bool clean_p
)
24450 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24454 sc
->cached_can_issue_more
= 0;
24455 sc
->last_scheduled_insn
= NULL_RTX
;
24456 sc
->load_store_pendulum
= 0;
24460 sc
->cached_can_issue_more
= cached_can_issue_more
;
24461 sc
->last_scheduled_insn
= last_scheduled_insn
;
24462 sc
->load_store_pendulum
= load_store_pendulum
;
24466 /* Sets the global scheduling context to the one pointed to by _SC. */
24468 rs6000_set_sched_context (void *_sc
)
24470 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24472 gcc_assert (sc
!= NULL
);
24474 cached_can_issue_more
= sc
->cached_can_issue_more
;
24475 last_scheduled_insn
= sc
->last_scheduled_insn
;
24476 load_store_pendulum
= sc
->load_store_pendulum
;
24481 rs6000_free_sched_context (void *_sc
)
24483 gcc_assert (_sc
!= NULL
);
24489 /* Length in units of the trampoline for entering a nested function. */
24492 rs6000_trampoline_size (void)
24496 switch (DEFAULT_ABI
)
24499 gcc_unreachable ();
24502 ret
= (TARGET_32BIT
) ? 12 : 24;
24507 ret
= (TARGET_32BIT
) ? 40 : 48;
24514 /* Emit RTL insns to initialize the variable parts of a trampoline.
24515 FNADDR is an RTX for the address of the function's pure code.
24516 CXT is an RTX for the static chain value for the function. */
24519 rs6000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
24521 int regsize
= (TARGET_32BIT
) ? 4 : 8;
24522 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
24523 rtx ctx_reg
= force_reg (Pmode
, cxt
);
24524 rtx addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
24526 switch (DEFAULT_ABI
)
24529 gcc_unreachable ();
24531 /* Under AIX, just build the 3 word function descriptor */
24534 rtx fnmem
, fn_reg
, toc_reg
;
24536 if (!TARGET_POINTERS_TO_NESTED_FUNCTIONS
)
24537 error ("-mno-r11 must not be used if you have trampolines");
24539 fnmem
= gen_const_mem (Pmode
, force_reg (Pmode
, fnaddr
));
24540 fn_reg
= gen_reg_rtx (Pmode
);
24541 toc_reg
= gen_reg_rtx (Pmode
);
24543 /* Macro to shorten the code expansions below. */
24544 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24546 m_tramp
= replace_equiv_address (m_tramp
, addr
);
24548 emit_move_insn (fn_reg
, MEM_PLUS (fnmem
, 0));
24549 emit_move_insn (toc_reg
, MEM_PLUS (fnmem
, regsize
));
24550 emit_move_insn (MEM_PLUS (m_tramp
, 0), fn_reg
);
24551 emit_move_insn (MEM_PLUS (m_tramp
, regsize
), toc_reg
);
24552 emit_move_insn (MEM_PLUS (m_tramp
, 2*regsize
), ctx_reg
);
24558 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24561 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
24562 LCT_NORMAL
, VOIDmode
, 4,
24564 GEN_INT (rs6000_trampoline_size ()), SImode
,
24572 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24573 identifier as an argument, so the front end shouldn't look it up. */
24576 rs6000_attribute_takes_identifier_p (const_tree attr_id
)
24578 return is_attribute_p ("altivec", attr_id
);
24581 /* Handle the "altivec" attribute. The attribute may have
24582 arguments as follows:
24584 __attribute__((altivec(vector__)))
24585 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24586 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24588 and may appear more than once (e.g., 'vector bool char') in a
24589 given declaration. */
24592 rs6000_handle_altivec_attribute (tree
*node
,
24593 tree name ATTRIBUTE_UNUSED
,
24595 int flags ATTRIBUTE_UNUSED
,
24596 bool *no_add_attrs
)
24598 tree type
= *node
, result
= NULL_TREE
;
24599 enum machine_mode mode
;
24602 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
24603 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
24604 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
24607 while (POINTER_TYPE_P (type
)
24608 || TREE_CODE (type
) == FUNCTION_TYPE
24609 || TREE_CODE (type
) == METHOD_TYPE
24610 || TREE_CODE (type
) == ARRAY_TYPE
)
24611 type
= TREE_TYPE (type
);
24613 mode
= TYPE_MODE (type
);
24615 /* Check for invalid AltiVec type qualifiers. */
24616 if (type
== long_double_type_node
)
24617 error ("use of %<long double%> in AltiVec types is invalid");
24618 else if (type
== boolean_type_node
)
24619 error ("use of boolean types in AltiVec types is invalid");
24620 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
24621 error ("use of %<complex%> in AltiVec types is invalid");
24622 else if (DECIMAL_FLOAT_MODE_P (mode
))
24623 error ("use of decimal floating point types in AltiVec types is invalid");
24624 else if (!TARGET_VSX
)
24626 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
24629 error ("use of %<long%> in AltiVec types is invalid for "
24630 "64-bit code without -mvsx");
24631 else if (rs6000_warn_altivec_long
)
24632 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24635 else if (type
== long_long_unsigned_type_node
24636 || type
== long_long_integer_type_node
)
24637 error ("use of %<long long%> in AltiVec types is invalid without "
24639 else if (type
== double_type_node
)
24640 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24643 switch (altivec_type
)
24646 unsigned_p
= TYPE_UNSIGNED (type
);
24650 result
= (unsigned_p
? unsigned_V2DI_type_node
: V2DI_type_node
);
24653 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
24656 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
24659 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
24661 case SFmode
: result
= V4SF_type_node
; break;
24662 case DFmode
: result
= V2DF_type_node
; break;
24663 /* If the user says 'vector int bool', we may be handed the 'bool'
24664 attribute _before_ the 'vector' attribute, and so select the
24665 proper type in the 'b' case below. */
24666 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
24667 case V2DImode
: case V2DFmode
:
24675 case DImode
: case V2DImode
: result
= bool_V2DI_type_node
; break;
24676 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
24677 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
24678 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
24685 case V8HImode
: result
= pixel_V8HI_type_node
;
24691 /* Propagate qualifiers attached to the element type
24692 onto the vector type. */
24693 if (result
&& result
!= type
&& TYPE_QUALS (type
))
24694 result
= build_qualified_type (result
, TYPE_QUALS (type
));
24696 *no_add_attrs
= true; /* No need to hang on to the attribute. */
24699 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
24704 /* AltiVec defines four built-in scalar types that serve as vector
24705 elements; we must teach the compiler how to mangle them. */
24707 static const char *
24708 rs6000_mangle_type (const_tree type
)
24710 type
= TYPE_MAIN_VARIANT (type
);
24712 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
24713 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
24716 if (type
== bool_char_type_node
) return "U6__boolc";
24717 if (type
== bool_short_type_node
) return "U6__bools";
24718 if (type
== pixel_type_node
) return "u7__pixel";
24719 if (type
== bool_int_type_node
) return "U6__booli";
24720 if (type
== bool_long_type_node
) return "U6__booll";
24722 /* Mangle IBM extended float long double as `g' (__float128) on
24723 powerpc*-linux where long-double-64 previously was the default. */
24724 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
24726 && TARGET_LONG_DOUBLE_128
24727 && !TARGET_IEEEQUAD
)
24730 /* For all other types, use normal C++ mangling. */
24734 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24735 struct attribute_spec.handler. */
24738 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
24739 tree args ATTRIBUTE_UNUSED
,
24740 int flags ATTRIBUTE_UNUSED
,
24741 bool *no_add_attrs
)
24743 if (TREE_CODE (*node
) != FUNCTION_TYPE
24744 && TREE_CODE (*node
) != FIELD_DECL
24745 && TREE_CODE (*node
) != TYPE_DECL
)
24747 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
24749 *no_add_attrs
= true;
24755 /* Set longcall attributes on all functions declared when
24756 rs6000_default_long_calls is true. */
24758 rs6000_set_default_type_attributes (tree type
)
24760 if (rs6000_default_long_calls
24761 && (TREE_CODE (type
) == FUNCTION_TYPE
24762 || TREE_CODE (type
) == METHOD_TYPE
))
24763 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
24765 TYPE_ATTRIBUTES (type
));
24768 darwin_set_default_type_attributes (type
);
24772 /* Return a reference suitable for calling a function with the
24773 longcall attribute. */
24776 rs6000_longcall_ref (rtx call_ref
)
24778 const char *call_name
;
24781 if (GET_CODE (call_ref
) != SYMBOL_REF
)
24784 /* System V adds '.' to the internal name, so skip them. */
24785 call_name
= XSTR (call_ref
, 0);
24786 if (*call_name
== '.')
24788 while (*call_name
== '.')
24791 node
= get_identifier (call_name
);
24792 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
24795 return force_reg (Pmode
, call_ref
);
24798 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24799 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24802 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24803 struct attribute_spec.handler. */
24805 rs6000_handle_struct_attribute (tree
*node
, tree name
,
24806 tree args ATTRIBUTE_UNUSED
,
24807 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
24810 if (DECL_P (*node
))
24812 if (TREE_CODE (*node
) == TYPE_DECL
)
24813 type
= &TREE_TYPE (*node
);
24818 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
24819 || TREE_CODE (*type
) == UNION_TYPE
)))
24821 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
24822 *no_add_attrs
= true;
24825 else if ((is_attribute_p ("ms_struct", name
)
24826 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
24827 || ((is_attribute_p ("gcc_struct", name
)
24828 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
24830 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
24832 *no_add_attrs
= true;
24839 rs6000_ms_bitfield_layout_p (const_tree record_type
)
24841 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
24842 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
24843 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
24846 #ifdef USING_ELFOS_H
24848 /* A get_unnamed_section callback, used for switching to toc_section. */
24851 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
24853 if (DEFAULT_ABI
== ABI_AIX
24854 && TARGET_MINIMAL_TOC
24855 && !TARGET_RELOCATABLE
)
24857 if (!toc_initialized
)
24859 toc_initialized
= 1;
24860 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
24861 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
24862 fprintf (asm_out_file
, "\t.tc ");
24863 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
24864 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24865 fprintf (asm_out_file
, "\n");
24867 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24868 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24869 fprintf (asm_out_file
, " = .+32768\n");
24872 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24874 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
24875 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
24878 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24879 if (!toc_initialized
)
24881 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24882 fprintf (asm_out_file
, " = .+32768\n");
24883 toc_initialized
= 1;
24888 /* Implement TARGET_ASM_INIT_SECTIONS. */
24891 rs6000_elf_asm_init_sections (void)
24894 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
24897 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
24898 SDATA2_SECTION_ASM_OP
);
24901 /* Implement TARGET_SELECT_RTX_SECTION. */
24904 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
24905 unsigned HOST_WIDE_INT align
)
24907 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
24908 return toc_section
;
24910 return default_elf_select_rtx_section (mode
, x
, align
);
24913 /* For a SYMBOL_REF, set generic flags and then perform some
24914 target-specific processing.
24916 When the AIX ABI is requested on a non-AIX system, replace the
24917 function name with the real name (with a leading .) rather than the
24918 function descriptor name. This saves a lot of overriding code to
24919 read the prefixes. */
24922 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
24924 default_encode_section_info (decl
, rtl
, first
);
24927 && TREE_CODE (decl
) == FUNCTION_DECL
24929 && DEFAULT_ABI
== ABI_AIX
)
24931 rtx sym_ref
= XEXP (rtl
, 0);
24932 size_t len
= strlen (XSTR (sym_ref
, 0));
24933 char *str
= XALLOCAVEC (char, len
+ 2);
24935 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
24936 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
24941 compare_section_name (const char *section
, const char *templ
)
24945 len
= strlen (templ
);
24946 return (strncmp (section
, templ
, len
) == 0
24947 && (section
[len
] == 0 || section
[len
] == '.'));
24951 rs6000_elf_in_small_data_p (const_tree decl
)
24953 if (rs6000_sdata
== SDATA_NONE
)
24956 /* We want to merge strings, so we never consider them small data. */
24957 if (TREE_CODE (decl
) == STRING_CST
)
24960 /* Functions are never in the small data area. */
24961 if (TREE_CODE (decl
) == FUNCTION_DECL
)
24964 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
24966 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
24967 if (compare_section_name (section
, ".sdata")
24968 || compare_section_name (section
, ".sdata2")
24969 || compare_section_name (section
, ".gnu.linkonce.s")
24970 || compare_section_name (section
, ".sbss")
24971 || compare_section_name (section
, ".sbss2")
24972 || compare_section_name (section
, ".gnu.linkonce.sb")
24973 || strcmp (section
, ".PPC.EMB.sdata0") == 0
24974 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
24979 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
24982 && size
<= g_switch_value
24983 /* If it's not public, and we're not going to reference it there,
24984 there's no need to put it in the small data section. */
24985 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
24992 #endif /* USING_ELFOS_H */
24994 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24997 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
24999 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
25002 /* Return a REG that occurs in ADDR with coefficient 1.
25003 ADDR can be effectively incremented by incrementing REG.
25005 r0 is special and we must not select it as an address
25006 register by this routine since our caller will try to
25007 increment the returned register via an "la" instruction. */
25010 find_addr_reg (rtx addr
)
25012 while (GET_CODE (addr
) == PLUS
)
25014 if (GET_CODE (XEXP (addr
, 0)) == REG
25015 && REGNO (XEXP (addr
, 0)) != 0)
25016 addr
= XEXP (addr
, 0);
25017 else if (GET_CODE (XEXP (addr
, 1)) == REG
25018 && REGNO (XEXP (addr
, 1)) != 0)
25019 addr
= XEXP (addr
, 1);
25020 else if (CONSTANT_P (XEXP (addr
, 0)))
25021 addr
= XEXP (addr
, 1);
25022 else if (CONSTANT_P (XEXP (addr
, 1)))
25023 addr
= XEXP (addr
, 0);
25025 gcc_unreachable ();
25027 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
25032 rs6000_fatal_bad_address (rtx op
)
25034 fatal_insn ("bad address", op
);
25039 typedef struct branch_island_d
{
25040 tree function_name
;
25045 DEF_VEC_O(branch_island
);
25046 DEF_VEC_ALLOC_O(branch_island
,gc
);
25048 static VEC(branch_island
,gc
) *branch_islands
;
25050 /* Remember to generate a branch island for far calls to the given
25054 add_compiler_branch_island (tree label_name
, tree function_name
,
25057 branch_island
*bi
= VEC_safe_push (branch_island
, gc
, branch_islands
, NULL
);
25059 bi
->function_name
= function_name
;
25060 bi
->label_name
= label_name
;
25061 bi
->line_number
= line_number
;
25064 /* Generate far-jump branch islands for everything recorded in
25065 branch_islands. Invoked immediately after the last instruction of
25066 the epilogue has been emitted; the branch islands must be appended
25067 to, and contiguous with, the function body. Mach-O stubs are
25068 generated in machopic_output_stub(). */
25071 macho_branch_islands (void)
25075 while (!VEC_empty (branch_island
, branch_islands
))
25077 branch_island
*bi
= VEC_last (branch_island
, branch_islands
);
25078 const char *label
= IDENTIFIER_POINTER (bi
->label_name
);
25079 const char *name
= IDENTIFIER_POINTER (bi
->function_name
);
25080 char name_buf
[512];
25081 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25082 if (name
[0] == '*' || name
[0] == '&')
25083 strcpy (name_buf
, name
+1);
25087 strcpy (name_buf
+1, name
);
25089 strcpy (tmp_buf
, "\n");
25090 strcat (tmp_buf
, label
);
25091 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25092 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25093 dbxout_stabd (N_SLINE
, bi
->line_number
);
25094 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25097 if (TARGET_LINK_STACK
)
25100 get_ppc476_thunk_name (name
);
25101 strcat (tmp_buf
, ":\n\tmflr r0\n\tbl ");
25102 strcat (tmp_buf
, name
);
25103 strcat (tmp_buf
, "\n");
25104 strcat (tmp_buf
, label
);
25105 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
25109 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
25110 strcat (tmp_buf
, label
);
25111 strcat (tmp_buf
, "_pic\n");
25112 strcat (tmp_buf
, label
);
25113 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
25116 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
25117 strcat (tmp_buf
, name_buf
);
25118 strcat (tmp_buf
, " - ");
25119 strcat (tmp_buf
, label
);
25120 strcat (tmp_buf
, "_pic)\n");
25122 strcat (tmp_buf
, "\tmtlr r0\n");
25124 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
25125 strcat (tmp_buf
, name_buf
);
25126 strcat (tmp_buf
, " - ");
25127 strcat (tmp_buf
, label
);
25128 strcat (tmp_buf
, "_pic)\n");
25130 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
25134 strcat (tmp_buf
, ":\nlis r12,hi16(");
25135 strcat (tmp_buf
, name_buf
);
25136 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
25137 strcat (tmp_buf
, name_buf
);
25138 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
25140 output_asm_insn (tmp_buf
, 0);
25141 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25142 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25143 dbxout_stabd (N_SLINE
, bi
->line_number
);
25144 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25145 VEC_pop (branch_island
, branch_islands
);
25149 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25150 already there or not. */
25153 no_previous_def (tree function_name
)
25158 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25159 if (function_name
== bi
->function_name
)
25164 /* GET_PREV_LABEL gets the label name from the previous definition of
25168 get_prev_label (tree function_name
)
25173 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25174 if (function_name
== bi
->function_name
)
25175 return bi
->label_name
;
25179 /* INSN is either a function call or a millicode call. It may have an
25180 unconditional jump in its delay slot.
25182 CALL_DEST is the routine we are calling. */
25185 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
25186 int cookie_operand_number
)
25188 static char buf
[256];
25189 if (darwin_emit_branch_islands
25190 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
25191 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
25194 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
25196 if (no_previous_def (funname
))
25198 rtx label_rtx
= gen_label_rtx ();
25199 char *label_buf
, temp_buf
[256];
25200 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
25201 CODE_LABEL_NUMBER (label_rtx
));
25202 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
25203 labelname
= get_identifier (label_buf
);
25204 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
25207 labelname
= get_prev_label (funname
);
25209 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25210 instruction will reach 'foo', otherwise link as 'bl L42'".
25211 "L42" should be a 'branch island', that will do a far jump to
25212 'foo'. Branch islands are generated in
25213 macho_branch_islands(). */
25214 sprintf (buf
, "jbsr %%z%d,%.246s",
25215 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
25218 sprintf (buf
, "bl %%z%d", dest_operand_number
);
25222 /* Generate PIC and indirect symbol stubs. */
25225 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
25227 unsigned int length
;
25228 char *symbol_name
, *lazy_ptr_name
;
25229 char *local_label_0
;
25230 static int label
= 0;
25232 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25233 symb
= (*targetm
.strip_name_encoding
) (symb
);
25236 length
= strlen (symb
);
25237 symbol_name
= XALLOCAVEC (char, length
+ 32);
25238 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
25240 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
25241 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
25244 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
25246 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
25250 fprintf (file
, "\t.align 5\n");
25252 fprintf (file
, "%s:\n", stub
);
25253 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25256 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25257 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
25259 fprintf (file
, "\tmflr r0\n");
25260 if (TARGET_LINK_STACK
)
25263 get_ppc476_thunk_name (name
);
25264 fprintf (file
, "\tbl %s\n", name
);
25265 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
25269 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
25270 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
25272 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
25273 lazy_ptr_name
, local_label_0
);
25274 fprintf (file
, "\tmtlr r0\n");
25275 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
25276 (TARGET_64BIT
? "ldu" : "lwzu"),
25277 lazy_ptr_name
, local_label_0
);
25278 fprintf (file
, "\tmtctr r12\n");
25279 fprintf (file
, "\tbctr\n");
25283 fprintf (file
, "\t.align 4\n");
25285 fprintf (file
, "%s:\n", stub
);
25286 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25288 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
25289 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
25290 (TARGET_64BIT
? "ldu" : "lwzu"),
25292 fprintf (file
, "\tmtctr r12\n");
25293 fprintf (file
, "\tbctr\n");
25296 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
25297 fprintf (file
, "%s:\n", lazy_ptr_name
);
25298 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25299 fprintf (file
, "%sdyld_stub_binding_helper\n",
25300 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
25303 /* Legitimize PIC addresses. If the address is already
25304 position-independent, we return ORIG. Newly generated
25305 position-independent addresses go into a reg. This is REG if non
25306 zero, otherwise we allocate register(s) as necessary. */
25308 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25311 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
25316 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
25317 reg
= gen_reg_rtx (Pmode
);
25319 if (GET_CODE (orig
) == CONST
)
25323 if (GET_CODE (XEXP (orig
, 0)) == PLUS
25324 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
25327 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
25329 /* Use a different reg for the intermediate value, as
25330 it will be marked UNCHANGING. */
25331 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
25332 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
25335 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
25338 if (GET_CODE (offset
) == CONST_INT
)
25340 if (SMALL_INT (offset
))
25341 return plus_constant (base
, INTVAL (offset
));
25342 else if (! reload_in_progress
&& ! reload_completed
)
25343 offset
= force_reg (Pmode
, offset
);
25346 rtx mem
= force_const_mem (Pmode
, orig
);
25347 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
25350 return gen_rtx_PLUS (Pmode
, base
, offset
);
25353 /* Fall back on generic machopic code. */
25354 return machopic_legitimize_pic_address (orig
, mode
, reg
);
25357 /* Output a .machine directive for the Darwin assembler, and call
25358 the generic start_file routine. */
25361 rs6000_darwin_file_start (void)
25363 static const struct
25369 { "ppc64", "ppc64", MASK_64BIT
},
25370 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
25371 { "power4", "ppc970", 0 },
25372 { "G5", "ppc970", 0 },
25373 { "7450", "ppc7450", 0 },
25374 { "7400", "ppc7400", MASK_ALTIVEC
},
25375 { "G4", "ppc7400", 0 },
25376 { "750", "ppc750", 0 },
25377 { "740", "ppc750", 0 },
25378 { "G3", "ppc750", 0 },
25379 { "604e", "ppc604e", 0 },
25380 { "604", "ppc604", 0 },
25381 { "603e", "ppc603", 0 },
25382 { "603", "ppc603", 0 },
25383 { "601", "ppc601", 0 },
25384 { NULL
, "ppc", 0 } };
25385 const char *cpu_id
= "";
25388 rs6000_file_start ();
25389 darwin_file_start ();
25391 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25393 if (rs6000_default_cpu
!= 0 && rs6000_default_cpu
[0] != '\0')
25394 cpu_id
= rs6000_default_cpu
;
25396 if (global_options_set
.x_rs6000_cpu_index
)
25397 cpu_id
= processor_target_table
[rs6000_cpu_index
].name
;
25399 /* Look through the mapping array. Pick the first name that either
25400 matches the argument, has a bit set in IF_SET that is also set
25401 in the target flags, or has a NULL name. */
25404 while (mapping
[i
].arg
!= NULL
25405 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
25406 && (mapping
[i
].if_set
& target_flags
) == 0)
25409 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
25412 #endif /* TARGET_MACHO */
25416 rs6000_elf_reloc_rw_mask (void)
25420 else if (DEFAULT_ABI
== ABI_AIX
)
25426 /* Record an element in the table of global constructors. SYMBOL is
25427 a SYMBOL_REF of the function to be called; PRIORITY is a number
25428 between 0 and MAX_INIT_PRIORITY.
25430 This differs from default_named_section_asm_out_constructor in
25431 that we have special handling for -mrelocatable. */
25434 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
25436 const char *section
= ".ctors";
25439 if (priority
!= DEFAULT_INIT_PRIORITY
)
25441 sprintf (buf
, ".ctors.%.5u",
25442 /* Invert the numbering so the linker puts us in the proper
25443 order; constructors are run from right to left, and the
25444 linker sorts in increasing order. */
25445 MAX_INIT_PRIORITY
- priority
);
25449 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25450 assemble_align (POINTER_SIZE
);
25452 if (TARGET_RELOCATABLE
)
25454 fputs ("\t.long (", asm_out_file
);
25455 output_addr_const (asm_out_file
, symbol
);
25456 fputs (")@fixup\n", asm_out_file
);
25459 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25463 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
25465 const char *section
= ".dtors";
25468 if (priority
!= DEFAULT_INIT_PRIORITY
)
25470 sprintf (buf
, ".dtors.%.5u",
25471 /* Invert the numbering so the linker puts us in the proper
25472 order; constructors are run from right to left, and the
25473 linker sorts in increasing order. */
25474 MAX_INIT_PRIORITY
- priority
);
25478 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25479 assemble_align (POINTER_SIZE
);
25481 if (TARGET_RELOCATABLE
)
25483 fputs ("\t.long (", asm_out_file
);
25484 output_addr_const (asm_out_file
, symbol
);
25485 fputs (")@fixup\n", asm_out_file
);
25488 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25492 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
25496 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
25497 ASM_OUTPUT_LABEL (file
, name
);
25498 fputs (DOUBLE_INT_ASM_OP
, file
);
25499 rs6000_output_function_entry (file
, name
);
25500 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
25503 fputs ("\t.size\t", file
);
25504 assemble_name (file
, name
);
25505 fputs (",24\n\t.type\t.", file
);
25506 assemble_name (file
, name
);
25507 fputs (",@function\n", file
);
25508 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
25510 fputs ("\t.globl\t.", file
);
25511 assemble_name (file
, name
);
25516 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25517 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25518 rs6000_output_function_entry (file
, name
);
25519 fputs (":\n", file
);
25523 if (TARGET_RELOCATABLE
25524 && !TARGET_SECURE_PLT
25525 && (get_pool_size () != 0 || crtl
->profile
)
25530 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
25532 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
25533 fprintf (file
, "\t.long ");
25534 assemble_name (file
, buf
);
25536 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
25537 assemble_name (file
, buf
);
25541 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25542 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25544 if (DEFAULT_ABI
== ABI_AIX
)
25546 const char *desc_name
, *orig_name
;
25548 orig_name
= (*targetm
.strip_name_encoding
) (name
);
25549 desc_name
= orig_name
;
25550 while (*desc_name
== '.')
25553 if (TREE_PUBLIC (decl
))
25554 fprintf (file
, "\t.globl %s\n", desc_name
);
25556 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25557 fprintf (file
, "%s:\n", desc_name
);
25558 fprintf (file
, "\t.long %s\n", orig_name
);
25559 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
25560 if (DEFAULT_ABI
== ABI_AIX
)
25561 fputs ("\t.long 0\n", file
);
25562 fprintf (file
, "\t.previous\n");
25564 ASM_OUTPUT_LABEL (file
, name
);
25568 rs6000_elf_file_end (void)
25570 #ifdef HAVE_AS_GNU_ATTRIBUTE
25571 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
25573 if (rs6000_passes_float
)
25574 fprintf (asm_out_file
, "\t.gnu_attribute 4, %d\n",
25575 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
25576 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
25578 if (rs6000_passes_vector
)
25579 fprintf (asm_out_file
, "\t.gnu_attribute 8, %d\n",
25580 (TARGET_ALTIVEC_ABI
? 2
25581 : TARGET_SPE_ABI
? 3
25583 if (rs6000_returns_struct
)
25584 fprintf (asm_out_file
, "\t.gnu_attribute 12, %d\n",
25585 aix_struct_return
? 2 : 1);
25588 #ifdef POWERPC_LINUX
25590 file_end_indicate_exec_stack ();
25597 rs6000_xcoff_asm_output_anchor (rtx symbol
)
25601 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
25602 SYMBOL_REF_BLOCK_OFFSET (symbol
));
25603 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
25607 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
25609 fputs (GLOBAL_ASM_OP
, stream
);
25610 RS6000_OUTPUT_BASENAME (stream
, name
);
25611 putc ('\n', stream
);
25614 /* A get_unnamed_decl callback, used for read-only sections. PTR
25615 points to the section string variable. */
25618 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
25620 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
25621 *(const char *const *) directive
,
25622 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
25625 /* Likewise for read-write sections. */
25628 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
25630 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
25631 *(const char *const *) directive
,
25632 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
25635 /* A get_unnamed_section callback, used for switching to toc_section. */
25638 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
25640 if (TARGET_MINIMAL_TOC
)
25642 /* toc_section is always selected at least once from
25643 rs6000_xcoff_file_start, so this is guaranteed to
25644 always be defined once and only once in each file. */
25645 if (!toc_initialized
)
25647 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
25648 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
25649 toc_initialized
= 1;
25651 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
25652 (TARGET_32BIT
? "" : ",3"));
25655 fputs ("\t.toc\n", asm_out_file
);
25658 /* Implement TARGET_ASM_INIT_SECTIONS. */
25661 rs6000_xcoff_asm_init_sections (void)
25663 read_only_data_section
25664 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
25665 &xcoff_read_only_section_name
);
25667 private_data_section
25668 = get_unnamed_section (SECTION_WRITE
,
25669 rs6000_xcoff_output_readwrite_section_asm_op
,
25670 &xcoff_private_data_section_name
);
25672 read_only_private_data_section
25673 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
25674 &xcoff_private_data_section_name
);
25677 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
25679 readonly_data_section
= read_only_data_section
;
25680 exception_section
= data_section
;
25684 rs6000_xcoff_reloc_rw_mask (void)
25690 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
25691 tree decl ATTRIBUTE_UNUSED
)
25694 static const char * const suffix
[3] = { "PR", "RO", "RW" };
25696 if (flags
& SECTION_CODE
)
25698 else if (flags
& SECTION_WRITE
)
25703 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
25704 (flags
& SECTION_CODE
) ? "." : "",
25705 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
25709 rs6000_xcoff_select_section (tree decl
, int reloc
,
25710 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
25712 if (decl_readonly_section (decl
, reloc
))
25714 if (TREE_PUBLIC (decl
))
25715 return read_only_data_section
;
25717 return read_only_private_data_section
;
25721 if (TREE_PUBLIC (decl
))
25722 return data_section
;
25724 return private_data_section
;
25729 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
25733 /* Use select_section for private and uninitialized data. */
25734 if (!TREE_PUBLIC (decl
)
25735 || DECL_COMMON (decl
)
25736 || DECL_INITIAL (decl
) == NULL_TREE
25737 || DECL_INITIAL (decl
) == error_mark_node
25738 || (flag_zero_initialized_in_bss
25739 && initializer_zerop (DECL_INITIAL (decl
))))
25742 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
25743 name
= (*targetm
.strip_name_encoding
) (name
);
25744 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
25747 /* Select section for constant in constant pool.
25749 On RS/6000, all constants are in the private read-only data area.
25750 However, if this is being placed in the TOC it must be output as a
25754 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
25755 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
25757 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
25758 return toc_section
;
25760 return read_only_private_data_section
;
25763 /* Remove any trailing [DS] or the like from the symbol name. */
25765 static const char *
25766 rs6000_xcoff_strip_name_encoding (const char *name
)
25771 len
= strlen (name
);
25772 if (name
[len
- 1] == ']')
25773 return ggc_alloc_string (name
, len
- 4);
25778 /* Section attributes. AIX is always PIC. */
25780 static unsigned int
25781 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
25783 unsigned int align
;
25784 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
25786 /* Align to at least UNIT size. */
25787 if (flags
& SECTION_CODE
|| !decl
)
25788 align
= MIN_UNITS_PER_WORD
;
25790 /* Increase alignment of large objects if not already stricter. */
25791 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
25792 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
25793 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
25795 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
25798 /* Output at beginning of assembler file.
25800 Initialize the section names for the RS/6000 at this point.
25802 Specify filename, including full path, to assembler.
25804 We want to go into the TOC section so at least one .toc will be emitted.
25805 Also, in order to output proper .bs/.es pairs, we need at least one static
25806 [RW] section emitted.
25808 Finally, declare mcount when profiling to make the assembler happy. */
25811 rs6000_xcoff_file_start (void)
25813 rs6000_gen_section_name (&xcoff_bss_section_name
,
25814 main_input_filename
, ".bss_");
25815 rs6000_gen_section_name (&xcoff_private_data_section_name
,
25816 main_input_filename
, ".rw_");
25817 rs6000_gen_section_name (&xcoff_read_only_section_name
,
25818 main_input_filename
, ".ro_");
25820 fputs ("\t.file\t", asm_out_file
);
25821 output_quoted_string (asm_out_file
, main_input_filename
);
25822 fputc ('\n', asm_out_file
);
25823 if (write_symbols
!= NO_DEBUG
)
25824 switch_to_section (private_data_section
);
25825 switch_to_section (text_section
);
25827 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
25828 rs6000_file_start ();
25831 /* Output at end of assembler file.
25832 On the RS/6000, referencing data should automatically pull in text. */
25835 rs6000_xcoff_file_end (void)
25837 switch_to_section (text_section
);
25838 fputs ("_section_.text:\n", asm_out_file
);
25839 switch_to_section (data_section
);
25840 fputs (TARGET_32BIT
25841 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25844 #endif /* TARGET_XCOFF */
25846 /* Compute a (partial) cost for rtx X. Return true if the complete
25847 cost has been computed, and false if subexpressions should be
25848 scanned. In either case, *TOTAL contains the cost result. */
25851 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int opno ATTRIBUTE_UNUSED
,
25852 int *total
, bool speed
)
25854 enum machine_mode mode
= GET_MODE (x
);
25858 /* On the RS/6000, if it is valid in the insn, it is free. */
25860 if (((outer_code
== SET
25861 || outer_code
== PLUS
25862 || outer_code
== MINUS
)
25863 && (satisfies_constraint_I (x
)
25864 || satisfies_constraint_L (x
)))
25865 || (outer_code
== AND
25866 && (satisfies_constraint_K (x
)
25868 ? satisfies_constraint_L (x
)
25869 : satisfies_constraint_J (x
))
25870 || mask_operand (x
, mode
)
25872 && mask64_operand (x
, DImode
))))
25873 || ((outer_code
== IOR
|| outer_code
== XOR
)
25874 && (satisfies_constraint_K (x
)
25876 ? satisfies_constraint_L (x
)
25877 : satisfies_constraint_J (x
))))
25878 || outer_code
== ASHIFT
25879 || outer_code
== ASHIFTRT
25880 || outer_code
== LSHIFTRT
25881 || outer_code
== ROTATE
25882 || outer_code
== ROTATERT
25883 || outer_code
== ZERO_EXTRACT
25884 || (outer_code
== MULT
25885 && satisfies_constraint_I (x
))
25886 || ((outer_code
== DIV
|| outer_code
== UDIV
25887 || outer_code
== MOD
|| outer_code
== UMOD
)
25888 && exact_log2 (INTVAL (x
)) >= 0)
25889 || (outer_code
== COMPARE
25890 && (satisfies_constraint_I (x
)
25891 || satisfies_constraint_K (x
)))
25892 || ((outer_code
== EQ
|| outer_code
== NE
)
25893 && (satisfies_constraint_I (x
)
25894 || satisfies_constraint_K (x
)
25896 ? satisfies_constraint_L (x
)
25897 : satisfies_constraint_J (x
))))
25898 || (outer_code
== GTU
25899 && satisfies_constraint_I (x
))
25900 || (outer_code
== LTU
25901 && satisfies_constraint_P (x
)))
25906 else if ((outer_code
== PLUS
25907 && reg_or_add_cint_operand (x
, VOIDmode
))
25908 || (outer_code
== MINUS
25909 && reg_or_sub_cint_operand (x
, VOIDmode
))
25910 || ((outer_code
== SET
25911 || outer_code
== IOR
25912 || outer_code
== XOR
)
25914 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
25916 *total
= COSTS_N_INSNS (1);
25922 if (mode
== DImode
&& code
== CONST_DOUBLE
)
25924 if ((outer_code
== IOR
|| outer_code
== XOR
)
25925 && CONST_DOUBLE_HIGH (x
) == 0
25926 && (CONST_DOUBLE_LOW (x
)
25927 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
25932 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
25933 || ((outer_code
== SET
25934 || outer_code
== IOR
25935 || outer_code
== XOR
)
25936 && CONST_DOUBLE_HIGH (x
) == 0))
25938 *total
= COSTS_N_INSNS (1);
25948 /* When optimizing for size, MEM should be slightly more expensive
25949 than generating address, e.g., (plus (reg) (const)).
25950 L1 cache latency is about two instructions. */
25951 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25960 if (FLOAT_MODE_P (mode
))
25961 *total
= rs6000_cost
->fp
;
25963 *total
= COSTS_N_INSNS (1);
25967 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
25968 && satisfies_constraint_I (XEXP (x
, 1)))
25970 if (INTVAL (XEXP (x
, 1)) >= -256
25971 && INTVAL (XEXP (x
, 1)) <= 255)
25972 *total
= rs6000_cost
->mulsi_const9
;
25974 *total
= rs6000_cost
->mulsi_const
;
25976 else if (mode
== SFmode
)
25977 *total
= rs6000_cost
->fp
;
25978 else if (FLOAT_MODE_P (mode
))
25979 *total
= rs6000_cost
->dmul
;
25980 else if (mode
== DImode
)
25981 *total
= rs6000_cost
->muldi
;
25983 *total
= rs6000_cost
->mulsi
;
25987 if (mode
== SFmode
)
25988 *total
= rs6000_cost
->fp
;
25990 *total
= rs6000_cost
->dmul
;
25995 if (FLOAT_MODE_P (mode
))
25997 *total
= mode
== DFmode
? rs6000_cost
->ddiv
25998 : rs6000_cost
->sdiv
;
26005 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
26006 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
26008 if (code
== DIV
|| code
== MOD
)
26010 *total
= COSTS_N_INSNS (2);
26013 *total
= COSTS_N_INSNS (1);
26017 if (GET_MODE (XEXP (x
, 1)) == DImode
)
26018 *total
= rs6000_cost
->divdi
;
26020 *total
= rs6000_cost
->divsi
;
26022 /* Add in shift and subtract for MOD. */
26023 if (code
== MOD
|| code
== UMOD
)
26024 *total
+= COSTS_N_INSNS (2);
26029 *total
= COSTS_N_INSNS (4);
26033 *total
= COSTS_N_INSNS (TARGET_POPCNTD
? 1 : 6);
26037 *total
= COSTS_N_INSNS (TARGET_CMPB
? 2 : 6);
26041 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
26053 *total
= COSTS_N_INSNS (1);
26061 /* Handle mul_highpart. */
26062 if (outer_code
== TRUNCATE
26063 && GET_CODE (XEXP (x
, 0)) == MULT
)
26065 if (mode
== DImode
)
26066 *total
= rs6000_cost
->muldi
;
26068 *total
= rs6000_cost
->mulsi
;
26071 else if (outer_code
== AND
)
26074 *total
= COSTS_N_INSNS (1);
26079 if (GET_CODE (XEXP (x
, 0)) == MEM
)
26082 *total
= COSTS_N_INSNS (1);
26088 if (!FLOAT_MODE_P (mode
))
26090 *total
= COSTS_N_INSNS (1);
26096 case UNSIGNED_FLOAT
:
26099 case FLOAT_TRUNCATE
:
26100 *total
= rs6000_cost
->fp
;
26104 if (mode
== DFmode
)
26107 *total
= rs6000_cost
->fp
;
26111 switch (XINT (x
, 1))
26114 *total
= rs6000_cost
->fp
;
26126 *total
= COSTS_N_INSNS (1);
26129 else if (FLOAT_MODE_P (mode
)
26130 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26132 *total
= rs6000_cost
->fp
;
26140 /* Carry bit requires mode == Pmode.
26141 NEG or PLUS already counted so only add one. */
26143 && (outer_code
== NEG
|| outer_code
== PLUS
))
26145 *total
= COSTS_N_INSNS (1);
26148 if (outer_code
== SET
)
26150 if (XEXP (x
, 1) == const0_rtx
)
26152 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26153 *total
= COSTS_N_INSNS (8);
26155 *total
= COSTS_N_INSNS (2);
26158 else if (mode
== Pmode
)
26160 *total
= COSTS_N_INSNS (3);
26169 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
26171 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26172 *total
= COSTS_N_INSNS (8);
26174 *total
= COSTS_N_INSNS (2);
26178 if (outer_code
== COMPARE
)
26192 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26195 rs6000_debug_rtx_costs (rtx x
, int code
, int outer_code
, int opno
, int *total
,
26198 bool ret
= rs6000_rtx_costs (x
, code
, outer_code
, opno
, total
, speed
);
26201 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26202 "opno = %d, total = %d, speed = %s, x:\n",
26203 ret
? "complete" : "scan inner",
26204 GET_RTX_NAME (code
),
26205 GET_RTX_NAME (outer_code
),
26208 speed
? "true" : "false");
26215 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26218 rs6000_debug_address_cost (rtx x
, bool speed
)
26220 int ret
= TARGET_ADDRESS_COST (x
, speed
);
26222 fprintf (stderr
, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26223 ret
, speed
? "true" : "false");
26230 /* A C expression returning the cost of moving data from a register of class
26231 CLASS1 to one of CLASS2. */
26234 rs6000_register_move_cost (enum machine_mode mode
,
26235 reg_class_t from
, reg_class_t to
)
26239 if (TARGET_DEBUG_COST
)
26242 /* Moves from/to GENERAL_REGS. */
26243 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
26244 || reg_classes_intersect_p (from
, GENERAL_REGS
))
26246 reg_class_t rclass
= from
;
26248 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
26251 if (rclass
== FLOAT_REGS
|| rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
26252 ret
= (rs6000_memory_move_cost (mode
, rclass
, false)
26253 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, false));
26255 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26257 else if (rclass
== CR_REGS
)
26260 /* For those processors that have slow LR/CTR moves, make them more
26261 expensive than memory in order to bias spills to memory .*/
26262 else if ((rs6000_cpu
== PROCESSOR_POWER6
26263 || rs6000_cpu
== PROCESSOR_POWER7
)
26264 && reg_classes_intersect_p (rclass
, LINK_OR_CTR_REGS
))
26265 ret
= 6 * hard_regno_nregs
[0][mode
];
26268 /* A move will cost one instruction per GPR moved. */
26269 ret
= 2 * hard_regno_nregs
[0][mode
];
26272 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26273 else if (VECTOR_UNIT_VSX_P (mode
)
26274 && reg_classes_intersect_p (to
, VSX_REGS
)
26275 && reg_classes_intersect_p (from
, VSX_REGS
))
26276 ret
= 2 * hard_regno_nregs
[32][mode
];
26278 /* Moving between two similar registers is just one instruction. */
26279 else if (reg_classes_intersect_p (to
, from
))
26280 ret
= (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
26282 /* Everything else has to go through GENERAL_REGS. */
26284 ret
= (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
26285 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
26287 if (TARGET_DEBUG_COST
)
26289 if (dbg_cost_ctrl
== 1)
26291 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26292 ret
, GET_MODE_NAME (mode
), reg_class_names
[from
],
26293 reg_class_names
[to
]);
26300 /* A C expressions returning the cost of moving data of MODE from a register to
26304 rs6000_memory_move_cost (enum machine_mode mode
, reg_class_t rclass
,
26305 bool in ATTRIBUTE_UNUSED
)
26309 if (TARGET_DEBUG_COST
)
26312 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
26313 ret
= 4 * hard_regno_nregs
[0][mode
];
26314 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
26315 ret
= 4 * hard_regno_nregs
[32][mode
];
26316 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
26317 ret
= 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
26319 ret
= 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
26321 if (TARGET_DEBUG_COST
)
26323 if (dbg_cost_ctrl
== 1)
26325 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26326 ret
, GET_MODE_NAME (mode
), reg_class_names
[rclass
], in
);
26333 /* Returns a code for a target-specific builtin that implements
26334 reciprocal of the function, or NULL_TREE if not available. */
26337 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
26338 bool sqrt ATTRIBUTE_UNUSED
)
26340 if (optimize_insn_for_size_p ())
26346 case VSX_BUILTIN_XVSQRTDP
:
26347 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode
))
26350 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
26352 case VSX_BUILTIN_XVSQRTSP
:
26353 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode
))
26356 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V4SF
];
26365 case BUILT_IN_SQRT
:
26366 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode
))
26369 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRT
];
26371 case BUILT_IN_SQRTF
:
26372 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode
))
26375 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
26382 /* Load up a constant. If the mode is a vector mode, splat the value across
26383 all of the vector elements. */
26386 rs6000_load_constant_and_splat (enum machine_mode mode
, REAL_VALUE_TYPE dconst
)
26390 if (mode
== SFmode
|| mode
== DFmode
)
26392 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, mode
);
26393 reg
= force_reg (mode
, d
);
26395 else if (mode
== V4SFmode
)
26397 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, SFmode
);
26398 rtvec v
= gen_rtvec (4, d
, d
, d
, d
);
26399 reg
= gen_reg_rtx (mode
);
26400 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26402 else if (mode
== V2DFmode
)
26404 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, DFmode
);
26405 rtvec v
= gen_rtvec (2, d
, d
);
26406 reg
= gen_reg_rtx (mode
);
26407 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26410 gcc_unreachable ();
26415 /* Generate an FMA instruction. */
26418 rs6000_emit_madd (rtx target
, rtx m1
, rtx m2
, rtx a
)
26420 enum machine_mode mode
= GET_MODE (target
);
26423 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26424 gcc_assert (dst
!= NULL
);
26427 emit_move_insn (target
, dst
);
26430 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26433 rs6000_emit_msub (rtx target
, rtx m1
, rtx m2
, rtx a
)
26435 enum machine_mode mode
= GET_MODE (target
);
26438 /* Altivec does not support fms directly;
26439 generate in terms of fma in that case. */
26440 if (optab_handler (fms_optab
, mode
) != CODE_FOR_nothing
)
26441 dst
= expand_ternary_op (mode
, fms_optab
, m1
, m2
, a
, target
, 0);
26444 a
= expand_unop (mode
, neg_optab
, a
, NULL_RTX
, 0);
26445 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26447 gcc_assert (dst
!= NULL
);
26450 emit_move_insn (target
, dst
);
26453 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26456 rs6000_emit_nmsub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26458 enum machine_mode mode
= GET_MODE (dst
);
26461 /* This is a tad more complicated, since the fnma_optab is for
26462 a different expression: fma(-m1, m2, a), which is the same
26463 thing except in the case of signed zeros.
26465 Fortunately we know that if FMA is supported that FNMSUB is
26466 also supported in the ISA. Just expand it directly. */
26468 gcc_assert (optab_handler (fma_optab
, mode
) != CODE_FOR_nothing
);
26470 r
= gen_rtx_NEG (mode
, a
);
26471 r
= gen_rtx_FMA (mode
, m1
, m2
, r
);
26472 r
= gen_rtx_NEG (mode
, r
);
26473 emit_insn (gen_rtx_SET (VOIDmode
, dst
, r
));
26476 /* Newton-Raphson approximation of floating point divide with just 2 passes
26477 (either single precision floating point, or newer machines with higher
26478 accuracy estimates). Support both scalar and vector divide. Assumes no
26479 trapping math and finite arguments. */
26482 rs6000_emit_swdiv_high_precision (rtx dst
, rtx n
, rtx d
)
26484 enum machine_mode mode
= GET_MODE (dst
);
26485 rtx x0
, e0
, e1
, y1
, u0
, v0
;
26486 enum insn_code code
= optab_handler (smul_optab
, mode
);
26487 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26488 rtx one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26490 gcc_assert (code
!= CODE_FOR_nothing
);
26492 /* x0 = 1./d estimate */
26493 x0
= gen_reg_rtx (mode
);
26494 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26495 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26498 e0
= gen_reg_rtx (mode
);
26499 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - (d * x0) */
26501 e1
= gen_reg_rtx (mode
);
26502 rs6000_emit_madd (e1
, e0
, e0
, e0
); /* e1 = (e0 * e0) + e0 */
26504 y1
= gen_reg_rtx (mode
);
26505 rs6000_emit_madd (y1
, e1
, x0
, x0
); /* y1 = (e1 * x0) + x0 */
26507 u0
= gen_reg_rtx (mode
);
26508 emit_insn (gen_mul (u0
, n
, y1
)); /* u0 = n * y1 */
26510 v0
= gen_reg_rtx (mode
);
26511 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - (d * u0) */
26513 rs6000_emit_madd (dst
, v0
, y1
, u0
); /* dst = (v0 * y1) + u0 */
26516 /* Newton-Raphson approximation of floating point divide that has a low
26517 precision estimate. Assumes no trapping math and finite arguments. */
26520 rs6000_emit_swdiv_low_precision (rtx dst
, rtx n
, rtx d
)
26522 enum machine_mode mode
= GET_MODE (dst
);
26523 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
26524 enum insn_code code
= optab_handler (smul_optab
, mode
);
26525 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26527 gcc_assert (code
!= CODE_FOR_nothing
);
26529 one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26531 /* x0 = 1./d estimate */
26532 x0
= gen_reg_rtx (mode
);
26533 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26534 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26537 e0
= gen_reg_rtx (mode
);
26538 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - d * x0 */
26540 y1
= gen_reg_rtx (mode
);
26541 rs6000_emit_madd (y1
, e0
, x0
, x0
); /* y1 = x0 + e0 * x0 */
26543 e1
= gen_reg_rtx (mode
);
26544 emit_insn (gen_mul (e1
, e0
, e0
)); /* e1 = e0 * e0 */
26546 y2
= gen_reg_rtx (mode
);
26547 rs6000_emit_madd (y2
, e1
, y1
, y1
); /* y2 = y1 + e1 * y1 */
26549 e2
= gen_reg_rtx (mode
);
26550 emit_insn (gen_mul (e2
, e1
, e1
)); /* e2 = e1 * e1 */
26552 y3
= gen_reg_rtx (mode
);
26553 rs6000_emit_madd (y3
, e2
, y2
, y2
); /* y3 = y2 + e2 * y2 */
26555 u0
= gen_reg_rtx (mode
);
26556 emit_insn (gen_mul (u0
, n
, y3
)); /* u0 = n * y3 */
26558 v0
= gen_reg_rtx (mode
);
26559 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - d * u0 */
26561 rs6000_emit_madd (dst
, v0
, y3
, u0
); /* dst = u0 + v0 * y3 */
26564 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26565 add a reg_note saying that this was a division. Support both scalar and
26566 vector divide. Assumes no trapping math and finite arguments. */
26569 rs6000_emit_swdiv (rtx dst
, rtx n
, rtx d
, bool note_p
)
26571 enum machine_mode mode
= GET_MODE (dst
);
26573 if (RS6000_RECIP_HIGH_PRECISION_P (mode
))
26574 rs6000_emit_swdiv_high_precision (dst
, n
, d
);
26576 rs6000_emit_swdiv_low_precision (dst
, n
, d
);
26579 add_reg_note (get_last_insn (), REG_EQUAL
, gen_rtx_DIV (mode
, n
, d
));
26582 /* Newton-Raphson approximation of single/double-precision floating point
26583 rsqrt. Assumes no trapping math and finite arguments. */
26586 rs6000_emit_swrsqrt (rtx dst
, rtx src
)
26588 enum machine_mode mode
= GET_MODE (src
);
26589 rtx x0
= gen_reg_rtx (mode
);
26590 rtx y
= gen_reg_rtx (mode
);
26591 int passes
= (TARGET_RECIP_PRECISION
) ? 2 : 3;
26592 REAL_VALUE_TYPE dconst3_2
;
26595 enum insn_code code
= optab_handler (smul_optab
, mode
);
26596 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26598 gcc_assert (code
!= CODE_FOR_nothing
);
26600 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26601 real_from_integer (&dconst3_2
, VOIDmode
, 3, 0, 0);
26602 SET_REAL_EXP (&dconst3_2
, REAL_EXP (&dconst3_2
) - 1);
26604 halfthree
= rs6000_load_constant_and_splat (mode
, dconst3_2
);
26606 /* x0 = rsqrt estimate */
26607 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26608 gen_rtx_UNSPEC (mode
, gen_rtvec (1, src
),
26611 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26612 rs6000_emit_msub (y
, src
, halfthree
, src
);
26614 for (i
= 0; i
< passes
; i
++)
26616 rtx x1
= gen_reg_rtx (mode
);
26617 rtx u
= gen_reg_rtx (mode
);
26618 rtx v
= gen_reg_rtx (mode
);
26620 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26621 emit_insn (gen_mul (u
, x0
, x0
));
26622 rs6000_emit_nmsub (v
, y
, u
, halfthree
);
26623 emit_insn (gen_mul (x1
, x0
, v
));
26627 emit_move_insn (dst
, x0
);
26631 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26632 (Power7) targets. DST is the target, and SRC is the argument operand. */
26635 rs6000_emit_popcount (rtx dst
, rtx src
)
26637 enum machine_mode mode
= GET_MODE (dst
);
26640 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26641 if (TARGET_POPCNTD
)
26643 if (mode
== SImode
)
26644 emit_insn (gen_popcntdsi2 (dst
, src
));
26646 emit_insn (gen_popcntddi2 (dst
, src
));
26650 tmp1
= gen_reg_rtx (mode
);
26652 if (mode
== SImode
)
26654 emit_insn (gen_popcntbsi2 (tmp1
, src
));
26655 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
26657 tmp2
= force_reg (SImode
, tmp2
);
26658 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
26662 emit_insn (gen_popcntbdi2 (tmp1
, src
));
26663 tmp2
= expand_mult (DImode
, tmp1
,
26664 GEN_INT ((HOST_WIDE_INT
)
26665 0x01010101 << 32 | 0x01010101),
26667 tmp2
= force_reg (DImode
, tmp2
);
26668 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
26673 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26674 target, and SRC is the argument operand. */
26677 rs6000_emit_parity (rtx dst
, rtx src
)
26679 enum machine_mode mode
= GET_MODE (dst
);
26682 tmp
= gen_reg_rtx (mode
);
26684 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26687 if (mode
== SImode
)
26689 emit_insn (gen_popcntbsi2 (tmp
, src
));
26690 emit_insn (gen_paritysi2_cmpb (dst
, tmp
));
26694 emit_insn (gen_popcntbdi2 (tmp
, src
));
26695 emit_insn (gen_paritydi2_cmpb (dst
, tmp
));
26700 if (mode
== SImode
)
26702 /* Is mult+shift >= shift+xor+shift+xor? */
26703 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
26705 rtx tmp1
, tmp2
, tmp3
, tmp4
;
26707 tmp1
= gen_reg_rtx (SImode
);
26708 emit_insn (gen_popcntbsi2 (tmp1
, src
));
26710 tmp2
= gen_reg_rtx (SImode
);
26711 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
26712 tmp3
= gen_reg_rtx (SImode
);
26713 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
26715 tmp4
= gen_reg_rtx (SImode
);
26716 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
26717 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
26720 rs6000_emit_popcount (tmp
, src
);
26721 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
26725 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26726 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
26728 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
26730 tmp1
= gen_reg_rtx (DImode
);
26731 emit_insn (gen_popcntbdi2 (tmp1
, src
));
26733 tmp2
= gen_reg_rtx (DImode
);
26734 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
26735 tmp3
= gen_reg_rtx (DImode
);
26736 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
26738 tmp4
= gen_reg_rtx (DImode
);
26739 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
26740 tmp5
= gen_reg_rtx (DImode
);
26741 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
26743 tmp6
= gen_reg_rtx (DImode
);
26744 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
26745 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
26748 rs6000_emit_popcount (tmp
, src
);
26749 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
26753 /* Return an RTX representing where to find the function value of a
26754 function returning MODE. */
26756 rs6000_complex_function_value (enum machine_mode mode
)
26758 unsigned int regno
;
26760 enum machine_mode inner
= GET_MODE_INNER (mode
);
26761 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
26763 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26764 regno
= FP_ARG_RETURN
;
26767 regno
= GP_ARG_RETURN
;
26769 /* 32-bit is OK since it'll go in r3/r4. */
26770 if (TARGET_32BIT
&& inner_bytes
>= 4)
26771 return gen_rtx_REG (mode
, regno
);
26774 if (inner_bytes
>= 8)
26775 return gen_rtx_REG (mode
, regno
);
26777 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
26779 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
26780 GEN_INT (inner_bytes
));
26781 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
26784 /* Target hook for TARGET_FUNCTION_VALUE.
26786 On the SPE, both FPs and vectors are returned in r3.
26788 On RS/6000 an integer value is in r3 and a floating-point value is in
26789 fp1, unless -msoft-float. */
26792 rs6000_function_value (const_tree valtype
,
26793 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
26794 bool outgoing ATTRIBUTE_UNUSED
)
26796 enum machine_mode mode
;
26797 unsigned int regno
;
26799 /* Special handling for structs in darwin64. */
26801 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype
), valtype
))
26803 CUMULATIVE_ARGS valcum
;
26807 valcum
.fregno
= FP_ARG_MIN_REG
;
26808 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
26809 /* Do a trial code generation as if this were going to be passed as
26810 an argument; if any part goes in memory, we return NULL. */
26811 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, true, /* retval= */ true);
26814 /* Otherwise fall through to standard ABI rules. */
26817 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
26819 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26820 return gen_rtx_PARALLEL (DImode
,
26822 gen_rtx_EXPR_LIST (VOIDmode
,
26823 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26825 gen_rtx_EXPR_LIST (VOIDmode
,
26826 gen_rtx_REG (SImode
,
26827 GP_ARG_RETURN
+ 1),
26830 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
26832 return gen_rtx_PARALLEL (DCmode
,
26834 gen_rtx_EXPR_LIST (VOIDmode
,
26835 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26837 gen_rtx_EXPR_LIST (VOIDmode
,
26838 gen_rtx_REG (SImode
,
26839 GP_ARG_RETURN
+ 1),
26841 gen_rtx_EXPR_LIST (VOIDmode
,
26842 gen_rtx_REG (SImode
,
26843 GP_ARG_RETURN
+ 2),
26845 gen_rtx_EXPR_LIST (VOIDmode
,
26846 gen_rtx_REG (SImode
,
26847 GP_ARG_RETURN
+ 3),
26851 mode
= TYPE_MODE (valtype
);
26852 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
26853 || POINTER_TYPE_P (valtype
))
26854 mode
= TARGET_32BIT
? SImode
: DImode
;
26856 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26857 /* _Decimal128 must use an even/odd register pair. */
26858 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
26859 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
26860 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
26861 regno
= FP_ARG_RETURN
;
26862 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
26863 && targetm
.calls
.split_complex_arg
)
26864 return rs6000_complex_function_value (mode
);
26865 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26866 return register is used in both cases, and we won't see V2DImode/V2DFmode
26867 for pure altivec, combine the two cases. */
26868 else if (TREE_CODE (valtype
) == VECTOR_TYPE
26869 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
26870 && ALTIVEC_OR_VSX_VECTOR_MODE (mode
))
26871 regno
= ALTIVEC_ARG_RETURN
;
26872 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
26873 && (mode
== DFmode
|| mode
== DCmode
26874 || mode
== TFmode
|| mode
== TCmode
))
26875 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
26877 regno
= GP_ARG_RETURN
;
26879 return gen_rtx_REG (mode
, regno
);
26882 /* Define how to find the value returned by a library function
26883 assuming the value has mode MODE. */
26885 rs6000_libcall_value (enum machine_mode mode
)
26887 unsigned int regno
;
26889 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
26891 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26892 return gen_rtx_PARALLEL (DImode
,
26894 gen_rtx_EXPR_LIST (VOIDmode
,
26895 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26897 gen_rtx_EXPR_LIST (VOIDmode
,
26898 gen_rtx_REG (SImode
,
26899 GP_ARG_RETURN
+ 1),
26903 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26904 /* _Decimal128 must use an even/odd register pair. */
26905 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
26906 else if (SCALAR_FLOAT_MODE_P (mode
)
26907 && TARGET_HARD_FLOAT
&& TARGET_FPRS
26908 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
26909 regno
= FP_ARG_RETURN
;
26910 /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same
26911 return register is used in both cases, and we won't see V2DImode/V2DFmode
26912 for pure altivec, combine the two cases. */
26913 else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode
)
26914 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
26915 regno
= ALTIVEC_ARG_RETURN
;
26916 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
26917 return rs6000_complex_function_value (mode
);
26918 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
26919 && (mode
== DFmode
|| mode
== DCmode
26920 || mode
== TFmode
|| mode
== TCmode
))
26921 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
26923 regno
= GP_ARG_RETURN
;
26925 return gen_rtx_REG (mode
, regno
);
26929 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26930 Frame pointer elimination is automatically handled.
26932 For the RS/6000, if frame pointer elimination is being done, we would like
26933 to convert ap into fp, not sp.
26935 We need r30 if -mminimal-toc was specified, and there are constant pool
26939 rs6000_can_eliminate (const int from
, const int to
)
26941 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
26942 ? ! frame_pointer_needed
26943 : from
== RS6000_PIC_OFFSET_TABLE_REGNUM
26944 ? ! TARGET_MINIMAL_TOC
|| TARGET_NO_TOC
|| get_pool_size () == 0
26948 /* Define the offset between two registers, FROM to be eliminated and its
26949 replacement TO, at the start of a routine. */
26951 rs6000_initial_elimination_offset (int from
, int to
)
26953 rs6000_stack_t
*info
= rs6000_stack_info ();
26954 HOST_WIDE_INT offset
;
26956 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26957 offset
= info
->push_p
? 0 : -info
->total_size
;
26958 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26960 offset
= info
->push_p
? 0 : -info
->total_size
;
26961 if (FRAME_GROWS_DOWNWARD
)
26962 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
26964 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
26965 offset
= FRAME_GROWS_DOWNWARD
26966 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
26968 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
26969 offset
= info
->total_size
;
26970 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26971 offset
= info
->push_p
? info
->total_size
: 0;
26972 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
26975 gcc_unreachable ();
26981 rs6000_dwarf_register_span (rtx reg
)
26985 unsigned regno
= REGNO (reg
);
26986 enum machine_mode mode
= GET_MODE (reg
);
26990 && (SPE_VECTOR_MODE (GET_MODE (reg
))
26991 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
26992 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
26997 regno
= REGNO (reg
);
26999 /* The duality of the SPE register size wreaks all kinds of havoc.
27000 This is a way of distinguishing r0 in 32-bits from r0 in
27002 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
27003 gcc_assert (words
<= 4);
27004 for (i
= 0; i
< words
; i
++, regno
++)
27006 if (BYTES_BIG_ENDIAN
)
27008 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
27009 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
27013 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
27014 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
27018 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
27021 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27024 rs6000_init_dwarf_reg_sizes_extra (tree address
)
27029 enum machine_mode mode
= TYPE_MODE (char_type_node
);
27030 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
27031 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
27032 rtx value
= gen_int_mode (4, mode
);
27034 for (i
= 1201; i
< 1232; i
++)
27036 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
27037 HOST_WIDE_INT offset
27038 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
27040 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
27045 /* Map internal gcc register numbers to DWARF2 register numbers. */
27048 rs6000_dbx_register_number (unsigned int regno
)
27050 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
27052 if (regno
== MQ_REGNO
)
27054 if (regno
== LR_REGNO
)
27056 if (regno
== CTR_REGNO
)
27058 if (CR_REGNO_P (regno
))
27059 return regno
- CR0_REGNO
+ 86;
27060 if (regno
== CA_REGNO
)
27061 return 101; /* XER */
27062 if (ALTIVEC_REGNO_P (regno
))
27063 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
27064 if (regno
== VRSAVE_REGNO
)
27066 if (regno
== VSCR_REGNO
)
27068 if (regno
== SPE_ACC_REGNO
)
27070 if (regno
== SPEFSCR_REGNO
)
27072 /* SPE high reg number. We get these values of regno from
27073 rs6000_dwarf_register_span. */
27074 gcc_assert (regno
>= 1200 && regno
< 1232);
27078 /* target hook eh_return_filter_mode */
27079 static enum machine_mode
27080 rs6000_eh_return_filter_mode (void)
27082 return TARGET_32BIT
? SImode
: word_mode
;
27085 /* Target hook for scalar_mode_supported_p. */
27087 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
27089 if (DECIMAL_FLOAT_MODE_P (mode
))
27090 return default_decimal_float_supported_p ();
27092 return default_scalar_mode_supported_p (mode
);
27095 /* Target hook for vector_mode_supported_p. */
27097 rs6000_vector_mode_supported_p (enum machine_mode mode
)
27100 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
27103 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
27106 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
27113 /* Target hook for invalid_arg_for_unprototyped_fn. */
27114 static const char *
27115 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
27117 return (!rs6000_darwin64_abi
27119 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
27120 && (funcdecl
== NULL_TREE
27121 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
27122 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
27123 ? N_("AltiVec argument passed to unprototyped function")
27127 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27128 setup by using __stack_chk_fail_local hidden function instead of
27129 calling __stack_chk_fail directly. Otherwise it is better to call
27130 __stack_chk_fail directly. */
27132 static tree ATTRIBUTE_UNUSED
27133 rs6000_stack_protect_fail (void)
27135 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
27136 ? default_hidden_stack_protect_fail ()
27137 : default_external_stack_protect_fail ();
27141 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
27142 int num_operands ATTRIBUTE_UNUSED
)
27144 if (rs6000_warn_cell_microcode
)
27147 int insn_code_number
= recog_memoized (insn
);
27148 location_t location
= locator_location (INSN_LOCATOR (insn
));
27150 /* Punt on insns we cannot recognize. */
27151 if (insn_code_number
< 0)
27154 temp
= get_insn_template (insn_code_number
, insn
);
27156 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
27157 warning_at (location
, OPT_mwarn_cell_microcode
,
27158 "emitting microcode insn %s\t[%s] #%d",
27159 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27160 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
27161 warning_at (location
, OPT_mwarn_cell_microcode
,
27162 "emitting conditional microcode insn %s\t[%s] #%d",
27163 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27168 /* Mask options that we want to support inside of attribute((target)) and
27169 #pragma GCC target operations. Note, we do not include things like
27170 64/32-bit, endianess, hard/soft floating point, etc. that would have
27171 different calling sequences. */
27173 struct rs6000_opt_mask
{
27174 const char *name
; /* option name */
27175 int mask
; /* mask to set */
27176 bool invert
; /* invert sense of mask */
27177 bool valid_target
; /* option is a target option */
27180 static struct rs6000_opt_mask
const rs6000_opt_masks
[] =
27182 { "altivec", MASK_ALTIVEC
, false, true },
27183 { "cmpb", MASK_CMPB
, false, true },
27184 { "dlmzb", MASK_DLMZB
, false, true },
27185 { "fprnd", MASK_FPRND
, false, true },
27186 { "hard-dfp", MASK_DFP
, false, true },
27187 { "isel", MASK_ISEL
, false, true },
27188 { "mfcrf", MASK_MFCRF
, false, true },
27189 { "mfpgpr", MASK_MFPGPR
, false, true },
27190 { "mulhw", MASK_MULHW
, false, true },
27191 { "multiple", MASK_MULTIPLE
, false, true },
27192 { "update", MASK_NO_UPDATE
, true , true },
27193 { "popcntb", MASK_POPCNTB
, false, true },
27194 { "popcntd", MASK_POPCNTD
, false, true },
27195 { "powerpc-gfxopt", MASK_PPC_GFXOPT
, false, true },
27196 { "powerpc-gpopt", MASK_PPC_GPOPT
, false, true },
27197 { "recip-precision", MASK_RECIP_PRECISION
, false, true },
27198 { "string", MASK_STRING
, false, true },
27199 { "vsx", MASK_VSX
, false, true },
27202 { "aix64", MASK_64BIT
, false, false },
27203 { "aix32", MASK_64BIT
, true, false },
27205 { "64", MASK_64BIT
, false, false },
27206 { "32", MASK_64BIT
, true, false },
27210 { "eabi", MASK_EABI
, false, false },
27212 #ifdef MASK_LITTLE_ENDIAN
27213 { "little", MASK_LITTLE_ENDIAN
, false, false },
27214 { "big", MASK_LITTLE_ENDIAN
, true, false },
27216 #ifdef MASK_RELOCATABLE
27217 { "relocatable", MASK_RELOCATABLE
, false, false },
27219 #ifdef MASK_STRICT_ALIGN
27220 { "strict-align", MASK_STRICT_ALIGN
, false, false },
27222 { "power", MASK_POWER
, false, false },
27223 { "power2", MASK_POWER2
, false, false },
27224 { "powerpc", MASK_POWERPC
, false, false },
27225 { "soft-float", MASK_SOFT_FLOAT
, false, false },
27226 { "string", MASK_STRING
, false, false },
27229 /* Option variables that we want to support inside attribute((target)) and
27230 #pragma GCC target operations. */
27232 struct rs6000_opt_var
{
27233 const char *name
; /* option name */
27234 size_t global_offset
; /* offset of the option in global_options. */
27235 size_t target_offset
; /* offset of the option in target optiosn. */
27238 static struct rs6000_opt_var
const rs6000_opt_vars
[] =
27241 offsetof (struct gcc_options
, x_TARGET_FRIZ
),
27242 offsetof (struct cl_target_option
, x_TARGET_FRIZ
), },
27243 { "avoid-indexed-addresses",
27244 offsetof (struct gcc_options
, x_TARGET_AVOID_XFORM
),
27245 offsetof (struct cl_target_option
, x_TARGET_AVOID_XFORM
) },
27247 offsetof (struct gcc_options
, x_rs6000_paired_float
),
27248 offsetof (struct cl_target_option
, x_rs6000_paired_float
), },
27250 offsetof (struct gcc_options
, x_rs6000_default_long_calls
),
27251 offsetof (struct cl_target_option
, x_rs6000_default_long_calls
), },
27254 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27255 parsing. Return true if there were no errors. */
27258 rs6000_inner_target_options (tree args
, bool attr_p
)
27262 if (args
== NULL_TREE
)
27265 else if (TREE_CODE (args
) == STRING_CST
)
27267 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27270 while ((q
= strtok (p
, ",")) != NULL
)
27272 bool error_p
= false;
27273 bool not_valid_p
= false;
27274 const char *cpu_opt
= NULL
;
27277 if (strncmp (q
, "cpu=", 4) == 0)
27279 int cpu_index
= rs6000_cpu_name_lookup (q
+4);
27280 if (cpu_index
>= 0)
27281 rs6000_cpu_index
= cpu_index
;
27288 else if (strncmp (q
, "tune=", 5) == 0)
27290 int tune_index
= rs6000_cpu_name_lookup (q
+5);
27291 if (tune_index
>= 0)
27292 rs6000_tune_index
= tune_index
;
27302 bool invert
= false;
27306 if (strncmp (r
, "no-", 3) == 0)
27312 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
27313 if (strcmp (r
, rs6000_opt_masks
[i
].name
) == 0)
27315 int mask
= rs6000_opt_masks
[i
].mask
;
27317 if (!rs6000_opt_masks
[i
].valid_target
)
27318 not_valid_p
= true;
27322 target_flags_explicit
|= mask
;
27324 if (rs6000_opt_masks
[i
].invert
)
27328 target_flags
&= ~mask
;
27330 target_flags
|= mask
;
27335 if (error_p
&& !not_valid_p
)
27337 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
27338 if (strcmp (r
, rs6000_opt_vars
[i
].name
) == 0)
27340 size_t j
= rs6000_opt_vars
[i
].global_offset
;
27341 ((int *) &global_options
)[j
] = !invert
;
27350 const char *eprefix
, *esuffix
;
27355 eprefix
= "__attribute__((__target__(";
27360 eprefix
= "#pragma GCC target ";
27365 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt
, eprefix
,
27367 else if (not_valid_p
)
27368 error ("%s\"%s\"%s is not allowed", eprefix
, q
, esuffix
);
27370 error ("%s\"%s\"%s is invalid", eprefix
, q
, esuffix
);
27375 else if (TREE_CODE (args
) == TREE_LIST
)
27379 tree value
= TREE_VALUE (args
);
27382 bool ret2
= rs6000_inner_target_options (value
, attr_p
);
27386 args
= TREE_CHAIN (args
);
27388 while (args
!= NULL_TREE
);
27392 gcc_unreachable ();
27397 /* Print out the target options as a list for -mdebug=target. */
27400 rs6000_debug_target_options (tree args
, const char *prefix
)
27402 if (args
== NULL_TREE
)
27403 fprintf (stderr
, "%s<NULL>", prefix
);
27405 else if (TREE_CODE (args
) == STRING_CST
)
27407 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27410 while ((q
= strtok (p
, ",")) != NULL
)
27413 fprintf (stderr
, "%s\"%s\"", prefix
, q
);
27418 else if (TREE_CODE (args
) == TREE_LIST
)
27422 tree value
= TREE_VALUE (args
);
27425 rs6000_debug_target_options (value
, prefix
);
27428 args
= TREE_CHAIN (args
);
27430 while (args
!= NULL_TREE
);
27434 gcc_unreachable ();
27440 /* Hook to validate attribute((target("..."))). */
27443 rs6000_valid_attribute_p (tree fndecl
,
27444 tree
ARG_UNUSED (name
),
27448 struct cl_target_option cur_target
;
27450 tree old_optimize
= build_optimization_node ();
27451 tree new_target
, new_optimize
;
27452 tree func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27454 gcc_assert ((fndecl
!= NULL_TREE
) && (args
!= NULL_TREE
));
27456 if (TARGET_DEBUG_TARGET
)
27458 tree tname
= DECL_NAME (fndecl
);
27459 fprintf (stderr
, "\n==================== rs6000_valid_attribute_p:\n");
27461 fprintf (stderr
, "function: %.*s\n",
27462 (int) IDENTIFIER_LENGTH (tname
),
27463 IDENTIFIER_POINTER (tname
));
27465 fprintf (stderr
, "function: unknown\n");
27467 fprintf (stderr
, "args:");
27468 rs6000_debug_target_options (args
, " ");
27469 fprintf (stderr
, "\n");
27472 fprintf (stderr
, "flags: 0x%x\n", flags
);
27474 fprintf (stderr
, "--------------------\n");
27477 old_optimize
= build_optimization_node ();
27478 func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27480 /* If the function changed the optimization levels as well as setting target
27481 options, start with the optimizations specified. */
27482 if (func_optimize
&& func_optimize
!= old_optimize
)
27483 cl_optimization_restore (&global_options
,
27484 TREE_OPTIMIZATION (func_optimize
));
27486 /* The target attributes may also change some optimization flags, so update
27487 the optimization options if necessary. */
27488 cl_target_option_save (&cur_target
, &global_options
);
27489 rs6000_cpu_index
= rs6000_tune_index
= -1;
27490 ret
= rs6000_inner_target_options (args
, true);
27492 /* Set up any additional state. */
27495 ret
= rs6000_option_override_internal (false);
27496 new_target
= build_target_option_node ();
27501 new_optimize
= build_optimization_node ();
27508 DECL_FUNCTION_SPECIFIC_TARGET (fndecl
) = new_target
;
27510 if (old_optimize
!= new_optimize
)
27511 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
) = new_optimize
;
27514 cl_target_option_restore (&global_options
, &cur_target
);
27516 if (old_optimize
!= new_optimize
)
27517 cl_optimization_restore (&global_options
,
27518 TREE_OPTIMIZATION (old_optimize
));
27524 /* Hook to validate the current #pragma GCC target and set the state, and
27525 update the macros based on what was changed. If ARGS is NULL, then
27526 POP_TARGET is used to reset the options. */
27529 rs6000_pragma_target_parse (tree args
, tree pop_target
)
27534 if (TARGET_DEBUG_TARGET
)
27536 fprintf (stderr
, "\n==================== rs6000_pragma_target_parse\n");
27537 fprintf (stderr
, "args:");
27538 rs6000_debug_target_options (args
, " ");
27539 fprintf (stderr
, "\n");
27543 fprintf (stderr
, "pop_target:\n");
27544 debug_tree (pop_target
);
27547 fprintf (stderr
, "pop_target: <NULL>\n");
27549 fprintf (stderr
, "--------------------\n");
27555 cur_tree
= ((pop_target
)
27557 : target_option_default_node
);
27558 cl_target_option_restore (&global_options
,
27559 TREE_TARGET_OPTION (cur_tree
));
27563 rs6000_cpu_index
= rs6000_tune_index
= -1;
27564 ret
= rs6000_inner_target_options (args
, false);
27565 cur_tree
= build_target_option_node ();
27572 target_option_current_node
= cur_tree
;
27578 /* Remember the last target of rs6000_set_current_function. */
27579 static GTY(()) tree rs6000_previous_fndecl
;
27581 /* Establish appropriate back-end context for processing the function
27582 FNDECL. The argument might be NULL to indicate processing at top
27583 level, outside of any function scope. */
27585 rs6000_set_current_function (tree fndecl
)
27587 tree old_tree
= (rs6000_previous_fndecl
27588 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl
)
27591 tree new_tree
= (fndecl
27592 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl
)
27595 if (TARGET_DEBUG_TARGET
)
27597 bool print_final
= false;
27598 fprintf (stderr
, "\n==================== rs6000_set_current_function");
27601 fprintf (stderr
, ", fndecl %s (%p)",
27602 (DECL_NAME (fndecl
)
27603 ? IDENTIFIER_POINTER (DECL_NAME (fndecl
))
27604 : "<unknown>"), (void *)fndecl
);
27606 if (rs6000_previous_fndecl
)
27607 fprintf (stderr
, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl
);
27609 fprintf (stderr
, "\n");
27612 fprintf (stderr
, "\nnew fndecl target specific options:\n");
27613 debug_tree (new_tree
);
27614 print_final
= true;
27619 fprintf (stderr
, "\nold fndecl target specific options:\n");
27620 debug_tree (old_tree
);
27621 print_final
= true;
27625 fprintf (stderr
, "--------------------\n");
27628 /* Only change the context if the function changes. This hook is called
27629 several times in the course of compiling a function, and we don't want to
27630 slow things down too much or call target_reinit when it isn't safe. */
27631 if (fndecl
&& fndecl
!= rs6000_previous_fndecl
)
27633 rs6000_previous_fndecl
= fndecl
;
27634 if (old_tree
== new_tree
)
27639 cl_target_option_restore (&global_options
,
27640 TREE_TARGET_OPTION (new_tree
));
27646 struct cl_target_option
*def
27647 = TREE_TARGET_OPTION (target_option_current_node
);
27649 cl_target_option_restore (&global_options
, def
);
27656 /* Save the current options */
27659 rs6000_function_specific_save (struct cl_target_option
*ptr
)
27661 ptr
->rs6000_target_flags_explicit
= target_flags_explicit
;
27664 /* Restore the current options */
27667 rs6000_function_specific_restore (struct cl_target_option
*ptr
)
27669 target_flags_explicit
= ptr
->rs6000_target_flags_explicit
;
27670 (void) rs6000_option_override_internal (false);
27673 /* Print the current options */
27676 rs6000_function_specific_print (FILE *file
, int indent
,
27677 struct cl_target_option
*ptr
)
27680 int flags
= ptr
->x_target_flags
;
27682 /* Print the various mask options. */
27683 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
27684 if ((flags
& rs6000_opt_masks
[i
].mask
) != 0)
27686 flags
&= ~ rs6000_opt_masks
[i
].mask
;
27687 fprintf (file
, "%*s-m%s%s\n", indent
, "",
27688 rs6000_opt_masks
[i
].invert
? "no-" : "",
27689 rs6000_opt_masks
[i
].name
);
27692 /* Print the various options that are variables. */
27693 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
27695 size_t j
= rs6000_opt_vars
[i
].target_offset
;
27696 if (((signed char *) ptr
)[j
])
27697 fprintf (file
, "%*s-m%s\n", indent
, "",
27698 rs6000_opt_vars
[i
].name
);
27703 /* Hook to determine if one function can safely inline another. */
27706 rs6000_can_inline_p (tree caller
, tree callee
)
27709 tree caller_tree
= DECL_FUNCTION_SPECIFIC_TARGET (caller
);
27710 tree callee_tree
= DECL_FUNCTION_SPECIFIC_TARGET (callee
);
27712 /* If callee has no option attributes, then it is ok to inline. */
27716 /* If caller has no option attributes, but callee does then it is not ok to
27718 else if (!caller_tree
)
27723 struct cl_target_option
*caller_opts
= TREE_TARGET_OPTION (caller_tree
);
27724 struct cl_target_option
*callee_opts
= TREE_TARGET_OPTION (callee_tree
);
27726 /* Callee's options should a subset of the caller's, i.e. a vsx function
27727 can inline an altivec function but a non-vsx function can't inline a
27729 if ((caller_opts
->x_target_flags
& callee_opts
->x_target_flags
)
27730 == callee_opts
->x_target_flags
)
27734 if (TARGET_DEBUG_TARGET
)
27735 fprintf (stderr
, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
27736 (DECL_NAME (caller
)
27737 ? IDENTIFIER_POINTER (DECL_NAME (caller
))
27739 (DECL_NAME (callee
)
27740 ? IDENTIFIER_POINTER (DECL_NAME (callee
))
27742 (ret
? "can" : "cannot"));
27747 /* Allocate a stack temp and fixup the address so it meets the particular
27748 memory requirements (either offetable or REG+REG addressing). */
27751 rs6000_allocate_stack_temp (enum machine_mode mode
,
27752 bool offsettable_p
,
27755 rtx stack
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
27756 rtx addr
= XEXP (stack
, 0);
27757 int strict_p
= (reload_in_progress
|| reload_completed
);
27759 if (!legitimate_indirect_address_p (addr
, strict_p
))
27762 && !rs6000_legitimate_offset_address_p (mode
, addr
, strict_p
))
27763 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
27765 else if (reg_reg_p
&& !legitimate_indexed_address_p (addr
, strict_p
))
27766 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
27772 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27773 to such a form to deal with memory reference instructions like STFIWX that
27774 only take reg+reg addressing. */
27777 rs6000_address_for_fpconvert (rtx x
)
27779 int strict_p
= (reload_in_progress
|| reload_completed
);
27782 gcc_assert (MEM_P (x
));
27783 addr
= XEXP (x
, 0);
27784 if (! legitimate_indirect_address_p (addr
, strict_p
)
27785 && ! legitimate_indexed_address_p (addr
, strict_p
))
27787 if (GET_CODE (addr
) == PRE_INC
|| GET_CODE (addr
) == PRE_DEC
)
27789 rtx reg
= XEXP (addr
, 0);
27790 HOST_WIDE_INT size
= GET_MODE_SIZE (GET_MODE (x
));
27791 rtx size_rtx
= GEN_INT ((GET_CODE (addr
) == PRE_DEC
) ? -size
: size
);
27792 gcc_assert (REG_P (reg
));
27793 emit_insn (gen_add3_insn (reg
, reg
, size_rtx
));
27796 else if (GET_CODE (addr
) == PRE_MODIFY
)
27798 rtx reg
= XEXP (addr
, 0);
27799 rtx expr
= XEXP (addr
, 1);
27800 gcc_assert (REG_P (reg
));
27801 gcc_assert (GET_CODE (expr
) == PLUS
);
27802 emit_insn (gen_add3_insn (reg
, XEXP (expr
, 0), XEXP (expr
, 1)));
27806 x
= replace_equiv_address (x
, copy_addr_to_reg (addr
));
27812 /* Given a memory reference, if it is not in the form for altivec memory
27813 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
27814 convert to the altivec format. */
27817 rs6000_address_for_altivec (rtx x
)
27819 gcc_assert (MEM_P (x
));
27820 if (!altivec_indexed_or_indirect_operand (x
, GET_MODE (x
)))
27822 rtx addr
= XEXP (x
, 0);
27823 int strict_p
= (reload_in_progress
|| reload_completed
);
27825 if (!legitimate_indexed_address_p (addr
, strict_p
)
27826 && !legitimate_indirect_address_p (addr
, strict_p
))
27827 addr
= copy_to_mode_reg (Pmode
, addr
);
27829 addr
= gen_rtx_AND (Pmode
, addr
, GEN_INT (-16));
27830 x
= change_address (x
, GET_MODE (x
), addr
);
27836 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
27838 On the RS/6000, all integer constants are acceptable, most won't be valid
27839 for particular insns, though. Only easy FP constants are acceptable. */
27842 rs6000_legitimate_constant_p (enum machine_mode mode
, rtx x
)
27844 if (rs6000_tls_referenced_p (x
))
27847 return ((GET_CODE (x
) != CONST_DOUBLE
&& GET_CODE (x
) != CONST_VECTOR
)
27848 || GET_MODE (x
) == VOIDmode
27849 || (TARGET_POWERPC64
&& mode
== DImode
)
27850 || easy_fp_constant (x
, mode
)
27851 || easy_vector_constant (x
, mode
));
27855 /* A function pointer under AIX is a pointer to a data area whose first word
27856 contains the actual address of the function, whose second word contains a
27857 pointer to its TOC, and whose third word contains a value to place in the
27858 static chain register (r11). Note that if we load the static chain, our
27859 "trampoline" need not have any executable code. */
27862 rs6000_call_indirect_aix (rtx value
, rtx func_desc
, rtx flag
)
27868 rtx stack_toc_offset
;
27870 rtx func_toc_offset
;
27872 rtx func_sc_offset
;
27875 rtx (*call_func
) (rtx
, rtx
, rtx
, rtx
);
27876 rtx (*call_value_func
) (rtx
, rtx
, rtx
, rtx
, rtx
);
27878 stack_ptr
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
27879 toc_reg
= gen_rtx_REG (Pmode
, TOC_REGNUM
);
27881 /* Load up address of the actual function. */
27882 func_desc
= force_reg (Pmode
, func_desc
);
27883 func_addr
= gen_reg_rtx (Pmode
);
27884 emit_move_insn (func_addr
, gen_rtx_MEM (Pmode
, func_desc
));
27889 stack_toc_offset
= GEN_INT (TOC_SAVE_OFFSET_32BIT
);
27890 func_toc_offset
= GEN_INT (AIX_FUNC_DESC_TOC_32BIT
);
27891 func_sc_offset
= GEN_INT (AIX_FUNC_DESC_SC_32BIT
);
27892 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS
)
27894 call_func
= gen_call_indirect_aix32bit
;
27895 call_value_func
= gen_call_value_indirect_aix32bit
;
27899 call_func
= gen_call_indirect_aix32bit_nor11
;
27900 call_value_func
= gen_call_value_indirect_aix32bit_nor11
;
27905 stack_toc_offset
= GEN_INT (TOC_SAVE_OFFSET_64BIT
);
27906 func_toc_offset
= GEN_INT (AIX_FUNC_DESC_TOC_64BIT
);
27907 func_sc_offset
= GEN_INT (AIX_FUNC_DESC_SC_64BIT
);
27908 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS
)
27910 call_func
= gen_call_indirect_aix64bit
;
27911 call_value_func
= gen_call_value_indirect_aix64bit
;
27915 call_func
= gen_call_indirect_aix64bit_nor11
;
27916 call_value_func
= gen_call_value_indirect_aix64bit_nor11
;
27920 /* Reserved spot to store the TOC. */
27921 stack_toc_mem
= gen_frame_mem (Pmode
,
27922 gen_rtx_PLUS (Pmode
,
27924 stack_toc_offset
));
27927 gcc_assert (cfun
->machine
);
27929 /* Can we optimize saving the TOC in the prologue or do we need to do it at
27931 if (TARGET_SAVE_TOC_INDIRECT
&& !cfun
->calls_alloca
)
27932 cfun
->machine
->save_toc_in_prologue
= true;
27936 MEM_VOLATILE_P (stack_toc_mem
) = 1;
27937 emit_move_insn (stack_toc_mem
, toc_reg
);
27940 /* Calculate the address to load the TOC of the called function. We don't
27941 actually load this until the split after reload. */
27942 func_toc_mem
= gen_rtx_MEM (Pmode
,
27943 gen_rtx_PLUS (Pmode
,
27947 /* If we have a static chain, load it up. */
27948 if (TARGET_POINTERS_TO_NESTED_FUNCTIONS
)
27950 func_sc_mem
= gen_rtx_MEM (Pmode
,
27951 gen_rtx_PLUS (Pmode
,
27955 sc_reg
= gen_rtx_REG (Pmode
, STATIC_CHAIN_REGNUM
);
27956 emit_move_insn (sc_reg
, func_sc_mem
);
27959 /* Create the call. */
27961 insn
= call_value_func (value
, func_addr
, flag
, func_toc_mem
,
27964 insn
= call_func (func_addr
, flag
, func_toc_mem
, stack_toc_mem
);
27966 emit_call_insn (insn
);
27969 /* Return whether we need to always update the saved TOC pointer when we update
27970 the stack pointer. */
27973 rs6000_save_toc_in_prologue_p (void)
27975 return (cfun
&& cfun
->machine
&& cfun
->machine
->save_toc_in_prologue
);
27978 #ifdef HAVE_GAS_HIDDEN
27979 # define USE_HIDDEN_LINKONCE 1
27981 # define USE_HIDDEN_LINKONCE 0
27984 /* Fills in the label name that should be used for a 476 link stack thunk. */
27987 get_ppc476_thunk_name (char name
[32])
27989 gcc_assert (TARGET_LINK_STACK
);
27991 if (USE_HIDDEN_LINKONCE
)
27992 sprintf (name
, "__ppc476.get_thunk");
27994 ASM_GENERATE_INTERNAL_LABEL (name
, "LPPC476_", 0);
27997 /* This function emits the simple thunk routine that is used to preserve
27998 the link stack on the 476 cpu. */
28001 rs6000_code_end (void)
28006 if (!TARGET_LINK_STACK
)
28009 get_ppc476_thunk_name (name
);
28011 decl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
, get_identifier (name
),
28012 build_function_type_list (void_type_node
, NULL_TREE
));
28013 DECL_RESULT (decl
) = build_decl (BUILTINS_LOCATION
, RESULT_DECL
,
28014 NULL_TREE
, void_type_node
);
28015 TREE_PUBLIC (decl
) = 1;
28016 TREE_STATIC (decl
) = 1;
28018 if (USE_HIDDEN_LINKONCE
)
28020 DECL_COMDAT_GROUP (decl
) = DECL_ASSEMBLER_NAME (decl
);
28021 targetm
.asm_out
.unique_section (decl
, 0);
28022 switch_to_section (get_named_section (decl
, NULL
, 0));
28023 DECL_WEAK (decl
) = 1;
28024 ASM_WEAKEN_DECL (asm_out_file
, decl
, name
, 0);
28025 targetm
.asm_out
.globalize_label (asm_out_file
, name
);
28026 targetm
.asm_out
.assemble_visibility (decl
, VISIBILITY_HIDDEN
);
28027 ASM_DECLARE_FUNCTION_NAME (asm_out_file
, name
, decl
);
28031 switch_to_section (text_section
);
28032 ASM_OUTPUT_LABEL (asm_out_file
, name
);
28035 DECL_INITIAL (decl
) = make_node (BLOCK
);
28036 current_function_decl
= decl
;
28037 init_function_start (decl
);
28038 first_function_block_is_cold
= false;
28039 /* Make sure unwind info is emitted for the thunk if needed. */
28040 final_start_function (emit_barrier (), asm_out_file
, 1);
28042 fputs ("\tblr\n", asm_out_file
);
28044 final_end_function ();
28045 init_insn_lengths ();
28046 free_after_compilation (cfun
);
28048 current_function_decl
= NULL
;
28051 struct gcc_target targetm
= TARGET_INITIALIZER
;
28053 #include "gt-rs6000.h"