1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
55 #include "sched-int.h"
57 #include "tree-flow.h"
60 #include "tm-constrs.h"
63 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
66 #include "gstab.h" /* for N_SLINE */
69 #ifndef TARGET_NO_PROTOTYPE
70 #define TARGET_NO_PROTOTYPE 0
73 #define min(A,B) ((A) < (B) ? (A) : (B))
74 #define max(A,B) ((A) > (B) ? (A) : (B))
76 /* Structure used to define the rs6000 stack */
77 typedef struct rs6000_stack
{
78 int reload_completed
; /* stack info won't change from here on */
79 int first_gp_reg_save
; /* first callee saved GP register used */
80 int first_fp_reg_save
; /* first callee saved FP register used */
81 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
82 int lr_save_p
; /* true if the link reg needs to be saved */
83 int cr_save_p
; /* true if the CR reg needs to be saved */
84 unsigned int vrsave_mask
; /* mask of vec registers to save */
85 int push_p
; /* true if we need to allocate stack space */
86 int calls_p
; /* true if the function makes any calls */
87 int world_save_p
; /* true if we're saving *everything*:
88 r13-r31, cr, f14-f31, vrsave, v20-v31 */
89 enum rs6000_abi abi
; /* which ABI to use */
90 int gp_save_offset
; /* offset to save GP regs from initial SP */
91 int fp_save_offset
; /* offset to save FP regs from initial SP */
92 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
93 int lr_save_offset
; /* offset to save LR from initial SP */
94 int cr_save_offset
; /* offset to save CR from initial SP */
95 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
96 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
97 int varargs_save_offset
; /* offset to save the varargs registers */
98 int ehrd_offset
; /* offset to EH return data */
99 int reg_size
; /* register size (4 or 8) */
100 HOST_WIDE_INT vars_size
; /* variable save area size */
101 int parm_size
; /* outgoing parameter size */
102 int save_size
; /* save area size */
103 int fixed_size
; /* fixed size of stack frame */
104 int gp_size
; /* size of saved GP registers */
105 int fp_size
; /* size of saved FP registers */
106 int altivec_size
; /* size of saved AltiVec registers */
107 int cr_size
; /* size to hold CR if not in save_size */
108 int vrsave_size
; /* size to hold VRSAVE if not in save_size */
109 int altivec_padding_size
; /* size of altivec alignment padding if
111 int spe_gp_size
; /* size of 64-bit GPR save size for SPE */
112 int spe_padding_size
;
113 HOST_WIDE_INT total_size
; /* total bytes allocated for stack */
114 int spe_64bit_regs_used
;
118 /* A C structure for machine-specific, per-function data.
119 This is added to the cfun structure. */
120 typedef struct GTY(()) machine_function
122 /* Some local-dynamic symbol. */
123 const char *some_ld_name
;
124 /* Whether the instruction chain has been scanned already. */
125 int insn_chain_scanned_p
;
126 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
127 int ra_needs_full_frame
;
128 /* Flags if __builtin_return_address (0) was used. */
130 /* Cache lr_save_p after expansion of builtin_eh_return. */
132 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
133 varargs save area. */
134 HOST_WIDE_INT varargs_save_offset
;
135 /* Temporary stack slot to use for SDmode copies. This slot is
136 64-bits wide and is allocated early enough so that the offset
137 does not overflow the 16-bit load/store offset field. */
138 rtx sdmode_stack_slot
;
141 /* Target cpu type */
143 struct rs6000_cpu_select rs6000_select
[3] =
145 /* switch name, tune arch */
146 { (const char *)0, "--with-cpu=", 1, 1 },
147 { (const char *)0, "-mcpu=", 1, 1 },
148 { (const char *)0, "-mtune=", 1, 0 },
151 /* Support targetm.vectorize.builtin_mask_for_load. */
152 static GTY(()) tree altivec_builtin_mask_for_load
;
154 /* Set to nonzero once AIX common-mode calls have been defined. */
155 static GTY(()) int common_mode_defined
;
157 /* Label number of label created for -mrelocatable, to call to so we can
158 get the address of the GOT section */
159 static int rs6000_pic_labelno
;
162 /* Counter for labels which are to be placed in .fixup. */
163 int fixuplabelno
= 0;
166 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
169 /* Specify the machine mode that pointers have. After generation of rtl, the
170 compiler makes no further distinction between pointers and any other objects
171 of this machine mode. The type is unsigned since not all things that
172 include rs6000.h also include machmode.h. */
173 unsigned rs6000_pmode
;
175 /* Width in bits of a pointer. */
176 unsigned rs6000_pointer_size
;
178 #ifdef HAVE_AS_GNU_ATTRIBUTE
179 /* Flag whether floating point values have been passed/returned. */
180 static bool rs6000_passes_float
;
181 /* Flag whether vector values have been passed/returned. */
182 static bool rs6000_passes_vector
;
183 /* Flag whether small (<= 8 byte) structures have been returned. */
184 static bool rs6000_returns_struct
;
187 /* Value is TRUE if register/mode pair is acceptable. */
188 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
190 /* Maximum number of registers needed for a given register class and mode. */
191 unsigned char rs6000_class_max_nregs
[NUM_MACHINE_MODES
][LIM_REG_CLASSES
];
193 /* How many registers are needed for a given register and mode. */
194 unsigned char rs6000_hard_regno_nregs
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
196 /* Map register number to register class. */
197 enum reg_class rs6000_regno_regclass
[FIRST_PSEUDO_REGISTER
];
199 /* Reload functions based on the type and the vector unit. */
200 static enum insn_code rs6000_vector_reload
[NUM_MACHINE_MODES
][2];
202 /* Built in types. */
203 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
204 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
206 /* Flag to say the TOC is initialized */
208 char toc_label_name
[10];
210 /* Cached value of rs6000_variable_issue. This is cached in
211 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
212 static short cached_can_issue_more
;
214 static GTY(()) section
*read_only_data_section
;
215 static GTY(()) section
*private_data_section
;
216 static GTY(()) section
*read_only_private_data_section
;
217 static GTY(()) section
*sdata2_section
;
218 static GTY(()) section
*toc_section
;
220 struct builtin_description
222 /* mask is not const because we're going to alter it below. This
223 nonsense will go away when we rewrite the -march infrastructure
224 to give us more target flag bits. */
226 const enum insn_code icode
;
227 const char *const name
;
228 const enum rs6000_builtins code
;
231 /* Describe the vector unit used for modes. */
232 enum rs6000_vector rs6000_vector_unit
[NUM_MACHINE_MODES
];
233 enum rs6000_vector rs6000_vector_mem
[NUM_MACHINE_MODES
];
235 /* Register classes for various constraints that are based on the target
237 enum reg_class rs6000_constraints
[RS6000_CONSTRAINT_MAX
];
239 /* Describe the alignment of a vector. */
240 int rs6000_vector_align
[NUM_MACHINE_MODES
];
242 /* Map selected modes to types for builtins. */
243 static GTY(()) tree builtin_mode_to_type
[MAX_MACHINE_MODE
][2];
245 /* What modes to automatically generate reciprocal divide estimate (fre) and
246 reciprocal sqrt (frsqrte) for. */
247 unsigned char rs6000_recip_bits
[MAX_MACHINE_MODE
];
249 /* Masks to determine which reciprocal esitmate instructions to generate
251 enum rs6000_recip_mask
{
252 RECIP_SF_DIV
= 0x001, /* Use divide estimate */
253 RECIP_DF_DIV
= 0x002,
254 RECIP_V4SF_DIV
= 0x004,
255 RECIP_V2DF_DIV
= 0x008,
257 RECIP_SF_RSQRT
= 0x010, /* Use reciprocal sqrt estimate. */
258 RECIP_DF_RSQRT
= 0x020,
259 RECIP_V4SF_RSQRT
= 0x040,
260 RECIP_V2DF_RSQRT
= 0x080,
262 /* Various combination of flags for -mrecip=xxx. */
264 RECIP_ALL
= (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
265 | RECIP_V2DF_DIV
| RECIP_SF_RSQRT
| RECIP_DF_RSQRT
266 | RECIP_V4SF_RSQRT
| RECIP_V2DF_RSQRT
),
268 RECIP_HIGH_PRECISION
= RECIP_ALL
,
270 /* On low precision machines like the power5, don't enable double precision
271 reciprocal square root estimate, since it isn't accurate enough. */
272 RECIP_LOW_PRECISION
= (RECIP_ALL
& ~(RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
))
275 /* -mrecip options. */
278 const char *string
; /* option name */
279 unsigned int mask
; /* mask bits to set */
280 } recip_options
[] = {
281 { "all", RECIP_ALL
},
282 { "none", RECIP_NONE
},
283 { "div", (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
285 { "divf", (RECIP_SF_DIV
| RECIP_V4SF_DIV
) },
286 { "divd", (RECIP_DF_DIV
| RECIP_V2DF_DIV
) },
287 { "rsqrt", (RECIP_SF_RSQRT
| RECIP_DF_RSQRT
| RECIP_V4SF_RSQRT
288 | RECIP_V2DF_RSQRT
) },
289 { "rsqrtf", (RECIP_SF_RSQRT
| RECIP_V4SF_RSQRT
) },
290 { "rsqrtd", (RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
) },
293 /* 2 argument gen function typedef. */
294 typedef rtx (*gen_2arg_fn_t
) (rtx
, rtx
, rtx
);
297 /* Target cpu costs. */
299 struct processor_costs
{
300 const int mulsi
; /* cost of SImode multiplication. */
301 const int mulsi_const
; /* cost of SImode multiplication by constant. */
302 const int mulsi_const9
; /* cost of SImode mult by short constant. */
303 const int muldi
; /* cost of DImode multiplication. */
304 const int divsi
; /* cost of SImode division. */
305 const int divdi
; /* cost of DImode division. */
306 const int fp
; /* cost of simple SFmode and DFmode insns. */
307 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
308 const int sdiv
; /* cost of SFmode division (fdivs). */
309 const int ddiv
; /* cost of DFmode division (fdiv). */
310 const int cache_line_size
; /* cache line size in bytes. */
311 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
312 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
313 const int simultaneous_prefetches
; /* number of parallel prefetch
317 const struct processor_costs
*rs6000_cost
;
319 /* Processor costs (relative to an add) */
321 /* Instruction size costs on 32bit processors. */
323 struct processor_costs size32_cost
= {
324 COSTS_N_INSNS (1), /* mulsi */
325 COSTS_N_INSNS (1), /* mulsi_const */
326 COSTS_N_INSNS (1), /* mulsi_const9 */
327 COSTS_N_INSNS (1), /* muldi */
328 COSTS_N_INSNS (1), /* divsi */
329 COSTS_N_INSNS (1), /* divdi */
330 COSTS_N_INSNS (1), /* fp */
331 COSTS_N_INSNS (1), /* dmul */
332 COSTS_N_INSNS (1), /* sdiv */
333 COSTS_N_INSNS (1), /* ddiv */
340 /* Instruction size costs on 64bit processors. */
342 struct processor_costs size64_cost
= {
343 COSTS_N_INSNS (1), /* mulsi */
344 COSTS_N_INSNS (1), /* mulsi_const */
345 COSTS_N_INSNS (1), /* mulsi_const9 */
346 COSTS_N_INSNS (1), /* muldi */
347 COSTS_N_INSNS (1), /* divsi */
348 COSTS_N_INSNS (1), /* divdi */
349 COSTS_N_INSNS (1), /* fp */
350 COSTS_N_INSNS (1), /* dmul */
351 COSTS_N_INSNS (1), /* sdiv */
352 COSTS_N_INSNS (1), /* ddiv */
359 /* Instruction costs on RIOS1 processors. */
361 struct processor_costs rios1_cost
= {
362 COSTS_N_INSNS (5), /* mulsi */
363 COSTS_N_INSNS (4), /* mulsi_const */
364 COSTS_N_INSNS (3), /* mulsi_const9 */
365 COSTS_N_INSNS (5), /* muldi */
366 COSTS_N_INSNS (19), /* divsi */
367 COSTS_N_INSNS (19), /* divdi */
368 COSTS_N_INSNS (2), /* fp */
369 COSTS_N_INSNS (2), /* dmul */
370 COSTS_N_INSNS (19), /* sdiv */
371 COSTS_N_INSNS (19), /* ddiv */
372 128, /* cache line size */
378 /* Instruction costs on RIOS2 processors. */
380 struct processor_costs rios2_cost
= {
381 COSTS_N_INSNS (2), /* mulsi */
382 COSTS_N_INSNS (2), /* mulsi_const */
383 COSTS_N_INSNS (2), /* mulsi_const9 */
384 COSTS_N_INSNS (2), /* muldi */
385 COSTS_N_INSNS (13), /* divsi */
386 COSTS_N_INSNS (13), /* divdi */
387 COSTS_N_INSNS (2), /* fp */
388 COSTS_N_INSNS (2), /* dmul */
389 COSTS_N_INSNS (17), /* sdiv */
390 COSTS_N_INSNS (17), /* ddiv */
391 256, /* cache line size */
397 /* Instruction costs on RS64A processors. */
399 struct processor_costs rs64a_cost
= {
400 COSTS_N_INSNS (20), /* mulsi */
401 COSTS_N_INSNS (12), /* mulsi_const */
402 COSTS_N_INSNS (8), /* mulsi_const9 */
403 COSTS_N_INSNS (34), /* muldi */
404 COSTS_N_INSNS (65), /* divsi */
405 COSTS_N_INSNS (67), /* divdi */
406 COSTS_N_INSNS (4), /* fp */
407 COSTS_N_INSNS (4), /* dmul */
408 COSTS_N_INSNS (31), /* sdiv */
409 COSTS_N_INSNS (31), /* ddiv */
410 128, /* cache line size */
416 /* Instruction costs on MPCCORE processors. */
418 struct processor_costs mpccore_cost
= {
419 COSTS_N_INSNS (2), /* mulsi */
420 COSTS_N_INSNS (2), /* mulsi_const */
421 COSTS_N_INSNS (2), /* mulsi_const9 */
422 COSTS_N_INSNS (2), /* muldi */
423 COSTS_N_INSNS (6), /* divsi */
424 COSTS_N_INSNS (6), /* divdi */
425 COSTS_N_INSNS (4), /* fp */
426 COSTS_N_INSNS (5), /* dmul */
427 COSTS_N_INSNS (10), /* sdiv */
428 COSTS_N_INSNS (17), /* ddiv */
429 32, /* cache line size */
435 /* Instruction costs on PPC403 processors. */
437 struct processor_costs ppc403_cost
= {
438 COSTS_N_INSNS (4), /* mulsi */
439 COSTS_N_INSNS (4), /* mulsi_const */
440 COSTS_N_INSNS (4), /* mulsi_const9 */
441 COSTS_N_INSNS (4), /* muldi */
442 COSTS_N_INSNS (33), /* divsi */
443 COSTS_N_INSNS (33), /* divdi */
444 COSTS_N_INSNS (11), /* fp */
445 COSTS_N_INSNS (11), /* dmul */
446 COSTS_N_INSNS (11), /* sdiv */
447 COSTS_N_INSNS (11), /* ddiv */
448 32, /* cache line size */
454 /* Instruction costs on PPC405 processors. */
456 struct processor_costs ppc405_cost
= {
457 COSTS_N_INSNS (5), /* mulsi */
458 COSTS_N_INSNS (4), /* mulsi_const */
459 COSTS_N_INSNS (3), /* mulsi_const9 */
460 COSTS_N_INSNS (5), /* muldi */
461 COSTS_N_INSNS (35), /* divsi */
462 COSTS_N_INSNS (35), /* divdi */
463 COSTS_N_INSNS (11), /* fp */
464 COSTS_N_INSNS (11), /* dmul */
465 COSTS_N_INSNS (11), /* sdiv */
466 COSTS_N_INSNS (11), /* ddiv */
467 32, /* cache line size */
473 /* Instruction costs on PPC440 processors. */
475 struct processor_costs ppc440_cost
= {
476 COSTS_N_INSNS (3), /* mulsi */
477 COSTS_N_INSNS (2), /* mulsi_const */
478 COSTS_N_INSNS (2), /* mulsi_const9 */
479 COSTS_N_INSNS (3), /* muldi */
480 COSTS_N_INSNS (34), /* divsi */
481 COSTS_N_INSNS (34), /* divdi */
482 COSTS_N_INSNS (5), /* fp */
483 COSTS_N_INSNS (5), /* dmul */
484 COSTS_N_INSNS (19), /* sdiv */
485 COSTS_N_INSNS (33), /* ddiv */
486 32, /* cache line size */
492 /* Instruction costs on PPC476 processors. */
494 struct processor_costs ppc476_cost
= {
495 COSTS_N_INSNS (4), /* mulsi */
496 COSTS_N_INSNS (4), /* mulsi_const */
497 COSTS_N_INSNS (4), /* mulsi_const9 */
498 COSTS_N_INSNS (4), /* muldi */
499 COSTS_N_INSNS (11), /* divsi */
500 COSTS_N_INSNS (11), /* divdi */
501 COSTS_N_INSNS (6), /* fp */
502 COSTS_N_INSNS (6), /* dmul */
503 COSTS_N_INSNS (19), /* sdiv */
504 COSTS_N_INSNS (33), /* ddiv */
505 32, /* l1 cache line size */
511 /* Instruction costs on PPC601 processors. */
513 struct processor_costs ppc601_cost
= {
514 COSTS_N_INSNS (5), /* mulsi */
515 COSTS_N_INSNS (5), /* mulsi_const */
516 COSTS_N_INSNS (5), /* mulsi_const9 */
517 COSTS_N_INSNS (5), /* muldi */
518 COSTS_N_INSNS (36), /* divsi */
519 COSTS_N_INSNS (36), /* divdi */
520 COSTS_N_INSNS (4), /* fp */
521 COSTS_N_INSNS (5), /* dmul */
522 COSTS_N_INSNS (17), /* sdiv */
523 COSTS_N_INSNS (31), /* ddiv */
524 32, /* cache line size */
530 /* Instruction costs on PPC603 processors. */
532 struct processor_costs ppc603_cost
= {
533 COSTS_N_INSNS (5), /* mulsi */
534 COSTS_N_INSNS (3), /* mulsi_const */
535 COSTS_N_INSNS (2), /* mulsi_const9 */
536 COSTS_N_INSNS (5), /* muldi */
537 COSTS_N_INSNS (37), /* divsi */
538 COSTS_N_INSNS (37), /* divdi */
539 COSTS_N_INSNS (3), /* fp */
540 COSTS_N_INSNS (4), /* dmul */
541 COSTS_N_INSNS (18), /* sdiv */
542 COSTS_N_INSNS (33), /* ddiv */
543 32, /* cache line size */
549 /* Instruction costs on PPC604 processors. */
551 struct processor_costs ppc604_cost
= {
552 COSTS_N_INSNS (4), /* mulsi */
553 COSTS_N_INSNS (4), /* mulsi_const */
554 COSTS_N_INSNS (4), /* mulsi_const9 */
555 COSTS_N_INSNS (4), /* muldi */
556 COSTS_N_INSNS (20), /* divsi */
557 COSTS_N_INSNS (20), /* divdi */
558 COSTS_N_INSNS (3), /* fp */
559 COSTS_N_INSNS (3), /* dmul */
560 COSTS_N_INSNS (18), /* sdiv */
561 COSTS_N_INSNS (32), /* ddiv */
562 32, /* cache line size */
568 /* Instruction costs on PPC604e processors. */
570 struct processor_costs ppc604e_cost
= {
571 COSTS_N_INSNS (2), /* mulsi */
572 COSTS_N_INSNS (2), /* mulsi_const */
573 COSTS_N_INSNS (2), /* mulsi_const9 */
574 COSTS_N_INSNS (2), /* muldi */
575 COSTS_N_INSNS (20), /* divsi */
576 COSTS_N_INSNS (20), /* divdi */
577 COSTS_N_INSNS (3), /* fp */
578 COSTS_N_INSNS (3), /* dmul */
579 COSTS_N_INSNS (18), /* sdiv */
580 COSTS_N_INSNS (32), /* ddiv */
581 32, /* cache line size */
587 /* Instruction costs on PPC620 processors. */
589 struct processor_costs ppc620_cost
= {
590 COSTS_N_INSNS (5), /* mulsi */
591 COSTS_N_INSNS (4), /* mulsi_const */
592 COSTS_N_INSNS (3), /* mulsi_const9 */
593 COSTS_N_INSNS (7), /* muldi */
594 COSTS_N_INSNS (21), /* divsi */
595 COSTS_N_INSNS (37), /* divdi */
596 COSTS_N_INSNS (3), /* fp */
597 COSTS_N_INSNS (3), /* dmul */
598 COSTS_N_INSNS (18), /* sdiv */
599 COSTS_N_INSNS (32), /* ddiv */
600 128, /* cache line size */
606 /* Instruction costs on PPC630 processors. */
608 struct processor_costs ppc630_cost
= {
609 COSTS_N_INSNS (5), /* mulsi */
610 COSTS_N_INSNS (4), /* mulsi_const */
611 COSTS_N_INSNS (3), /* mulsi_const9 */
612 COSTS_N_INSNS (7), /* muldi */
613 COSTS_N_INSNS (21), /* divsi */
614 COSTS_N_INSNS (37), /* divdi */
615 COSTS_N_INSNS (3), /* fp */
616 COSTS_N_INSNS (3), /* dmul */
617 COSTS_N_INSNS (17), /* sdiv */
618 COSTS_N_INSNS (21), /* ddiv */
619 128, /* cache line size */
625 /* Instruction costs on Cell processor. */
626 /* COSTS_N_INSNS (1) ~ one add. */
628 struct processor_costs ppccell_cost
= {
629 COSTS_N_INSNS (9/2)+2, /* mulsi */
630 COSTS_N_INSNS (6/2), /* mulsi_const */
631 COSTS_N_INSNS (6/2), /* mulsi_const9 */
632 COSTS_N_INSNS (15/2)+2, /* muldi */
633 COSTS_N_INSNS (38/2), /* divsi */
634 COSTS_N_INSNS (70/2), /* divdi */
635 COSTS_N_INSNS (10/2), /* fp */
636 COSTS_N_INSNS (10/2), /* dmul */
637 COSTS_N_INSNS (74/2), /* sdiv */
638 COSTS_N_INSNS (74/2), /* ddiv */
639 128, /* cache line size */
645 /* Instruction costs on PPC750 and PPC7400 processors. */
647 struct processor_costs ppc750_cost
= {
648 COSTS_N_INSNS (5), /* mulsi */
649 COSTS_N_INSNS (3), /* mulsi_const */
650 COSTS_N_INSNS (2), /* mulsi_const9 */
651 COSTS_N_INSNS (5), /* muldi */
652 COSTS_N_INSNS (17), /* divsi */
653 COSTS_N_INSNS (17), /* divdi */
654 COSTS_N_INSNS (3), /* fp */
655 COSTS_N_INSNS (3), /* dmul */
656 COSTS_N_INSNS (17), /* sdiv */
657 COSTS_N_INSNS (31), /* ddiv */
658 32, /* cache line size */
664 /* Instruction costs on PPC7450 processors. */
666 struct processor_costs ppc7450_cost
= {
667 COSTS_N_INSNS (4), /* mulsi */
668 COSTS_N_INSNS (3), /* mulsi_const */
669 COSTS_N_INSNS (3), /* mulsi_const9 */
670 COSTS_N_INSNS (4), /* muldi */
671 COSTS_N_INSNS (23), /* divsi */
672 COSTS_N_INSNS (23), /* divdi */
673 COSTS_N_INSNS (5), /* fp */
674 COSTS_N_INSNS (5), /* dmul */
675 COSTS_N_INSNS (21), /* sdiv */
676 COSTS_N_INSNS (35), /* ddiv */
677 32, /* cache line size */
683 /* Instruction costs on PPC8540 processors. */
685 struct processor_costs ppc8540_cost
= {
686 COSTS_N_INSNS (4), /* mulsi */
687 COSTS_N_INSNS (4), /* mulsi_const */
688 COSTS_N_INSNS (4), /* mulsi_const9 */
689 COSTS_N_INSNS (4), /* muldi */
690 COSTS_N_INSNS (19), /* divsi */
691 COSTS_N_INSNS (19), /* divdi */
692 COSTS_N_INSNS (4), /* fp */
693 COSTS_N_INSNS (4), /* dmul */
694 COSTS_N_INSNS (29), /* sdiv */
695 COSTS_N_INSNS (29), /* ddiv */
696 32, /* cache line size */
699 1, /* prefetch streams /*/
702 /* Instruction costs on E300C2 and E300C3 cores. */
704 struct processor_costs ppce300c2c3_cost
= {
705 COSTS_N_INSNS (4), /* mulsi */
706 COSTS_N_INSNS (4), /* mulsi_const */
707 COSTS_N_INSNS (4), /* mulsi_const9 */
708 COSTS_N_INSNS (4), /* muldi */
709 COSTS_N_INSNS (19), /* divsi */
710 COSTS_N_INSNS (19), /* divdi */
711 COSTS_N_INSNS (3), /* fp */
712 COSTS_N_INSNS (4), /* dmul */
713 COSTS_N_INSNS (18), /* sdiv */
714 COSTS_N_INSNS (33), /* ddiv */
718 1, /* prefetch streams /*/
721 /* Instruction costs on PPCE500MC processors. */
723 struct processor_costs ppce500mc_cost
= {
724 COSTS_N_INSNS (4), /* mulsi */
725 COSTS_N_INSNS (4), /* mulsi_const */
726 COSTS_N_INSNS (4), /* mulsi_const9 */
727 COSTS_N_INSNS (4), /* muldi */
728 COSTS_N_INSNS (14), /* divsi */
729 COSTS_N_INSNS (14), /* divdi */
730 COSTS_N_INSNS (8), /* fp */
731 COSTS_N_INSNS (10), /* dmul */
732 COSTS_N_INSNS (36), /* sdiv */
733 COSTS_N_INSNS (66), /* ddiv */
734 64, /* cache line size */
737 1, /* prefetch streams /*/
740 /* Instruction costs on PPCE500MC64 processors. */
742 struct processor_costs ppce500mc64_cost
= {
743 COSTS_N_INSNS (4), /* mulsi */
744 COSTS_N_INSNS (4), /* mulsi_const */
745 COSTS_N_INSNS (4), /* mulsi_const9 */
746 COSTS_N_INSNS (4), /* muldi */
747 COSTS_N_INSNS (14), /* divsi */
748 COSTS_N_INSNS (14), /* divdi */
749 COSTS_N_INSNS (4), /* fp */
750 COSTS_N_INSNS (10), /* dmul */
751 COSTS_N_INSNS (36), /* sdiv */
752 COSTS_N_INSNS (66), /* ddiv */
753 64, /* cache line size */
756 1, /* prefetch streams /*/
759 /* Instruction costs on AppliedMicro Titan processors. */
761 struct processor_costs titan_cost
= {
762 COSTS_N_INSNS (5), /* mulsi */
763 COSTS_N_INSNS (5), /* mulsi_const */
764 COSTS_N_INSNS (5), /* mulsi_const9 */
765 COSTS_N_INSNS (5), /* muldi */
766 COSTS_N_INSNS (18), /* divsi */
767 COSTS_N_INSNS (18), /* divdi */
768 COSTS_N_INSNS (10), /* fp */
769 COSTS_N_INSNS (10), /* dmul */
770 COSTS_N_INSNS (46), /* sdiv */
771 COSTS_N_INSNS (72), /* ddiv */
772 32, /* cache line size */
775 1, /* prefetch streams /*/
778 /* Instruction costs on POWER4 and POWER5 processors. */
780 struct processor_costs power4_cost
= {
781 COSTS_N_INSNS (3), /* mulsi */
782 COSTS_N_INSNS (2), /* mulsi_const */
783 COSTS_N_INSNS (2), /* mulsi_const9 */
784 COSTS_N_INSNS (4), /* muldi */
785 COSTS_N_INSNS (18), /* divsi */
786 COSTS_N_INSNS (34), /* divdi */
787 COSTS_N_INSNS (3), /* fp */
788 COSTS_N_INSNS (3), /* dmul */
789 COSTS_N_INSNS (17), /* sdiv */
790 COSTS_N_INSNS (17), /* ddiv */
791 128, /* cache line size */
794 8, /* prefetch streams /*/
797 /* Instruction costs on POWER6 processors. */
799 struct processor_costs power6_cost
= {
800 COSTS_N_INSNS (8), /* mulsi */
801 COSTS_N_INSNS (8), /* mulsi_const */
802 COSTS_N_INSNS (8), /* mulsi_const9 */
803 COSTS_N_INSNS (8), /* muldi */
804 COSTS_N_INSNS (22), /* divsi */
805 COSTS_N_INSNS (28), /* divdi */
806 COSTS_N_INSNS (3), /* fp */
807 COSTS_N_INSNS (3), /* dmul */
808 COSTS_N_INSNS (13), /* sdiv */
809 COSTS_N_INSNS (16), /* ddiv */
810 128, /* cache line size */
813 16, /* prefetch streams */
816 /* Instruction costs on POWER7 processors. */
818 struct processor_costs power7_cost
= {
819 COSTS_N_INSNS (2), /* mulsi */
820 COSTS_N_INSNS (2), /* mulsi_const */
821 COSTS_N_INSNS (2), /* mulsi_const9 */
822 COSTS_N_INSNS (2), /* muldi */
823 COSTS_N_INSNS (18), /* divsi */
824 COSTS_N_INSNS (34), /* divdi */
825 COSTS_N_INSNS (3), /* fp */
826 COSTS_N_INSNS (3), /* dmul */
827 COSTS_N_INSNS (13), /* sdiv */
828 COSTS_N_INSNS (16), /* ddiv */
829 128, /* cache line size */
832 12, /* prefetch streams */
835 /* Instruction costs on POWER A2 processors. */
837 struct processor_costs ppca2_cost
= {
838 COSTS_N_INSNS (16), /* mulsi */
839 COSTS_N_INSNS (16), /* mulsi_const */
840 COSTS_N_INSNS (16), /* mulsi_const9 */
841 COSTS_N_INSNS (16), /* muldi */
842 COSTS_N_INSNS (22), /* divsi */
843 COSTS_N_INSNS (28), /* divdi */
844 COSTS_N_INSNS (3), /* fp */
845 COSTS_N_INSNS (3), /* dmul */
846 COSTS_N_INSNS (59), /* sdiv */
847 COSTS_N_INSNS (72), /* ddiv */
851 16, /* prefetch streams */
855 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
856 #undef RS6000_BUILTIN
857 #undef RS6000_BUILTIN_EQUATE
858 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
859 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
861 static const enum rs6000_btc builtin_classify
[(int)RS6000_BUILTIN_COUNT
] =
863 #include "rs6000-builtin.def"
866 #undef RS6000_BUILTIN
867 #undef RS6000_BUILTIN_EQUATE
869 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
870 static tree (*rs6000_veclib_handler
) (tree
, tree
, tree
);
873 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
874 static const char *rs6000_invalid_within_doloop (const_rtx
);
875 static bool rs6000_legitimate_address_p (enum machine_mode
, rtx
, bool);
876 static bool rs6000_debug_legitimate_address_p (enum machine_mode
, rtx
, bool);
877 static rtx
rs6000_generate_compare (rtx
, enum machine_mode
);
878 static void rs6000_emit_stack_tie (void);
879 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
880 static bool spe_func_has_64bit_regs_p (void);
881 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
883 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
884 static unsigned rs6000_hash_constant (rtx
);
885 static unsigned toc_hash_function (const void *);
886 static int toc_hash_eq (const void *, const void *);
887 static bool reg_offset_addressing_ok_p (enum machine_mode
);
888 static bool virtual_stack_registers_memory_p (rtx
);
889 static bool constant_pool_expr_p (rtx
);
890 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
891 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
892 static struct machine_function
* rs6000_init_machine_status (void);
893 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
894 static bool no_global_regs_above (int, bool);
895 #ifdef HAVE_GAS_HIDDEN
896 static void rs6000_assemble_visibility (tree
, int);
898 static int rs6000_ra_ever_killed (void);
899 static bool rs6000_attribute_takes_identifier_p (const_tree
);
900 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
901 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
902 static bool rs6000_ms_bitfield_layout_p (const_tree
);
903 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
904 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
905 static const char *rs6000_mangle_type (const_tree
);
906 static void rs6000_set_default_type_attributes (tree
);
907 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
908 static rtx
rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
909 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
910 enum machine_mode
, bool, bool, bool);
911 static bool rs6000_reg_live_or_pic_offset_p (int);
912 static tree
rs6000_builtin_vectorized_libmass (tree
, tree
, tree
);
913 static tree
rs6000_builtin_vectorized_function (tree
, tree
, tree
);
914 static void rs6000_restore_saved_cr (rtx
, int);
915 static bool rs6000_output_addr_const_extra (FILE *, rtx
);
916 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
917 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
918 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
920 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
921 static bool rs6000_return_in_memory (const_tree
, const_tree
);
922 static rtx
rs6000_function_value (const_tree
, const_tree
, bool);
923 static void rs6000_file_start (void);
925 static int rs6000_elf_reloc_rw_mask (void);
926 static void rs6000_elf_asm_out_constructor (rtx
, int) ATTRIBUTE_UNUSED
;
927 static void rs6000_elf_asm_out_destructor (rtx
, int) ATTRIBUTE_UNUSED
;
928 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED
;
929 static void rs6000_elf_asm_init_sections (void);
930 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
931 unsigned HOST_WIDE_INT
);
932 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
935 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
936 static void rs6000_alloc_sdmode_stack_slot (void);
937 static void rs6000_instantiate_decls (void);
939 static void rs6000_xcoff_asm_output_anchor (rtx
);
940 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
941 static void rs6000_xcoff_asm_init_sections (void);
942 static int rs6000_xcoff_reloc_rw_mask (void);
943 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
944 static section
*rs6000_xcoff_select_section (tree
, int,
945 unsigned HOST_WIDE_INT
);
946 static void rs6000_xcoff_unique_section (tree
, int);
947 static section
*rs6000_xcoff_select_rtx_section
948 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
949 static const char * rs6000_xcoff_strip_name_encoding (const char *);
950 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
951 static void rs6000_xcoff_file_start (void);
952 static void rs6000_xcoff_file_end (void);
954 static int rs6000_variable_issue (FILE *, int, rtx
, int);
955 static int rs6000_register_move_cost (enum machine_mode
,
956 reg_class_t
, reg_class_t
);
957 static int rs6000_memory_move_cost (enum machine_mode
, reg_class_t
, bool);
958 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
959 static bool rs6000_debug_rtx_costs (rtx
, int, int, int *, bool);
960 static int rs6000_debug_address_cost (rtx
, bool);
961 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
962 static int rs6000_debug_adjust_cost (rtx
, rtx
, rtx
, int);
963 static void rs6000_sched_init (FILE *, int, int);
964 static bool is_microcoded_insn (rtx
);
965 static bool is_nonpipeline_insn (rtx
);
966 static bool is_cracked_insn (rtx
);
967 static bool is_branch_slot_insn (rtx
);
968 static bool is_load_insn (rtx
);
969 static rtx
get_store_dest (rtx pat
);
970 static bool is_store_insn (rtx
);
971 static bool set_to_load_agen (rtx
,rtx
);
972 static bool adjacent_mem_locations (rtx
,rtx
);
973 static int rs6000_adjust_priority (rtx
, int);
974 static int rs6000_issue_rate (void);
975 static bool rs6000_is_costly_dependence (dep_t
, int, int);
976 static rtx
get_next_active_insn (rtx
, rtx
);
977 static bool insn_terminates_group_p (rtx
, enum group_termination
);
978 static bool insn_must_be_first_in_group (rtx
);
979 static bool insn_must_be_last_in_group (rtx
);
980 static bool is_costly_group (rtx
*, rtx
);
981 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
982 static int redefine_groups (FILE *, int, rtx
, rtx
);
983 static int pad_groups (FILE *, int, rtx
, rtx
);
984 static void rs6000_sched_finish (FILE *, int);
985 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
986 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
987 static int rs6000_use_sched_lookahead (void);
988 static int rs6000_use_sched_lookahead_guard (rtx
);
989 static void * rs6000_alloc_sched_context (void);
990 static void rs6000_init_sched_context (void *, bool);
991 static void rs6000_set_sched_context (void *);
992 static void rs6000_free_sched_context (void *);
993 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
994 static tree
rs6000_builtin_mask_for_load (void);
995 static tree
rs6000_builtin_mul_widen_even (tree
);
996 static tree
rs6000_builtin_mul_widen_odd (tree
);
997 static tree
rs6000_builtin_conversion (unsigned int, tree
, tree
);
998 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
999 static bool rs6000_builtin_support_vector_misalignment (enum
1003 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt
,
1005 static enum machine_mode
rs6000_preferred_simd_mode (enum machine_mode
);
1007 static void def_builtin (int, const char *, tree
, int);
1008 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
1009 static void rs6000_init_builtins (void);
1010 static tree
rs6000_builtin_decl (unsigned, bool);
1012 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
1013 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
1014 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
1015 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
1016 static void altivec_init_builtins (void);
1017 static unsigned builtin_hash_function (const void *);
1018 static int builtin_hash_eq (const void *, const void *);
1019 static tree
builtin_function_type (enum machine_mode
, enum machine_mode
,
1020 enum machine_mode
, enum machine_mode
,
1021 enum rs6000_builtins
, const char *name
);
1022 static void rs6000_common_init_builtins (void);
1023 static void rs6000_init_libfuncs (void);
1025 static void paired_init_builtins (void);
1026 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
1027 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
1028 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
1029 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1031 static void enable_mask_for_builtins (struct builtin_description
*, int,
1032 enum rs6000_builtins
,
1033 enum rs6000_builtins
);
1034 static void spe_init_builtins (void);
1035 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
1036 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
1037 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1038 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
1039 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
1040 static rs6000_stack_t
*rs6000_stack_info (void);
1041 static void debug_stack_info (rs6000_stack_t
*);
1043 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
1044 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
1045 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
1046 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
1047 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
1048 static rtx
altivec_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1049 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
1050 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
1051 static rtx
altivec_expand_vec_set_builtin (tree
);
1052 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
1053 static int get_element_number (tree
, tree
);
1054 static void rs6000_option_override (void);
1055 static void rs6000_option_init_struct (struct gcc_options
*);
1056 static void rs6000_option_default_params (void);
1057 static bool rs6000_handle_option (struct gcc_options
*, struct gcc_options
*,
1058 const struct cl_decoded_option
*,
1060 static int rs6000_loop_align_max_skip (rtx
);
1061 static int first_altivec_reg_to_save (void);
1062 static unsigned int compute_vrsave_mask (void);
1063 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
1064 static void is_altivec_return_reg (rtx
, void *);
1065 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
1066 int easy_vector_constant (rtx
, enum machine_mode
);
1067 static rtx
rs6000_dwarf_register_span (rtx
);
1068 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
1069 static rtx
rs6000_legitimize_address (rtx
, rtx
, enum machine_mode
);
1070 static rtx
rs6000_debug_legitimize_address (rtx
, rtx
, enum machine_mode
);
1071 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
1072 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
1073 static rtx
rs6000_delegitimize_address (rtx
);
1074 static rtx
rs6000_tls_get_addr (void);
1075 static rtx
rs6000_got_sym (void);
1076 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
1077 static const char *rs6000_get_some_local_dynamic_name (void);
1078 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
1079 static rtx
rs6000_complex_function_value (enum machine_mode
);
1080 static rtx
rs6000_spe_function_arg (const CUMULATIVE_ARGS
*,
1081 enum machine_mode
, const_tree
);
1082 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
1083 HOST_WIDE_INT
, int);
1084 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
1087 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
1090 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
1091 const_tree
, HOST_WIDE_INT
,
1093 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, bool, bool);
1094 static rtx
rs6000_mixed_function_arg (enum machine_mode
, const_tree
, int);
1095 static void rs6000_function_arg_advance (CUMULATIVE_ARGS
*, enum machine_mode
,
1097 static rtx
rs6000_function_arg (CUMULATIVE_ARGS
*, enum machine_mode
,
1099 static unsigned int rs6000_function_arg_boundary (enum machine_mode
,
1101 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
1102 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
1103 enum machine_mode
, tree
,
1105 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
1107 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
1109 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
1111 static void macho_branch_islands (void);
1112 static int no_previous_def (tree function_name
);
1113 static tree
get_prev_label (tree function_name
);
1114 static void rs6000_darwin_file_start (void);
1117 static tree
rs6000_build_builtin_va_list (void);
1118 static void rs6000_va_start (tree
, rtx
);
1119 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
1120 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
1121 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
1122 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
1123 static rtx
rs6000_emit_vector_compare_inner (enum rtx_code
, rtx
, rtx
);
1124 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
1126 static tree
rs6000_stack_protect_fail (void);
1128 static rtx
rs6000_legitimize_reload_address (rtx
, enum machine_mode
, int, int,
1131 static rtx
rs6000_debug_legitimize_reload_address (rtx
, enum machine_mode
, int,
1134 rtx (*rs6000_legitimize_reload_address_ptr
) (rtx
, enum machine_mode
, int, int,
1136 = rs6000_legitimize_reload_address
;
1138 static bool rs6000_mode_dependent_address_p (const_rtx
);
1139 static bool rs6000_mode_dependent_address (const_rtx
);
1140 static bool rs6000_debug_mode_dependent_address (const_rtx
);
1141 static bool (*rs6000_mode_dependent_address_ptr
) (const_rtx
)
1142 = rs6000_mode_dependent_address
;
1144 static enum reg_class
rs6000_secondary_reload_class (enum reg_class
,
1145 enum machine_mode
, rtx
);
1146 static enum reg_class
rs6000_debug_secondary_reload_class (enum reg_class
,
1149 enum reg_class (*rs6000_secondary_reload_class_ptr
) (enum reg_class
,
1150 enum machine_mode
, rtx
)
1151 = rs6000_secondary_reload_class
;
1153 static enum reg_class
rs6000_preferred_reload_class (rtx
, enum reg_class
);
1154 static enum reg_class
rs6000_debug_preferred_reload_class (rtx
,
1156 enum reg_class (*rs6000_preferred_reload_class_ptr
) (rtx
, enum reg_class
)
1157 = rs6000_preferred_reload_class
;
1159 static bool rs6000_secondary_memory_needed (enum reg_class
, enum reg_class
,
1162 static bool rs6000_debug_secondary_memory_needed (enum reg_class
,
1166 bool (*rs6000_secondary_memory_needed_ptr
) (enum reg_class
, enum reg_class
,
1168 = rs6000_secondary_memory_needed
;
1170 static bool rs6000_cannot_change_mode_class (enum machine_mode
,
1173 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode
,
1177 bool (*rs6000_cannot_change_mode_class_ptr
) (enum machine_mode
,
1180 = rs6000_cannot_change_mode_class
;
1182 static reg_class_t
rs6000_secondary_reload (bool, rtx
, reg_class_t
,
1184 struct secondary_reload_info
*);
1186 const int INSN_NOT_AVAILABLE
= -1;
1187 static enum machine_mode
rs6000_eh_return_filter_mode (void);
1188 static bool rs6000_can_eliminate (const int, const int);
1189 static void rs6000_conditional_register_usage (void);
1190 static void rs6000_trampoline_init (rtx
, tree
, rtx
);
1191 static bool rs6000_cannot_force_const_mem (enum machine_mode
, rtx
);
1192 static bool rs6000_legitimate_constant_p (enum machine_mode
, rtx
);
1194 /* Hash table stuff for keeping track of TOC entries. */
1196 struct GTY(()) toc_hash_struct
1198 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1199 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1201 enum machine_mode key_mode
;
1205 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
1207 /* Hash table to keep track of the argument types for builtin functions. */
1209 struct GTY(()) builtin_hash_struct
1212 enum machine_mode mode
[4]; /* return value + 3 arguments. */
1213 unsigned char uns_p
[4]; /* and whether the types are unsigned. */
1216 static GTY ((param_is (struct builtin_hash_struct
))) htab_t builtin_hash_table
;
1218 static bool rs6000_valid_attribute_p (tree
, tree
, tree
, int);
1219 static void rs6000_function_specific_save (struct cl_target_option
*);
1220 static void rs6000_function_specific_restore (struct cl_target_option
*);
1221 static void rs6000_function_specific_print (FILE *, int,
1222 struct cl_target_option
*);
1223 static bool rs6000_can_inline_p (tree
, tree
);
1224 static void rs6000_set_current_function (tree
);
1227 /* Default register names. */
1228 char rs6000_reg_names
[][8] =
1230 "0", "1", "2", "3", "4", "5", "6", "7",
1231 "8", "9", "10", "11", "12", "13", "14", "15",
1232 "16", "17", "18", "19", "20", "21", "22", "23",
1233 "24", "25", "26", "27", "28", "29", "30", "31",
1234 "0", "1", "2", "3", "4", "5", "6", "7",
1235 "8", "9", "10", "11", "12", "13", "14", "15",
1236 "16", "17", "18", "19", "20", "21", "22", "23",
1237 "24", "25", "26", "27", "28", "29", "30", "31",
1238 "mq", "lr", "ctr","ap",
1239 "0", "1", "2", "3", "4", "5", "6", "7",
1241 /* AltiVec registers. */
1242 "0", "1", "2", "3", "4", "5", "6", "7",
1243 "8", "9", "10", "11", "12", "13", "14", "15",
1244 "16", "17", "18", "19", "20", "21", "22", "23",
1245 "24", "25", "26", "27", "28", "29", "30", "31",
1247 /* SPE registers. */
1248 "spe_acc", "spefscr",
1249 /* Soft frame pointer. */
1253 #ifdef TARGET_REGNAMES
1254 static const char alt_reg_names
[][8] =
1256 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1257 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1258 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1259 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1260 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1261 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1262 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1263 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1264 "mq", "lr", "ctr", "ap",
1265 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1267 /* AltiVec registers. */
1268 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1269 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1270 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1271 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1273 /* SPE registers. */
1274 "spe_acc", "spefscr",
1275 /* Soft frame pointer. */
1280 /* Table of valid machine attributes. */
1282 static const struct attribute_spec rs6000_attribute_table
[] =
1284 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1285 affects_type_identity } */
1286 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
,
1288 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
,
1290 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
,
1292 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
,
1294 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
,
1296 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1297 SUBTARGET_ATTRIBUTE_TABLE
,
1299 { NULL
, 0, 0, false, false, false, NULL
, false }
1302 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1303 static const struct default_options rs6000_option_optimization_table
[] =
1305 { OPT_LEVELS_1_PLUS
, OPT_fomit_frame_pointer
, NULL
, 1 },
1306 { OPT_LEVELS_NONE
, 0, NULL
, 0 }
1309 #ifndef MASK_STRICT_ALIGN
1310 #define MASK_STRICT_ALIGN 0
1312 #ifndef TARGET_PROFILE_KERNEL
1313 #define TARGET_PROFILE_KERNEL 0
1316 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1317 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1319 /* Initialize the GCC target structure. */
1320 #undef TARGET_ATTRIBUTE_TABLE
1321 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1322 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1323 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1324 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1325 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1327 #undef TARGET_ASM_ALIGNED_DI_OP
1328 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1330 /* Default unaligned ops are only provided for ELF. Find the ops needed
1331 for non-ELF systems. */
1332 #ifndef OBJECT_FORMAT_ELF
1334 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1336 #undef TARGET_ASM_UNALIGNED_HI_OP
1337 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1338 #undef TARGET_ASM_UNALIGNED_SI_OP
1339 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1340 #undef TARGET_ASM_UNALIGNED_DI_OP
1341 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1344 #undef TARGET_ASM_UNALIGNED_HI_OP
1345 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1346 #undef TARGET_ASM_UNALIGNED_SI_OP
1347 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1348 #undef TARGET_ASM_UNALIGNED_DI_OP
1349 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1350 #undef TARGET_ASM_ALIGNED_DI_OP
1351 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1355 /* This hook deals with fixups for relocatable code and DI-mode objects
1357 #undef TARGET_ASM_INTEGER
1358 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1360 #ifdef HAVE_GAS_HIDDEN
1361 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1362 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1365 #undef TARGET_HAVE_TLS
1366 #define TARGET_HAVE_TLS HAVE_AS_TLS
1368 #undef TARGET_CANNOT_FORCE_CONST_MEM
1369 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1371 #undef TARGET_DELEGITIMIZE_ADDRESS
1372 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1374 #undef TARGET_ASM_FUNCTION_PROLOGUE
1375 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1376 #undef TARGET_ASM_FUNCTION_EPILOGUE
1377 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1379 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1380 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1382 #undef TARGET_LEGITIMIZE_ADDRESS
1383 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1385 #undef TARGET_SCHED_VARIABLE_ISSUE
1386 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1388 #undef TARGET_SCHED_ISSUE_RATE
1389 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1390 #undef TARGET_SCHED_ADJUST_COST
1391 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1392 #undef TARGET_SCHED_ADJUST_PRIORITY
1393 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1394 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1395 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1396 #undef TARGET_SCHED_INIT
1397 #define TARGET_SCHED_INIT rs6000_sched_init
1398 #undef TARGET_SCHED_FINISH
1399 #define TARGET_SCHED_FINISH rs6000_sched_finish
1400 #undef TARGET_SCHED_REORDER
1401 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1402 #undef TARGET_SCHED_REORDER2
1403 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1405 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1406 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1408 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1409 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1411 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1412 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1413 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1414 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1415 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1416 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1417 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1418 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1420 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1421 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1422 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1423 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1424 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1425 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1426 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1427 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1428 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1429 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1430 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1431 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1432 rs6000_builtin_support_vector_misalignment
1433 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1434 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1435 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1436 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1437 rs6000_builtin_vectorization_cost
1438 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1439 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1440 rs6000_preferred_simd_mode
1442 #undef TARGET_INIT_BUILTINS
1443 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1444 #undef TARGET_BUILTIN_DECL
1445 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1447 #undef TARGET_EXPAND_BUILTIN
1448 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1450 #undef TARGET_MANGLE_TYPE
1451 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1453 #undef TARGET_INIT_LIBFUNCS
1454 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1457 #undef TARGET_BINDS_LOCAL_P
1458 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1461 #undef TARGET_MS_BITFIELD_LAYOUT_P
1462 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1464 #undef TARGET_ASM_OUTPUT_MI_THUNK
1465 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1467 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1468 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1470 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1471 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1473 #undef TARGET_INVALID_WITHIN_DOLOOP
1474 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1476 #undef TARGET_REGISTER_MOVE_COST
1477 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1478 #undef TARGET_MEMORY_MOVE_COST
1479 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1480 #undef TARGET_RTX_COSTS
1481 #define TARGET_RTX_COSTS rs6000_rtx_costs
1482 #undef TARGET_ADDRESS_COST
1483 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1485 #undef TARGET_DWARF_REGISTER_SPAN
1486 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1488 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1489 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1491 /* On rs6000, function arguments are promoted, as are function return
1493 #undef TARGET_PROMOTE_FUNCTION_MODE
1494 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1496 #undef TARGET_RETURN_IN_MEMORY
1497 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1499 #undef TARGET_SETUP_INCOMING_VARARGS
1500 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1502 /* Always strict argument naming on rs6000. */
1503 #undef TARGET_STRICT_ARGUMENT_NAMING
1504 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1505 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1506 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1507 #undef TARGET_SPLIT_COMPLEX_ARG
1508 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1509 #undef TARGET_MUST_PASS_IN_STACK
1510 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1511 #undef TARGET_PASS_BY_REFERENCE
1512 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1513 #undef TARGET_ARG_PARTIAL_BYTES
1514 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1515 #undef TARGET_FUNCTION_ARG_ADVANCE
1516 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1517 #undef TARGET_FUNCTION_ARG
1518 #define TARGET_FUNCTION_ARG rs6000_function_arg
1519 #undef TARGET_FUNCTION_ARG_BOUNDARY
1520 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1522 #undef TARGET_BUILD_BUILTIN_VA_LIST
1523 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1525 #undef TARGET_EXPAND_BUILTIN_VA_START
1526 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1528 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1529 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1531 #undef TARGET_EH_RETURN_FILTER_MODE
1532 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1534 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1535 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1537 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1538 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1540 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1541 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1543 #undef TARGET_HANDLE_OPTION
1544 #define TARGET_HANDLE_OPTION rs6000_handle_option
1546 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1547 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1549 #undef TARGET_OPTION_OVERRIDE
1550 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1552 #undef TARGET_OPTION_INIT_STRUCT
1553 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1555 #undef TARGET_OPTION_DEFAULT_PARAMS
1556 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1558 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1559 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1561 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1562 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1563 rs6000_builtin_vectorized_function
1565 #undef TARGET_DEFAULT_TARGET_FLAGS
1566 #define TARGET_DEFAULT_TARGET_FLAGS \
1569 #undef TARGET_STACK_PROTECT_FAIL
1570 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1572 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1573 The PowerPC architecture requires only weak consistency among
1574 processors--that is, memory accesses between processors need not be
1575 sequentially consistent and memory accesses among processors can occur
1576 in any order. The ability to order memory accesses weakly provides
1577 opportunities for more efficient use of the system bus. Unless a
1578 dependency exists, the 604e allows read operations to precede store
1580 #undef TARGET_RELAXED_ORDERING
1581 #define TARGET_RELAXED_ORDERING true
1584 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1585 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1588 /* Use a 32-bit anchor range. This leads to sequences like:
1590 addis tmp,anchor,high
1593 where tmp itself acts as an anchor, and can be shared between
1594 accesses to the same 64k page. */
1595 #undef TARGET_MIN_ANCHOR_OFFSET
1596 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1597 #undef TARGET_MAX_ANCHOR_OFFSET
1598 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1599 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1600 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1602 #undef TARGET_BUILTIN_RECIPROCAL
1603 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1605 #undef TARGET_EXPAND_TO_RTL_HOOK
1606 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1608 #undef TARGET_INSTANTIATE_DECLS
1609 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1611 #undef TARGET_SECONDARY_RELOAD
1612 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1614 #undef TARGET_LEGITIMATE_ADDRESS_P
1615 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1617 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1618 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1620 #undef TARGET_CAN_ELIMINATE
1621 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1623 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1624 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1626 #undef TARGET_TRAMPOLINE_INIT
1627 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1629 #undef TARGET_FUNCTION_VALUE
1630 #define TARGET_FUNCTION_VALUE rs6000_function_value
1632 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1633 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1635 #undef TARGET_OPTION_SAVE
1636 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1638 #undef TARGET_OPTION_RESTORE
1639 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1641 #undef TARGET_OPTION_PRINT
1642 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1644 #undef TARGET_CAN_INLINE_P
1645 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1647 #undef TARGET_SET_CURRENT_FUNCTION
1648 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1650 #undef TARGET_LEGITIMATE_CONSTANT_P
1651 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1653 struct gcc_target targetm
= TARGET_INITIALIZER
;
1656 /* Simplifications for entries below. */
1659 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1660 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1663 /* Some OSs don't support saving the high part of 64-bit registers on context
1664 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1665 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1666 either, the user must explicitly specify them and we won't interfere with
1667 the user's specification. */
1670 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1671 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1672 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1673 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1674 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
1675 | MASK_POPCNTD
| MASK_VSX
| MASK_ISEL
| MASK_NO_UPDATE
1676 | MASK_RECIP_PRECISION
)
1679 /* Masks for instructions set at various powerpc ISAs. */
1681 ISA_2_1_MASKS
= MASK_MFCRF
,
1682 ISA_2_2_MASKS
= (ISA_2_1_MASKS
| MASK_POPCNTB
),
1683 ISA_2_4_MASKS
= (ISA_2_2_MASKS
| MASK_FPRND
),
1685 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1686 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1687 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1688 server and embedded. */
1689 ISA_2_5_MASKS_EMBEDDED
= (ISA_2_2_MASKS
| MASK_CMPB
| MASK_RECIP_PRECISION
1690 | MASK_PPC_GFXOPT
| MASK_PPC_GPOPT
),
1691 ISA_2_5_MASKS_SERVER
= (ISA_2_5_MASKS_EMBEDDED
| MASK_DFP
),
1693 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1694 altivec is a win so enable it. */
1695 ISA_2_6_MASKS_EMBEDDED
= (ISA_2_5_MASKS_EMBEDDED
| MASK_POPCNTD
),
1696 ISA_2_6_MASKS_SERVER
= (ISA_2_5_MASKS_SERVER
| MASK_POPCNTD
| MASK_ALTIVEC
1700 /* This table occasionally claims that a processor does not support a
1701 particular feature even though it does, but the feature is slower than the
1702 alternative. Thus, it shouldn't be relied on as a complete description of
1703 the processor's support.
1705 Please keep this list in order, and don't forget to update the documentation
1706 in invoke.texi when adding a new processor or flag. */
1710 const char *const name
; /* Canonical processor name. */
1711 const enum processor_type processor
; /* Processor type enum value. */
1712 const int target_enable
; /* Target flags to enable. */
1715 static struct rs6000_ptt
const processor_target_table
[] =
1717 {"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1718 {"403", PROCESSOR_PPC403
,
1719 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1720 {"405", PROCESSOR_PPC405
,
1721 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1722 {"405fp", PROCESSOR_PPC405
,
1723 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1724 {"440", PROCESSOR_PPC440
,
1725 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1726 {"440fp", PROCESSOR_PPC440
,
1727 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1728 {"464", PROCESSOR_PPC440
,
1729 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1730 {"464fp", PROCESSOR_PPC440
,
1731 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1732 {"476", PROCESSOR_PPC476
,
1733 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_PPC_GFXOPT
| MASK_MFCRF
1734 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
1735 {"476fp", PROCESSOR_PPC476
,
1736 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POPCNTB
1737 | MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
1738 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1739 {"601", PROCESSOR_PPC601
,
1740 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1741 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1742 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1743 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1744 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1745 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1746 {"620", PROCESSOR_PPC620
,
1747 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1748 {"630", PROCESSOR_PPC630
,
1749 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1750 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1751 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1752 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1753 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1754 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1755 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1756 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1757 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
1759 /* 8548 has a dummy entry for now. */
1760 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
1762 {"a2", PROCESSOR_PPCA2
,
1763 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_POPCNTB
1764 | MASK_CMPB
| MASK_NO_UPDATE
},
1765 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1766 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
1767 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
1769 {"e500mc64", PROCESSOR_PPCE500MC64
, POWERPC_BASE_MASK
| MASK_POWERPC64
1770 | MASK_PPC_GFXOPT
| MASK_ISEL
},
1771 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1772 {"970", PROCESSOR_POWER4
,
1773 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1774 {"cell", PROCESSOR_CELL
,
1775 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1776 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1777 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1778 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1779 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1780 {"G5", PROCESSOR_POWER4
,
1781 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1782 {"titan", PROCESSOR_TITAN
,
1783 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1784 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1785 {"power2", PROCESSOR_POWER
,
1786 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1787 {"power3", PROCESSOR_PPC630
,
1788 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1789 {"power4", PROCESSOR_POWER4
,
1790 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1792 {"power5", PROCESSOR_POWER5
,
1793 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1794 | MASK_MFCRF
| MASK_POPCNTB
},
1795 {"power5+", PROCESSOR_POWER5
,
1796 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1797 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1798 {"power6", PROCESSOR_POWER6
,
1799 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1800 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
1801 | MASK_RECIP_PRECISION
},
1802 {"power6x", PROCESSOR_POWER6
,
1803 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1804 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
1805 | MASK_MFPGPR
| MASK_RECIP_PRECISION
},
1806 {"power7", PROCESSOR_POWER7
, /* Don't add MASK_ISEL by default */
1807 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
1808 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
| MASK_POPCNTD
1809 | MASK_VSX
| MASK_RECIP_PRECISION
},
1810 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1811 {"powerpc64", PROCESSOR_POWERPC64
,
1812 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1813 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1814 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1815 {"rios2", PROCESSOR_RIOS2
,
1816 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1817 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1818 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1819 {"rs64", PROCESSOR_RS64A
,
1820 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1823 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1827 rs6000_cpu_name_lookup (const char *name
)
1833 for (i
= 0; i
< ARRAY_SIZE (processor_target_table
); i
++)
1834 if (! strcmp (name
, processor_target_table
[i
].name
))
1842 /* Return number of consecutive hard regs needed starting at reg REGNO
1843 to hold something of mode MODE.
1844 This is ordinarily the length in words of a value of mode MODE
1845 but can be less for certain modes in special long registers.
1847 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1848 scalar instructions. The upper 32 bits are only available to the
1851 POWER and PowerPC GPRs hold 32 bits worth;
1852 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1855 rs6000_hard_regno_nregs_internal (int regno
, enum machine_mode mode
)
1857 unsigned HOST_WIDE_INT reg_size
;
1859 if (FP_REGNO_P (regno
))
1860 reg_size
= (VECTOR_MEM_VSX_P (mode
)
1861 ? UNITS_PER_VSX_WORD
1862 : UNITS_PER_FP_WORD
);
1864 else if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1865 reg_size
= UNITS_PER_SPE_WORD
;
1867 else if (ALTIVEC_REGNO_P (regno
))
1868 reg_size
= UNITS_PER_ALTIVEC_WORD
;
1870 /* The value returned for SCmode in the E500 double case is 2 for
1871 ABI compatibility; storing an SCmode value in a single register
1872 would require function_arg and rs6000_spe_function_arg to handle
1873 SCmode so as to pass the value correctly in a pair of
1875 else if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
1876 && !DECIMAL_FLOAT_MODE_P (mode
))
1877 reg_size
= UNITS_PER_FP_WORD
;
1880 reg_size
= UNITS_PER_WORD
;
1882 return (GET_MODE_SIZE (mode
) + reg_size
- 1) / reg_size
;
1885 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1888 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1890 int last_regno
= regno
+ rs6000_hard_regno_nregs
[mode
][regno
] - 1;
1892 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1893 implementations. Don't allow an item to be split between a FP register
1894 and an Altivec register. */
1895 if (VECTOR_MEM_VSX_P (mode
))
1897 if (FP_REGNO_P (regno
))
1898 return FP_REGNO_P (last_regno
);
1900 if (ALTIVEC_REGNO_P (regno
))
1901 return ALTIVEC_REGNO_P (last_regno
);
1904 /* The GPRs can hold any mode, but values bigger than one register
1905 cannot go past R31. */
1906 if (INT_REGNO_P (regno
))
1907 return INT_REGNO_P (last_regno
);
1909 /* The float registers (except for VSX vector modes) can only hold floating
1910 modes and DImode. This excludes the 32-bit decimal float mode for
1912 if (FP_REGNO_P (regno
))
1914 if (SCALAR_FLOAT_MODE_P (mode
)
1915 && (mode
!= TDmode
|| (regno
% 2) == 0)
1916 && FP_REGNO_P (last_regno
))
1919 if (GET_MODE_CLASS (mode
) == MODE_INT
1920 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1923 if (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1924 && PAIRED_VECTOR_MODE (mode
))
1930 /* The CR register can only hold CC modes. */
1931 if (CR_REGNO_P (regno
))
1932 return GET_MODE_CLASS (mode
) == MODE_CC
;
1934 if (CA_REGNO_P (regno
))
1935 return mode
== BImode
;
1937 /* AltiVec only in AldyVec registers. */
1938 if (ALTIVEC_REGNO_P (regno
))
1939 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
);
1941 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1942 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1945 /* We cannot put TImode anywhere except general register and it must be able
1946 to fit within the register set. In the future, allow TImode in the
1947 Altivec or VSX registers. */
1949 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1952 /* Print interesting facts about registers. */
1954 rs6000_debug_reg_print (int first_regno
, int last_regno
, const char *reg_name
)
1958 for (r
= first_regno
; r
<= last_regno
; ++r
)
1960 const char *comma
= "";
1963 if (first_regno
== last_regno
)
1964 fprintf (stderr
, "%s:\t", reg_name
);
1966 fprintf (stderr
, "%s%d:\t", reg_name
, r
- first_regno
);
1969 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1970 if (rs6000_hard_regno_mode_ok_p
[m
][r
] && rs6000_hard_regno_nregs
[m
][r
])
1974 fprintf (stderr
, ",\n\t");
1979 if (rs6000_hard_regno_nregs
[m
][r
] > 1)
1980 len
+= fprintf (stderr
, "%s%s/%d", comma
, GET_MODE_NAME (m
),
1981 rs6000_hard_regno_nregs
[m
][r
]);
1983 len
+= fprintf (stderr
, "%s%s", comma
, GET_MODE_NAME (m
));
1988 if (call_used_regs
[r
])
1992 fprintf (stderr
, ",\n\t");
1997 len
+= fprintf (stderr
, "%s%s", comma
, "call-used");
2005 fprintf (stderr
, ",\n\t");
2010 len
+= fprintf (stderr
, "%s%s", comma
, "fixed");
2016 fprintf (stderr
, ",\n\t");
2020 fprintf (stderr
, "%sregno = %d\n", comma
, r
);
2024 #define DEBUG_FMT_D "%-32s= %d\n"
2025 #define DEBUG_FMT_S "%-32s= %s\n"
2027 /* Print various interesting information with -mdebug=reg. */
2029 rs6000_debug_reg_global (void)
2031 static const char *const tf
[2] = { "false", "true" };
2032 const char *nl
= (const char *)0;
2034 char costly_num
[20];
2036 const char *costly_str
;
2037 const char *nop_str
;
2038 const char *trace_str
;
2039 const char *abi_str
;
2040 const char *cmodel_str
;
2042 /* Map enum rs6000_vector to string. */
2043 static const char *rs6000_debug_vector_unit
[] = {
2052 fprintf (stderr
, "Register information: (last virtual reg = %d)\n",
2053 LAST_VIRTUAL_REGISTER
);
2054 rs6000_debug_reg_print (0, 31, "gr");
2055 rs6000_debug_reg_print (32, 63, "fp");
2056 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO
,
2059 rs6000_debug_reg_print (LR_REGNO
, LR_REGNO
, "lr");
2060 rs6000_debug_reg_print (CTR_REGNO
, CTR_REGNO
, "ctr");
2061 rs6000_debug_reg_print (CR0_REGNO
, CR7_REGNO
, "cr");
2062 rs6000_debug_reg_print (MQ_REGNO
, MQ_REGNO
, "mq");
2063 rs6000_debug_reg_print (CA_REGNO
, CA_REGNO
, "ca");
2064 rs6000_debug_reg_print (VRSAVE_REGNO
, VRSAVE_REGNO
, "vrsave");
2065 rs6000_debug_reg_print (VSCR_REGNO
, VSCR_REGNO
, "vscr");
2066 rs6000_debug_reg_print (SPE_ACC_REGNO
, SPE_ACC_REGNO
, "spe_a");
2067 rs6000_debug_reg_print (SPEFSCR_REGNO
, SPEFSCR_REGNO
, "spe_f");
2071 "d reg_class = %s\n"
2072 "f reg_class = %s\n"
2073 "v reg_class = %s\n"
2074 "wa reg_class = %s\n"
2075 "wd reg_class = %s\n"
2076 "wf reg_class = %s\n"
2077 "ws reg_class = %s\n\n",
2078 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_d
]],
2079 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_f
]],
2080 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_v
]],
2081 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wa
]],
2082 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wd
]],
2083 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wf
]],
2084 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_ws
]]);
2086 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2087 if (rs6000_vector_unit
[m
] || rs6000_vector_mem
[m
])
2090 fprintf (stderr
, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2092 rs6000_debug_vector_unit
[ rs6000_vector_unit
[m
] ],
2093 rs6000_debug_vector_unit
[ rs6000_vector_mem
[m
] ]);
2099 if (rs6000_recip_control
)
2101 fprintf (stderr
, "\nReciprocal mask = 0x%x\n", rs6000_recip_control
);
2103 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2104 if (rs6000_recip_bits
[m
])
2107 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2109 (RS6000_RECIP_AUTO_RE_P (m
)
2111 : (RS6000_RECIP_HAVE_RE_P (m
) ? "have" : "none")),
2112 (RS6000_RECIP_AUTO_RSQRTE_P (m
)
2114 : (RS6000_RECIP_HAVE_RSQRTE_P (m
) ? "have" : "none")));
2117 fputs ("\n", stderr
);
2120 if (rs6000_cpu_index
>= 0)
2121 fprintf (stderr
, DEBUG_FMT_S
, "cpu",
2122 processor_target_table
[rs6000_cpu_index
].name
);
2124 if (rs6000_tune_index
>= 0)
2125 fprintf (stderr
, DEBUG_FMT_S
, "tune",
2126 processor_target_table
[rs6000_tune_index
].name
);
2128 switch (rs6000_sched_costly_dep
)
2130 case max_dep_latency
:
2131 costly_str
= "max_dep_latency";
2135 costly_str
= "no_dep_costly";
2138 case all_deps_costly
:
2139 costly_str
= "all_deps_costly";
2142 case true_store_to_load_dep_costly
:
2143 costly_str
= "true_store_to_load_dep_costly";
2146 case store_to_load_dep_costly
:
2147 costly_str
= "store_to_load_dep_costly";
2151 costly_str
= costly_num
;
2152 sprintf (costly_num
, "%d", (int)rs6000_sched_costly_dep
);
2156 fprintf (stderr
, DEBUG_FMT_S
, "sched_costly_dep", costly_str
);
2158 switch (rs6000_sched_insert_nops
)
2160 case sched_finish_regroup_exact
:
2161 nop_str
= "sched_finish_regroup_exact";
2164 case sched_finish_pad_groups
:
2165 nop_str
= "sched_finish_pad_groups";
2168 case sched_finish_none
:
2169 nop_str
= "sched_finish_none";
2174 sprintf (nop_num
, "%d", (int)rs6000_sched_insert_nops
);
2178 fprintf (stderr
, DEBUG_FMT_S
, "sched_insert_nops", nop_str
);
2180 switch (rs6000_sdata
)
2187 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "data");
2191 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "sysv");
2195 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "eabi");
2200 switch (rs6000_traceback
)
2202 case traceback_default
: trace_str
= "default"; break;
2203 case traceback_none
: trace_str
= "none"; break;
2204 case traceback_part
: trace_str
= "part"; break;
2205 case traceback_full
: trace_str
= "full"; break;
2206 default: trace_str
= "unknown"; break;
2209 fprintf (stderr
, DEBUG_FMT_S
, "traceback", trace_str
);
2211 switch (rs6000_current_cmodel
)
2213 case CMODEL_SMALL
: cmodel_str
= "small"; break;
2214 case CMODEL_MEDIUM
: cmodel_str
= "medium"; break;
2215 case CMODEL_LARGE
: cmodel_str
= "large"; break;
2216 default: cmodel_str
= "unknown"; break;
2219 fprintf (stderr
, DEBUG_FMT_S
, "cmodel", cmodel_str
);
2221 switch (rs6000_current_abi
)
2223 case ABI_NONE
: abi_str
= "none"; break;
2224 case ABI_AIX
: abi_str
= "aix"; break;
2225 case ABI_V4
: abi_str
= "V4"; break;
2226 case ABI_DARWIN
: abi_str
= "darwin"; break;
2227 default: abi_str
= "unknown"; break;
2230 fprintf (stderr
, DEBUG_FMT_S
, "abi", abi_str
);
2232 if (rs6000_altivec_abi
)
2233 fprintf (stderr
, DEBUG_FMT_S
, "altivec_abi", "true");
2236 fprintf (stderr
, DEBUG_FMT_S
, "spe_abi", "true");
2238 if (rs6000_darwin64_abi
)
2239 fprintf (stderr
, DEBUG_FMT_S
, "darwin64_abi", "true");
2241 if (rs6000_float_gprs
)
2242 fprintf (stderr
, DEBUG_FMT_S
, "float_gprs", "true");
2244 fprintf (stderr
, DEBUG_FMT_S
, "always_hint", tf
[!!rs6000_always_hint
]);
2245 fprintf (stderr
, DEBUG_FMT_S
, "align_branch",
2246 tf
[!!rs6000_align_branch_targets
]);
2247 fprintf (stderr
, DEBUG_FMT_D
, "tls_size", rs6000_tls_size
);
2248 fprintf (stderr
, DEBUG_FMT_D
, "long_double_size",
2249 rs6000_long_double_type_size
);
2250 fprintf (stderr
, DEBUG_FMT_D
, "sched_restricted_insns_priority",
2251 (int)rs6000_sched_restricted_insns_priority
);
2254 /* Initialize the various global tables that are based on register size. */
2256 rs6000_init_hard_regno_mode_ok (bool global_init_p
)
2262 /* Precalculate REGNO_REG_CLASS. */
2263 rs6000_regno_regclass
[0] = GENERAL_REGS
;
2264 for (r
= 1; r
< 32; ++r
)
2265 rs6000_regno_regclass
[r
] = BASE_REGS
;
2267 for (r
= 32; r
< 64; ++r
)
2268 rs6000_regno_regclass
[r
] = FLOAT_REGS
;
2270 for (r
= 64; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2271 rs6000_regno_regclass
[r
] = NO_REGS
;
2273 for (r
= FIRST_ALTIVEC_REGNO
; r
<= LAST_ALTIVEC_REGNO
; ++r
)
2274 rs6000_regno_regclass
[r
] = ALTIVEC_REGS
;
2276 rs6000_regno_regclass
[CR0_REGNO
] = CR0_REGS
;
2277 for (r
= CR1_REGNO
; r
<= CR7_REGNO
; ++r
)
2278 rs6000_regno_regclass
[r
] = CR_REGS
;
2280 rs6000_regno_regclass
[MQ_REGNO
] = MQ_REGS
;
2281 rs6000_regno_regclass
[LR_REGNO
] = LINK_REGS
;
2282 rs6000_regno_regclass
[CTR_REGNO
] = CTR_REGS
;
2283 rs6000_regno_regclass
[CA_REGNO
] = CA_REGS
;
2284 rs6000_regno_regclass
[VRSAVE_REGNO
] = VRSAVE_REGS
;
2285 rs6000_regno_regclass
[VSCR_REGNO
] = VRSAVE_REGS
;
2286 rs6000_regno_regclass
[SPE_ACC_REGNO
] = SPE_ACC_REGS
;
2287 rs6000_regno_regclass
[SPEFSCR_REGNO
] = SPEFSCR_REGS
;
2288 rs6000_regno_regclass
[ARG_POINTER_REGNUM
] = BASE_REGS
;
2289 rs6000_regno_regclass
[FRAME_POINTER_REGNUM
] = BASE_REGS
;
2291 /* Precalculate vector information, this must be set up before the
2292 rs6000_hard_regno_nregs_internal below. */
2293 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2295 rs6000_vector_unit
[m
] = rs6000_vector_mem
[m
] = VECTOR_NONE
;
2296 rs6000_vector_reload
[m
][0] = CODE_FOR_nothing
;
2297 rs6000_vector_reload
[m
][1] = CODE_FOR_nothing
;
2300 for (c
= 0; c
< (int)(int)RS6000_CONSTRAINT_MAX
; c
++)
2301 rs6000_constraints
[c
] = NO_REGS
;
2303 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2304 believes it can use native alignment or still uses 128-bit alignment. */
2305 if (TARGET_VSX
&& !TARGET_VSX_ALIGN_128
)
2316 /* V2DF mode, VSX only. */
2319 rs6000_vector_unit
[V2DFmode
] = VECTOR_VSX
;
2320 rs6000_vector_mem
[V2DFmode
] = VECTOR_VSX
;
2321 rs6000_vector_align
[V2DFmode
] = align64
;
2324 /* V4SF mode, either VSX or Altivec. */
2327 rs6000_vector_unit
[V4SFmode
] = VECTOR_VSX
;
2328 rs6000_vector_mem
[V4SFmode
] = VECTOR_VSX
;
2329 rs6000_vector_align
[V4SFmode
] = align32
;
2331 else if (TARGET_ALTIVEC
)
2333 rs6000_vector_unit
[V4SFmode
] = VECTOR_ALTIVEC
;
2334 rs6000_vector_mem
[V4SFmode
] = VECTOR_ALTIVEC
;
2335 rs6000_vector_align
[V4SFmode
] = align32
;
2338 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2342 rs6000_vector_unit
[V4SImode
] = VECTOR_ALTIVEC
;
2343 rs6000_vector_unit
[V8HImode
] = VECTOR_ALTIVEC
;
2344 rs6000_vector_unit
[V16QImode
] = VECTOR_ALTIVEC
;
2345 rs6000_vector_align
[V4SImode
] = align32
;
2346 rs6000_vector_align
[V8HImode
] = align32
;
2347 rs6000_vector_align
[V16QImode
] = align32
;
2351 rs6000_vector_mem
[V4SImode
] = VECTOR_VSX
;
2352 rs6000_vector_mem
[V8HImode
] = VECTOR_VSX
;
2353 rs6000_vector_mem
[V16QImode
] = VECTOR_VSX
;
2357 rs6000_vector_mem
[V4SImode
] = VECTOR_ALTIVEC
;
2358 rs6000_vector_mem
[V8HImode
] = VECTOR_ALTIVEC
;
2359 rs6000_vector_mem
[V16QImode
] = VECTOR_ALTIVEC
;
2363 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2364 Altivec doesn't have 64-bit support. */
2367 rs6000_vector_mem
[V2DImode
] = VECTOR_VSX
;
2368 rs6000_vector_unit
[V2DImode
] = VECTOR_NONE
;
2369 rs6000_vector_align
[V2DImode
] = align64
;
2372 /* DFmode, see if we want to use the VSX unit. */
2373 if (TARGET_VSX
&& TARGET_VSX_SCALAR_DOUBLE
)
2375 rs6000_vector_unit
[DFmode
] = VECTOR_VSX
;
2376 rs6000_vector_mem
[DFmode
]
2377 = (TARGET_VSX_SCALAR_MEMORY
? VECTOR_VSX
: VECTOR_NONE
);
2378 rs6000_vector_align
[DFmode
] = align64
;
2381 /* TODO add SPE and paired floating point vector support. */
2383 /* Register class constaints for the constraints that depend on compile
2385 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2386 rs6000_constraints
[RS6000_CONSTRAINT_f
] = FLOAT_REGS
;
2388 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
2389 rs6000_constraints
[RS6000_CONSTRAINT_d
] = FLOAT_REGS
;
2393 /* At present, we just use VSX_REGS, but we have different constraints
2394 based on the use, in case we want to fine tune the default register
2395 class used. wa = any VSX register, wf = register class to use for
2396 V4SF, wd = register class to use for V2DF, and ws = register classs to
2397 use for DF scalars. */
2398 rs6000_constraints
[RS6000_CONSTRAINT_wa
] = VSX_REGS
;
2399 rs6000_constraints
[RS6000_CONSTRAINT_wf
] = VSX_REGS
;
2400 rs6000_constraints
[RS6000_CONSTRAINT_wd
] = VSX_REGS
;
2401 rs6000_constraints
[RS6000_CONSTRAINT_ws
] = (TARGET_VSX_SCALAR_MEMORY
2407 rs6000_constraints
[RS6000_CONSTRAINT_v
] = ALTIVEC_REGS
;
2409 /* Set up the reload helper functions. */
2410 if (TARGET_VSX
|| TARGET_ALTIVEC
)
2414 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_di_store
;
2415 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_di_load
;
2416 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_di_store
;
2417 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_di_load
;
2418 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_di_store
;
2419 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_di_load
;
2420 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_di_store
;
2421 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_di_load
;
2422 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_di_store
;
2423 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_di_load
;
2424 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_di_store
;
2425 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_di_load
;
2429 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_si_store
;
2430 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_si_load
;
2431 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_si_store
;
2432 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_si_load
;
2433 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_si_store
;
2434 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_si_load
;
2435 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_si_store
;
2436 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_si_load
;
2437 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_si_store
;
2438 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_si_load
;
2439 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_si_store
;
2440 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_si_load
;
2444 /* Precalculate HARD_REGNO_NREGS. */
2445 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2446 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2447 rs6000_hard_regno_nregs
[m
][r
]
2448 = rs6000_hard_regno_nregs_internal (r
, (enum machine_mode
)m
);
2450 /* Precalculate HARD_REGNO_MODE_OK. */
2451 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2452 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2453 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
)m
))
2454 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
2456 /* Precalculate CLASS_MAX_NREGS sizes. */
2457 for (c
= 0; c
< LIM_REG_CLASSES
; ++c
)
2461 if (TARGET_VSX
&& VSX_REG_CLASS_P (c
))
2462 reg_size
= UNITS_PER_VSX_WORD
;
2464 else if (c
== ALTIVEC_REGS
)
2465 reg_size
= UNITS_PER_ALTIVEC_WORD
;
2467 else if (c
== FLOAT_REGS
)
2468 reg_size
= UNITS_PER_FP_WORD
;
2471 reg_size
= UNITS_PER_WORD
;
2473 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2474 rs6000_class_max_nregs
[m
][c
]
2475 = (GET_MODE_SIZE (m
) + reg_size
- 1) / reg_size
;
2478 if (TARGET_E500_DOUBLE
)
2479 rs6000_class_max_nregs
[DFmode
][GENERAL_REGS
] = 1;
2481 /* Calculate which modes to automatically generate code to use a the
2482 reciprocal divide and square root instructions. In the future, possibly
2483 automatically generate the instructions even if the user did not specify
2484 -mrecip. The older machines double precision reciprocal sqrt estimate is
2485 not accurate enough. */
2486 memset (rs6000_recip_bits
, 0, sizeof (rs6000_recip_bits
));
2488 rs6000_recip_bits
[SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2490 rs6000_recip_bits
[DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2491 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2492 rs6000_recip_bits
[V4SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2493 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2494 rs6000_recip_bits
[V2DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2496 if (TARGET_FRSQRTES
)
2497 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2499 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2500 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2501 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2502 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2503 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2505 if (rs6000_recip_control
)
2507 if (!flag_finite_math_only
)
2508 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2509 if (flag_trapping_math
)
2510 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2511 if (!flag_reciprocal_math
)
2512 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2513 if (flag_finite_math_only
&& !flag_trapping_math
&& flag_reciprocal_math
)
2515 if (RS6000_RECIP_HAVE_RE_P (SFmode
)
2516 && (rs6000_recip_control
& RECIP_SF_DIV
) != 0)
2517 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2519 if (RS6000_RECIP_HAVE_RE_P (DFmode
)
2520 && (rs6000_recip_control
& RECIP_DF_DIV
) != 0)
2521 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2523 if (RS6000_RECIP_HAVE_RE_P (V4SFmode
)
2524 && (rs6000_recip_control
& RECIP_V4SF_DIV
) != 0)
2525 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2527 if (RS6000_RECIP_HAVE_RE_P (V2DFmode
)
2528 && (rs6000_recip_control
& RECIP_V2DF_DIV
) != 0)
2529 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2531 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode
)
2532 && (rs6000_recip_control
& RECIP_SF_RSQRT
) != 0)
2533 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2535 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode
)
2536 && (rs6000_recip_control
& RECIP_DF_RSQRT
) != 0)
2537 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2539 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode
)
2540 && (rs6000_recip_control
& RECIP_V4SF_RSQRT
) != 0)
2541 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2543 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode
)
2544 && (rs6000_recip_control
& RECIP_V2DF_RSQRT
) != 0)
2545 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2549 if (global_init_p
|| TARGET_DEBUG_TARGET
)
2551 if (TARGET_DEBUG_REG
)
2552 rs6000_debug_reg_global ();
2554 if (TARGET_DEBUG_COST
|| TARGET_DEBUG_REG
)
2556 "SImode variable mult cost = %d\n"
2557 "SImode constant mult cost = %d\n"
2558 "SImode short constant mult cost = %d\n"
2559 "DImode multipliciation cost = %d\n"
2560 "SImode division cost = %d\n"
2561 "DImode division cost = %d\n"
2562 "Simple fp operation cost = %d\n"
2563 "DFmode multiplication cost = %d\n"
2564 "SFmode division cost = %d\n"
2565 "DFmode division cost = %d\n"
2566 "cache line size = %d\n"
2567 "l1 cache size = %d\n"
2568 "l2 cache size = %d\n"
2569 "simultaneous prefetches = %d\n"
2572 rs6000_cost
->mulsi_const
,
2573 rs6000_cost
->mulsi_const9
,
2581 rs6000_cost
->cache_line_size
,
2582 rs6000_cost
->l1_cache_size
,
2583 rs6000_cost
->l2_cache_size
,
2584 rs6000_cost
->simultaneous_prefetches
);
2589 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2592 darwin_rs6000_override_options (void)
2594 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2596 rs6000_altivec_abi
= 1;
2597 TARGET_ALTIVEC_VRSAVE
= 1;
2599 if (DEFAULT_ABI
== ABI_DARWIN
2601 darwin_one_byte_bool
= 1;
2603 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
2605 target_flags
|= MASK_POWERPC64
;
2606 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2610 rs6000_default_long_calls
= 1;
2611 target_flags
|= MASK_SOFT_FLOAT
;
2614 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2616 if (!flag_mkernel
&& !flag_apple_kext
2618 && ! (target_flags_explicit
& MASK_ALTIVEC
))
2619 target_flags
|= MASK_ALTIVEC
;
2621 /* Unless the user (not the configurer) has explicitly overridden
2622 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2623 G4 unless targetting the kernel. */
2626 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
2627 && ! (target_flags_explicit
& MASK_ALTIVEC
)
2628 && ! rs6000_select
[1].string
)
2630 target_flags
|= MASK_ALTIVEC
;
2635 /* If not otherwise specified by a target, make 'long double' equivalent to
2638 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2639 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2642 /* Override command line options. Mostly we process the processor type and
2643 sometimes adjust other TARGET_ options. */
2646 rs6000_option_override_internal (bool global_init_p
)
2649 const char *default_cpu
= OPTION_TARGET_CPU_DEFAULT
;
2653 struct cl_target_option
*main_target_opt
2654 = ((global_init_p
|| target_option_default_node
== NULL
)
2655 ? NULL
: TREE_TARGET_OPTION (target_option_default_node
));
2657 /* On 64-bit Darwin, power alignment is ABI-incompatible with some C
2658 library functions, so warn about it. The flag may be useful for
2659 performance studies from time to time though, so don't disable it
2661 if (global_options_set
.x_rs6000_alignment_flags
2662 && rs6000_alignment_flags
== MASK_ALIGN_POWER
2663 && DEFAULT_ABI
== ABI_DARWIN
2665 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2666 " it is incompatible with the installed C and C++ libraries");
2668 /* Numerous experiment shows that IRA based loop pressure
2669 calculation works better for RTL loop invariant motion on targets
2670 with enough (>= 32) registers. It is an expensive optimization.
2671 So it is on only for peak performance. */
2672 if (optimize
>= 3 && global_init_p
)
2673 flag_ira_loop_pressure
= 1;
2675 /* Set the pointer size. */
2678 rs6000_pmode
= (int)DImode
;
2679 rs6000_pointer_size
= 64;
2683 rs6000_pmode
= (int)SImode
;
2684 rs6000_pointer_size
= 32;
2687 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
2688 #ifdef OS_MISSING_POWERPC64
2689 if (OS_MISSING_POWERPC64
)
2690 set_masks
&= ~MASK_POWERPC64
;
2692 #ifdef OS_MISSING_ALTIVEC
2693 if (OS_MISSING_ALTIVEC
)
2694 set_masks
&= ~MASK_ALTIVEC
;
2697 /* Don't override by the processor default if given explicitly. */
2698 set_masks
&= ~target_flags_explicit
;
2700 /* Identify the processor type. */
2703 if (TARGET_POWERPC64
)
2704 default_cpu
= "powerpc64";
2705 else if (TARGET_POWERPC
)
2706 default_cpu
= "powerpc";
2709 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2710 the cpu in a target attribute or pragma, but did not specify a tuning
2711 option, use the cpu for the tuning option rather than the option specified
2712 with -mtune on the command line. */
2713 if (rs6000_cpu_index
> 0)
2714 cpu_index
= rs6000_cpu_index
;
2715 else if (main_target_opt
!= NULL
&& main_target_opt
->x_rs6000_cpu_index
> 0)
2716 rs6000_cpu_index
= cpu_index
= main_target_opt
->x_rs6000_cpu_index
;
2718 rs6000_cpu_index
= cpu_index
= rs6000_cpu_name_lookup (default_cpu
);
2720 if (rs6000_tune_index
> 0)
2721 tune_index
= rs6000_tune_index
;
2723 rs6000_tune_index
= tune_index
= cpu_index
;
2727 target_flags
&= ~set_masks
;
2728 target_flags
|= (processor_target_table
[cpu_index
].target_enable
2732 rs6000_cpu
= ((tune_index
>= 0)
2733 ? processor_target_table
[tune_index
].processor
2735 ? PROCESSOR_DEFAULT64
2736 : PROCESSOR_DEFAULT
));
2738 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
2739 || rs6000_cpu
== PROCESSOR_PPCE500MC
|| rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2742 error ("AltiVec not supported in this target");
2744 error ("SPE not supported in this target");
2747 /* Disable Cell microcode if we are optimizing for the Cell
2748 and not optimizing for size. */
2749 if (rs6000_gen_cell_microcode
== -1)
2750 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
2753 /* If we are optimizing big endian systems for space and it's OK to
2754 use instructions that would be microcoded on the Cell, use the
2755 load/store multiple and string instructions. */
2756 if (BYTES_BIG_ENDIAN
&& optimize_size
&& rs6000_gen_cell_microcode
)
2757 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
2759 /* Don't allow -mmultiple or -mstring on little endian systems
2760 unless the cpu is a 750, because the hardware doesn't support the
2761 instructions used in little endian mode, and causes an alignment
2762 trap. The 750 does not cause an alignment trap (except when the
2763 target is unaligned). */
2765 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
2767 if (TARGET_MULTIPLE
)
2769 target_flags
&= ~MASK_MULTIPLE
;
2770 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
2771 warning (0, "-mmultiple is not supported on little endian systems");
2776 target_flags
&= ~MASK_STRING
;
2777 if ((target_flags_explicit
& MASK_STRING
) != 0)
2778 warning (0, "-mstring is not supported on little endian systems");
2782 /* Add some warnings for VSX. */
2785 const char *msg
= NULL
;
2786 if (!TARGET_HARD_FLOAT
|| !TARGET_FPRS
2787 || !TARGET_SINGLE_FLOAT
|| !TARGET_DOUBLE_FLOAT
)
2789 if (target_flags_explicit
& MASK_VSX
)
2790 msg
= N_("-mvsx requires hardware floating point");
2792 target_flags
&= ~ MASK_VSX
;
2794 else if (TARGET_PAIRED_FLOAT
)
2795 msg
= N_("-mvsx and -mpaired are incompatible");
2796 /* The hardware will allow VSX and little endian, but until we make sure
2797 things like vector select, etc. work don't allow VSX on little endian
2798 systems at this point. */
2799 else if (!BYTES_BIG_ENDIAN
)
2800 msg
= N_("-mvsx used with little endian code");
2801 else if (TARGET_AVOID_XFORM
> 0)
2802 msg
= N_("-mvsx needs indexed addressing");
2803 else if (!TARGET_ALTIVEC
&& (target_flags_explicit
& MASK_ALTIVEC
))
2805 if (target_flags_explicit
& MASK_VSX
)
2806 msg
= N_("-mvsx and -mno-altivec are incompatible");
2808 msg
= N_("-mno-altivec disables vsx");
2814 target_flags
&= ~ MASK_VSX
;
2815 target_flags_explicit
|= MASK_VSX
;
2819 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2820 unless the user explicitly used the -mno-<option> to disable the code. */
2822 target_flags
|= (ISA_2_6_MASKS_SERVER
& ~target_flags_explicit
);
2823 else if (TARGET_POPCNTD
)
2824 target_flags
|= (ISA_2_6_MASKS_EMBEDDED
& ~target_flags_explicit
);
2825 else if (TARGET_DFP
)
2826 target_flags
|= (ISA_2_5_MASKS_SERVER
& ~target_flags_explicit
);
2827 else if (TARGET_CMPB
)
2828 target_flags
|= (ISA_2_5_MASKS_EMBEDDED
& ~target_flags_explicit
);
2829 else if (TARGET_FPRND
)
2830 target_flags
|= (ISA_2_4_MASKS
& ~target_flags_explicit
);
2831 else if (TARGET_POPCNTB
)
2832 target_flags
|= (ISA_2_2_MASKS
& ~target_flags_explicit
);
2833 else if (TARGET_ALTIVEC
)
2834 target_flags
|= (MASK_PPC_GFXOPT
& ~target_flags_explicit
);
2836 /* E500mc does "better" if we inline more aggressively. Respect the
2837 user's opinion, though. */
2838 if (rs6000_block_move_inline_limit
== 0
2839 && (rs6000_cpu
== PROCESSOR_PPCE500MC
2840 || rs6000_cpu
== PROCESSOR_PPCE500MC64
))
2841 rs6000_block_move_inline_limit
= 128;
2843 /* store_one_arg depends on expand_block_move to handle at least the
2844 size of reg_parm_stack_space. */
2845 if (rs6000_block_move_inline_limit
< (TARGET_POWERPC64
? 64 : 32))
2846 rs6000_block_move_inline_limit
= (TARGET_POWERPC64
? 64 : 32);
2850 /* If the appropriate debug option is enabled, replace the target hooks
2851 with debug versions that call the real version and then prints
2852 debugging information. */
2853 if (TARGET_DEBUG_COST
)
2855 targetm
.rtx_costs
= rs6000_debug_rtx_costs
;
2856 targetm
.address_cost
= rs6000_debug_address_cost
;
2857 targetm
.sched
.adjust_cost
= rs6000_debug_adjust_cost
;
2860 if (TARGET_DEBUG_ADDR
)
2862 targetm
.legitimate_address_p
= rs6000_debug_legitimate_address_p
;
2863 targetm
.legitimize_address
= rs6000_debug_legitimize_address
;
2864 rs6000_secondary_reload_class_ptr
2865 = rs6000_debug_secondary_reload_class
;
2866 rs6000_secondary_memory_needed_ptr
2867 = rs6000_debug_secondary_memory_needed
;
2868 rs6000_cannot_change_mode_class_ptr
2869 = rs6000_debug_cannot_change_mode_class
;
2870 rs6000_preferred_reload_class_ptr
2871 = rs6000_debug_preferred_reload_class
;
2872 rs6000_legitimize_reload_address_ptr
2873 = rs6000_debug_legitimize_reload_address
;
2874 rs6000_mode_dependent_address_ptr
2875 = rs6000_debug_mode_dependent_address
;
2878 if (rs6000_veclibabi_name
)
2880 if (strcmp (rs6000_veclibabi_name
, "mass") == 0)
2881 rs6000_veclib_handler
= rs6000_builtin_vectorized_libmass
;
2884 error ("unknown vectorization library ABI type (%s) for "
2885 "-mveclibabi= switch", rs6000_veclibabi_name
);
2891 if (!global_options_set
.x_rs6000_long_double_type_size
)
2893 if (main_target_opt
!= NULL
2894 && (main_target_opt
->x_rs6000_long_double_type_size
2895 != RS6000_DEFAULT_LONG_DOUBLE_SIZE
))
2896 error ("target attribute or pragma changes long double size");
2898 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2901 #ifndef POWERPC_LINUX
2902 if (!global_options_set
.x_rs6000_ieeequad
)
2903 rs6000_ieeequad
= 1;
2906 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2907 target attribute or pragma which automatically enables both options,
2908 unless the altivec ABI was set. This is set by default for 64-bit, but
2910 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_altivec_abi
)
2911 target_flags
&= ~((MASK_VSX
| MASK_ALTIVEC
) & ~target_flags_explicit
);
2913 /* Enable Altivec ABI for AIX -maltivec. */
2914 if (TARGET_XCOFF
&& (TARGET_ALTIVEC
|| TARGET_VSX
))
2916 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_altivec_abi
)
2917 error ("target attribute or pragma changes AltiVec ABI");
2919 rs6000_altivec_abi
= 1;
2922 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2923 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2924 be explicitly overridden in either case. */
2927 if (!global_options_set
.x_rs6000_altivec_abi
2928 && (TARGET_64BIT
|| TARGET_ALTIVEC
|| TARGET_VSX
))
2930 if (main_target_opt
!= NULL
&&
2931 !main_target_opt
->x_rs6000_altivec_abi
)
2932 error ("target attribute or pragma changes AltiVec ABI");
2934 rs6000_altivec_abi
= 1;
2937 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2938 if (!global_options_set
.x_TARGET_ALTIVEC_VRSAVE
)
2939 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
2942 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2943 So far, the only darwin64 targets are also MACH-O. */
2945 && DEFAULT_ABI
== ABI_DARWIN
2948 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_darwin64_abi
)
2949 error ("target attribute or pragma changes darwin64 ABI");
2952 rs6000_darwin64_abi
= 1;
2953 /* Default to natural alignment, for better performance. */
2954 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2958 /* Place FP constants in the constant pool instead of TOC
2959 if section anchors enabled. */
2960 if (flag_section_anchors
)
2961 TARGET_NO_FP_IN_TOC
= 1;
2963 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2964 SUBTARGET_OVERRIDE_OPTIONS
;
2966 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2967 SUBSUBTARGET_OVERRIDE_OPTIONS
;
2969 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2970 SUB3TARGET_OVERRIDE_OPTIONS
;
2973 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
2974 || rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2976 /* The e500 and e500mc do not have string instructions, and we set
2977 MASK_STRING above when optimizing for size. */
2978 if ((target_flags
& MASK_STRING
) != 0)
2979 target_flags
= target_flags
& ~MASK_STRING
;
2981 else if (rs6000_select
[1].string
!= NULL
)
2983 /* For the powerpc-eabispe configuration, we set all these by
2984 default, so let's unset them if we manually set another
2985 CPU that is not the E500. */
2986 if (main_target_opt
!= NULL
2987 && ((main_target_opt
->x_rs6000_spe_abi
!= rs6000_spe_abi
)
2988 || (main_target_opt
->x_rs6000_spe
!= rs6000_spe
)
2989 || (main_target_opt
->x_rs6000_float_gprs
!= rs6000_float_gprs
)))
2990 error ("target attribute or pragma changes SPE ABI");
2993 if (!global_options_set
.x_rs6000_spe_abi
)
2995 if (!global_options_set
.x_rs6000_spe
)
2997 if (!global_options_set
.x_rs6000_float_gprs
)
2998 rs6000_float_gprs
= 0;
3000 if (!(target_flags_explicit
& MASK_ISEL
))
3001 target_flags
&= ~MASK_ISEL
;
3004 /* Detect invalid option combinations with E500. */
3007 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
3008 && rs6000_cpu
!= PROCESSOR_POWER5
3009 && rs6000_cpu
!= PROCESSOR_POWER6
3010 && rs6000_cpu
!= PROCESSOR_POWER7
3011 && rs6000_cpu
!= PROCESSOR_PPCA2
3012 && rs6000_cpu
!= PROCESSOR_CELL
);
3013 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
3014 || rs6000_cpu
== PROCESSOR_POWER5
3015 || rs6000_cpu
== PROCESSOR_POWER7
);
3016 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
3017 || rs6000_cpu
== PROCESSOR_POWER5
3018 || rs6000_cpu
== PROCESSOR_POWER6
3019 || rs6000_cpu
== PROCESSOR_POWER7
3020 || rs6000_cpu
== PROCESSOR_PPCE500MC
3021 || rs6000_cpu
== PROCESSOR_PPCE500MC64
);
3023 /* Allow debug switches to override the above settings. These are set to -1
3024 in rs6000.opt to indicate the user hasn't directly set the switch. */
3025 if (TARGET_ALWAYS_HINT
>= 0)
3026 rs6000_always_hint
= TARGET_ALWAYS_HINT
;
3028 if (TARGET_SCHED_GROUPS
>= 0)
3029 rs6000_sched_groups
= TARGET_SCHED_GROUPS
;
3031 if (TARGET_ALIGN_BRANCH_TARGETS
>= 0)
3032 rs6000_align_branch_targets
= TARGET_ALIGN_BRANCH_TARGETS
;
3034 rs6000_sched_restricted_insns_priority
3035 = (rs6000_sched_groups
? 1 : 0);
3037 /* Handle -msched-costly-dep option. */
3038 rs6000_sched_costly_dep
3039 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
3041 if (rs6000_sched_costly_dep_str
)
3043 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
3044 rs6000_sched_costly_dep
= no_dep_costly
;
3045 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
3046 rs6000_sched_costly_dep
= all_deps_costly
;
3047 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
3048 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
3049 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
3050 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
3052 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
3053 atoi (rs6000_sched_costly_dep_str
));
3056 /* Handle -minsert-sched-nops option. */
3057 rs6000_sched_insert_nops
3058 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
3060 if (rs6000_sched_insert_nops_str
)
3062 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
3063 rs6000_sched_insert_nops
= sched_finish_none
;
3064 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
3065 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
3066 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
3067 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
3069 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
3070 atoi (rs6000_sched_insert_nops_str
));
3075 #ifdef TARGET_REGNAMES
3076 /* If the user desires alternate register names, copy in the
3077 alternate names now. */
3078 if (TARGET_REGNAMES
)
3079 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
3082 /* Set aix_struct_return last, after the ABI is determined.
3083 If -maix-struct-return or -msvr4-struct-return was explicitly
3084 used, don't override with the ABI default. */
3085 if (!global_options_set
.x_aix_struct_return
)
3086 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
3089 /* IBM XL compiler defaults to unsigned bitfields. */
3090 if (TARGET_XL_COMPAT
)
3091 flag_signed_bitfields
= 0;
3094 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
3095 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
3098 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
3100 /* We can only guarantee the availability of DI pseudo-ops when
3101 assembling for 64-bit targets. */
3104 targetm
.asm_out
.aligned_op
.di
= NULL
;
3105 targetm
.asm_out
.unaligned_op
.di
= NULL
;
3109 /* Set branch target alignment, if not optimizing for size. */
3112 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3113 aligned 8byte to avoid misprediction by the branch predictor. */
3114 if (rs6000_cpu
== PROCESSOR_TITAN
3115 || rs6000_cpu
== PROCESSOR_CELL
)
3117 if (align_functions
<= 0)
3118 align_functions
= 8;
3119 if (align_jumps
<= 0)
3121 if (align_loops
<= 0)
3124 if (rs6000_align_branch_targets
)
3126 if (align_functions
<= 0)
3127 align_functions
= 16;
3128 if (align_jumps
<= 0)
3130 if (align_loops
<= 0)
3132 can_override_loop_align
= 1;
3136 if (align_jumps_max_skip
<= 0)
3137 align_jumps_max_skip
= 15;
3138 if (align_loops_max_skip
<= 0)
3139 align_loops_max_skip
= 15;
3142 /* Arrange to save and restore machine status around nested functions. */
3143 init_machine_status
= rs6000_init_machine_status
;
3145 /* We should always be splitting complex arguments, but we can't break
3146 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3147 if (DEFAULT_ABI
!= ABI_AIX
)
3148 targetm
.calls
.split_complex_arg
= NULL
;
3151 /* Initialize rs6000_cost with the appropriate target costs. */
3153 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
3157 case PROCESSOR_RIOS1
:
3158 rs6000_cost
= &rios1_cost
;
3161 case PROCESSOR_RIOS2
:
3162 rs6000_cost
= &rios2_cost
;
3165 case PROCESSOR_RS64A
:
3166 rs6000_cost
= &rs64a_cost
;
3169 case PROCESSOR_MPCCORE
:
3170 rs6000_cost
= &mpccore_cost
;
3173 case PROCESSOR_PPC403
:
3174 rs6000_cost
= &ppc403_cost
;
3177 case PROCESSOR_PPC405
:
3178 rs6000_cost
= &ppc405_cost
;
3181 case PROCESSOR_PPC440
:
3182 rs6000_cost
= &ppc440_cost
;
3185 case PROCESSOR_PPC476
:
3186 rs6000_cost
= &ppc476_cost
;
3189 case PROCESSOR_PPC601
:
3190 rs6000_cost
= &ppc601_cost
;
3193 case PROCESSOR_PPC603
:
3194 rs6000_cost
= &ppc603_cost
;
3197 case PROCESSOR_PPC604
:
3198 rs6000_cost
= &ppc604_cost
;
3201 case PROCESSOR_PPC604e
:
3202 rs6000_cost
= &ppc604e_cost
;
3205 case PROCESSOR_PPC620
:
3206 rs6000_cost
= &ppc620_cost
;
3209 case PROCESSOR_PPC630
:
3210 rs6000_cost
= &ppc630_cost
;
3213 case PROCESSOR_CELL
:
3214 rs6000_cost
= &ppccell_cost
;
3217 case PROCESSOR_PPC750
:
3218 case PROCESSOR_PPC7400
:
3219 rs6000_cost
= &ppc750_cost
;
3222 case PROCESSOR_PPC7450
:
3223 rs6000_cost
= &ppc7450_cost
;
3226 case PROCESSOR_PPC8540
:
3227 rs6000_cost
= &ppc8540_cost
;
3230 case PROCESSOR_PPCE300C2
:
3231 case PROCESSOR_PPCE300C3
:
3232 rs6000_cost
= &ppce300c2c3_cost
;
3235 case PROCESSOR_PPCE500MC
:
3236 rs6000_cost
= &ppce500mc_cost
;
3239 case PROCESSOR_PPCE500MC64
:
3240 rs6000_cost
= &ppce500mc64_cost
;
3243 case PROCESSOR_TITAN
:
3244 rs6000_cost
= &titan_cost
;
3247 case PROCESSOR_POWER4
:
3248 case PROCESSOR_POWER5
:
3249 rs6000_cost
= &power4_cost
;
3252 case PROCESSOR_POWER6
:
3253 rs6000_cost
= &power6_cost
;
3256 case PROCESSOR_POWER7
:
3257 rs6000_cost
= &power7_cost
;
3260 case PROCESSOR_PPCA2
:
3261 rs6000_cost
= &ppca2_cost
;
3270 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES
,
3271 rs6000_cost
->simultaneous_prefetches
,
3272 global_options
.x_param_values
,
3273 global_options_set
.x_param_values
);
3274 maybe_set_param_value (PARAM_L1_CACHE_SIZE
, rs6000_cost
->l1_cache_size
,
3275 global_options
.x_param_values
,
3276 global_options_set
.x_param_values
);
3277 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE
,
3278 rs6000_cost
->cache_line_size
,
3279 global_options
.x_param_values
,
3280 global_options_set
.x_param_values
);
3281 maybe_set_param_value (PARAM_L2_CACHE_SIZE
, rs6000_cost
->l2_cache_size
,
3282 global_options
.x_param_values
,
3283 global_options_set
.x_param_values
);
3285 /* If using typedef char *va_list, signal that
3286 __builtin_va_start (&ap, 0) can be optimized to
3287 ap = __builtin_next_arg (0). */
3288 if (DEFAULT_ABI
!= ABI_V4
)
3289 targetm
.expand_builtin_va_start
= NULL
;
3292 /* Set up single/double float flags.
3293 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3294 then set both flags. */
3295 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
3296 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
3297 rs6000_single_float
= rs6000_double_float
= 1;
3299 /* Reset single and double FP flags if target is E500. */
3302 rs6000_single_float
= rs6000_double_float
= 0;
3303 if (TARGET_E500_SINGLE
)
3304 rs6000_single_float
= 1;
3305 if (TARGET_E500_DOUBLE
)
3306 rs6000_single_float
= rs6000_double_float
= 1;
3309 if (main_target_opt
)
3311 if (main_target_opt
->x_rs6000_single_float
!= rs6000_single_float
)
3312 error ("target attribute or pragma changes single precision floating "
3314 if (main_target_opt
->x_rs6000_double_float
!= rs6000_double_float
)
3315 error ("target attribute or pragma changes double precision floating "
3319 /* If not explicitly specified via option, decide whether to generate indexed
3320 load/store instructions. */
3321 if (TARGET_AVOID_XFORM
== -1)
3322 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3323 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3324 need indexed accesses and the type used is the scalar type of the element
3325 being loaded or stored. */
3326 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
3327 && !TARGET_ALTIVEC
);
3329 /* Set the -mrecip options. */
3330 if (rs6000_recip_name
)
3332 char *p
= ASTRDUP (rs6000_recip_name
);
3334 unsigned int mask
, i
;
3337 while ((q
= strtok (p
, ",")) != NULL
)
3348 if (!strcmp (q
, "default"))
3349 mask
= ((TARGET_RECIP_PRECISION
)
3350 ? RECIP_HIGH_PRECISION
: RECIP_LOW_PRECISION
);
3353 for (i
= 0; i
< ARRAY_SIZE (recip_options
); i
++)
3354 if (!strcmp (q
, recip_options
[i
].string
))
3356 mask
= recip_options
[i
].mask
;
3360 if (i
== ARRAY_SIZE (recip_options
))
3362 error ("unknown option for -mrecip=%s", q
);
3370 rs6000_recip_control
&= ~mask
;
3372 rs6000_recip_control
|= mask
;
3376 rs6000_init_hard_regno_mode_ok (global_init_p
);
3378 /* Save the initial options in case the user does function specific options */
3380 target_option_default_node
= target_option_current_node
3381 = build_target_option_node ();
3386 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3387 define the target cpu type. */
3390 rs6000_option_override (void)
3392 (void) rs6000_option_override_internal (true);
3396 /* Implement targetm.vectorize.builtin_mask_for_load. */
3398 rs6000_builtin_mask_for_load (void)
3400 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3401 return altivec_builtin_mask_for_load
;
3406 /* Implement LOOP_ALIGN. */
3408 rs6000_loop_align (rtx label
)
3413 /* Don't override loop alignment if -falign-loops was specified. */
3414 if (!can_override_loop_align
)
3415 return align_loops_log
;
3417 bb
= BLOCK_FOR_INSN (label
);
3418 ninsns
= num_loop_insns(bb
->loop_father
);
3420 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3421 if (ninsns
> 4 && ninsns
<= 8
3422 && (rs6000_cpu
== PROCESSOR_POWER4
3423 || rs6000_cpu
== PROCESSOR_POWER5
3424 || rs6000_cpu
== PROCESSOR_POWER6
3425 || rs6000_cpu
== PROCESSOR_POWER7
))
3428 return align_loops_log
;
3431 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3433 rs6000_loop_align_max_skip (rtx label
)
3435 return (1 << rs6000_loop_align (label
)) - 1;
3438 /* Implement targetm.vectorize.builtin_conversion.
3439 Returns a decl of a function that implements conversion of an integer vector
3440 into a floating-point vector, or vice-versa. DEST_TYPE is the
3441 destination type and SRC_TYPE the source type of the conversion.
3442 Return NULL_TREE if it is not available. */
3444 rs6000_builtin_conversion (unsigned int tcode
, tree dest_type
, tree src_type
)
3446 enum tree_code code
= (enum tree_code
) tcode
;
3450 case FIX_TRUNC_EXPR
:
3451 switch (TYPE_MODE (dest_type
))
3454 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3457 return TYPE_UNSIGNED (dest_type
)
3458 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPUXDS_UNS
]
3459 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPSXDS
];
3462 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3465 return TYPE_UNSIGNED (dest_type
)
3466 ? rs6000_builtin_decls
[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
]
3467 : rs6000_builtin_decls
[VECTOR_BUILTIN_FIX_V4SF_V4SI
];
3474 switch (TYPE_MODE (src_type
))
3477 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3480 return TYPE_UNSIGNED (src_type
)
3481 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVUXDDP
]
3482 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVSXDDP
];
3485 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3488 return TYPE_UNSIGNED (src_type
)
3489 ? rs6000_builtin_decls
[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
]
3490 : rs6000_builtin_decls
[VECTOR_BUILTIN_FLOAT_V4SI_V4SF
];
3501 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3503 rs6000_builtin_mul_widen_even (tree type
)
3505 if (!TARGET_ALTIVEC
)
3508 switch (TYPE_MODE (type
))
3511 return TYPE_UNSIGNED (type
)
3512 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH_UNS
]
3513 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
3516 return TYPE_UNSIGNED (type
)
3517 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB_UNS
]
3518 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
3524 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3526 rs6000_builtin_mul_widen_odd (tree type
)
3528 if (!TARGET_ALTIVEC
)
3531 switch (TYPE_MODE (type
))
3534 return TYPE_UNSIGNED (type
)
3535 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH_UNS
]
3536 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
3539 return TYPE_UNSIGNED (type
)
3540 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB_UNS
]
3541 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
3548 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3549 after applying N number of iterations. This routine does not determine
3550 how may iterations are required to reach desired alignment. */
3553 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
3560 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
3563 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
3573 /* Assuming that all other types are naturally aligned. CHECKME! */
3578 /* Return true if the vector misalignment factor is supported by the
3581 rs6000_builtin_support_vector_misalignment (enum machine_mode mode
,
3588 /* Return if movmisalign pattern is not supported for this mode. */
3589 if (optab_handler (movmisalign_optab
, mode
) == CODE_FOR_nothing
)
3592 if (misalignment
== -1)
3594 /* Misalignment factor is unknown at compile time but we know
3595 it's word aligned. */
3596 if (rs6000_vector_alignment_reachable (type
, is_packed
))
3598 int element_size
= TREE_INT_CST_LOW (TYPE_SIZE (type
));
3600 if (element_size
== 64 || element_size
== 32)
3607 /* VSX supports word-aligned vector. */
3608 if (misalignment
% 4 == 0)
3614 /* Implement targetm.vectorize.builtin_vec_perm. */
3616 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
3618 tree inner_type
= TREE_TYPE (type
);
3619 bool uns_p
= TYPE_UNSIGNED (inner_type
);
3622 *mask_element_type
= unsigned_char_type_node
;
3624 switch (TYPE_MODE (type
))
3628 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI_UNS
]
3629 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
]);
3634 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI_UNS
]
3635 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
]);
3640 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI_UNS
]
3641 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
]);
3645 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
3649 if (!TARGET_ALLOW_DF_PERMUTE
)
3652 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DF
];
3656 if (!TARGET_ALLOW_DF_PERMUTE
)
3660 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI_UNS
]
3661 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI
]);
3673 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3675 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost
,
3676 tree vectype
, int misalign
)
3680 switch (type_of_cost
)
3690 case cond_branch_not_taken
:
3694 case cond_branch_taken
:
3697 case unaligned_load
:
3698 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3700 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3702 /* Double word aligned. */
3710 /* Double word aligned. */
3714 /* Unknown misalignment. */
3727 /* Misaligned loads are not supported. */
3732 case unaligned_store
:
3733 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3735 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3737 /* Double word aligned. */
3745 /* Double word aligned. */
3749 /* Unknown misalignment. */
3762 /* Misaligned stores are not supported. */
3772 /* Implement targetm.vectorize.preferred_simd_mode. */
3774 static enum machine_mode
3775 rs6000_preferred_simd_mode (enum machine_mode mode
)
3784 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3808 if (TARGET_PAIRED_FLOAT
3814 /* Implement TARGET_OPTION_INIT_STRUCT. */
3817 rs6000_option_init_struct (struct gcc_options
*opts
)
3819 if (DEFAULT_ABI
== ABI_DARWIN
)
3820 /* The Darwin libraries never set errno, so we might as well
3821 avoid calling them when that's the only reason we would. */
3822 opts
->x_flag_errno_math
= 0;
3824 /* Enable section anchors by default. */
3826 opts
->x_flag_section_anchors
= 1;
3829 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3832 rs6000_option_default_params (void)
3834 /* Double growth factor to counter reduced min jump length. */
3835 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS
, 16);
3838 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3839 library with vectorized intrinsics. */
3842 rs6000_builtin_vectorized_libmass (tree fndecl
, tree type_out
, tree type_in
)
3845 const char *suffix
= NULL
;
3846 tree fntype
, new_fndecl
, bdecl
= NULL_TREE
;
3849 enum machine_mode el_mode
, in_mode
;
3852 /* Libmass is suitable for unsafe math only as it does not correctly support
3853 parts of IEEE with the required precision such as denormals. Only support
3854 it if we have VSX to use the simd d2 or f4 functions.
3855 XXX: Add variable length support. */
3856 if (!flag_unsafe_math_optimizations
|| !TARGET_VSX
)
3859 el_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3860 n
= TYPE_VECTOR_SUBPARTS (type_out
);
3861 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3862 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3863 if (el_mode
!= in_mode
3867 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3869 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3872 case BUILT_IN_ATAN2
:
3873 case BUILT_IN_HYPOT
:
3879 case BUILT_IN_ACOSH
:
3881 case BUILT_IN_ASINH
:
3883 case BUILT_IN_ATANH
:
3891 case BUILT_IN_EXPM1
:
3892 case BUILT_IN_LGAMMA
:
3893 case BUILT_IN_LOG10
:
3894 case BUILT_IN_LOG1P
:
3902 bdecl
= implicit_built_in_decls
[fn
];
3903 suffix
= "d2"; /* pow -> powd2 */
3904 if (el_mode
!= DFmode
3909 case BUILT_IN_ATAN2F
:
3910 case BUILT_IN_HYPOTF
:
3915 case BUILT_IN_ACOSF
:
3916 case BUILT_IN_ACOSHF
:
3917 case BUILT_IN_ASINF
:
3918 case BUILT_IN_ASINHF
:
3919 case BUILT_IN_ATANF
:
3920 case BUILT_IN_ATANHF
:
3921 case BUILT_IN_CBRTF
:
3923 case BUILT_IN_COSHF
:
3925 case BUILT_IN_ERFCF
:
3926 case BUILT_IN_EXP2F
:
3928 case BUILT_IN_EXPM1F
:
3929 case BUILT_IN_LGAMMAF
:
3930 case BUILT_IN_LOG10F
:
3931 case BUILT_IN_LOG1PF
:
3932 case BUILT_IN_LOG2F
:
3935 case BUILT_IN_SINHF
:
3936 case BUILT_IN_SQRTF
:
3938 case BUILT_IN_TANHF
:
3939 bdecl
= implicit_built_in_decls
[fn
];
3940 suffix
= "4"; /* powf -> powf4 */
3941 if (el_mode
!= SFmode
3953 gcc_assert (suffix
!= NULL
);
3954 bname
= IDENTIFIER_POINTER (DECL_NAME (bdecl
));
3955 strcpy (name
, bname
+ sizeof ("__builtin_") - 1);
3956 strcat (name
, suffix
);
3959 fntype
= build_function_type_list (type_out
, type_in
, NULL
);
3960 else if (n_args
== 2)
3961 fntype
= build_function_type_list (type_out
, type_in
, type_in
, NULL
);
3965 /* Build a function declaration for the vectorized function. */
3966 new_fndecl
= build_decl (BUILTINS_LOCATION
,
3967 FUNCTION_DECL
, get_identifier (name
), fntype
);
3968 TREE_PUBLIC (new_fndecl
) = 1;
3969 DECL_EXTERNAL (new_fndecl
) = 1;
3970 DECL_IS_NOVOPS (new_fndecl
) = 1;
3971 TREE_READONLY (new_fndecl
) = 1;
3976 /* Returns a function decl for a vectorized version of the builtin function
3977 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3978 if it is not available. */
3981 rs6000_builtin_vectorized_function (tree fndecl
, tree type_out
,
3984 enum machine_mode in_mode
, out_mode
;
3987 if (TREE_CODE (type_out
) != VECTOR_TYPE
3988 || TREE_CODE (type_in
) != VECTOR_TYPE
3989 || !TARGET_VECTORIZE_BUILTINS
)
3992 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3993 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
3994 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3995 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3997 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3999 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
4002 case BUILT_IN_COPYSIGN
:
4003 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4004 && out_mode
== DFmode
&& out_n
== 2
4005 && in_mode
== DFmode
&& in_n
== 2)
4006 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNDP
];
4008 case BUILT_IN_COPYSIGNF
:
4009 if (out_mode
!= SFmode
|| out_n
!= 4
4010 || in_mode
!= SFmode
|| in_n
!= 4)
4012 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4013 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNSP
];
4014 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4015 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_COPYSIGN_V4SF
];
4018 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4019 && out_mode
== DFmode
&& out_n
== 2
4020 && in_mode
== DFmode
&& in_n
== 2)
4021 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTDP
];
4023 case BUILT_IN_SQRTF
:
4024 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4025 && out_mode
== SFmode
&& out_n
== 4
4026 && in_mode
== SFmode
&& in_n
== 4)
4027 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTSP
];
4030 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4031 && out_mode
== DFmode
&& out_n
== 2
4032 && in_mode
== DFmode
&& in_n
== 2)
4033 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIP
];
4035 case BUILT_IN_CEILF
:
4036 if (out_mode
!= SFmode
|| out_n
!= 4
4037 || in_mode
!= SFmode
|| in_n
!= 4)
4039 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4040 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIP
];
4041 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4042 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIP
];
4044 case BUILT_IN_FLOOR
:
4045 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4046 && out_mode
== DFmode
&& out_n
== 2
4047 && in_mode
== DFmode
&& in_n
== 2)
4048 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIM
];
4050 case BUILT_IN_FLOORF
:
4051 if (out_mode
!= SFmode
|| out_n
!= 4
4052 || in_mode
!= SFmode
|| in_n
!= 4)
4054 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4055 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIM
];
4056 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4057 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIM
];
4060 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4061 && out_mode
== DFmode
&& out_n
== 2
4062 && in_mode
== DFmode
&& in_n
== 2)
4063 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDDP
];
4066 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4067 && out_mode
== SFmode
&& out_n
== 4
4068 && in_mode
== SFmode
&& in_n
== 4)
4069 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDSP
];
4070 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
)
4071 && out_mode
== SFmode
&& out_n
== 4
4072 && in_mode
== SFmode
&& in_n
== 4)
4073 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMADDFP
];
4075 case BUILT_IN_TRUNC
:
4076 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4077 && out_mode
== DFmode
&& out_n
== 2
4078 && in_mode
== DFmode
&& in_n
== 2)
4079 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIZ
];
4081 case BUILT_IN_TRUNCF
:
4082 if (out_mode
!= SFmode
|| out_n
!= 4
4083 || in_mode
!= SFmode
|| in_n
!= 4)
4085 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4086 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIZ
];
4087 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4088 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIZ
];
4090 case BUILT_IN_NEARBYINT
:
4091 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4092 && flag_unsafe_math_optimizations
4093 && out_mode
== DFmode
&& out_n
== 2
4094 && in_mode
== DFmode
&& in_n
== 2)
4095 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPI
];
4097 case BUILT_IN_NEARBYINTF
:
4098 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4099 && flag_unsafe_math_optimizations
4100 && out_mode
== SFmode
&& out_n
== 4
4101 && in_mode
== SFmode
&& in_n
== 4)
4102 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPI
];
4105 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4106 && !flag_trapping_math
4107 && out_mode
== DFmode
&& out_n
== 2
4108 && in_mode
== DFmode
&& in_n
== 2)
4109 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIC
];
4111 case BUILT_IN_RINTF
:
4112 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4113 && !flag_trapping_math
4114 && out_mode
== SFmode
&& out_n
== 4
4115 && in_mode
== SFmode
&& in_n
== 4)
4116 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIC
];
4123 else if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4125 enum rs6000_builtins fn
4126 = (enum rs6000_builtins
)DECL_FUNCTION_CODE (fndecl
);
4129 case RS6000_BUILTIN_RSQRTF
:
4130 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
4131 && out_mode
== SFmode
&& out_n
== 4
4132 && in_mode
== SFmode
&& in_n
== 4)
4133 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRSQRTFP
];
4135 case RS6000_BUILTIN_RSQRT
:
4136 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4137 && out_mode
== DFmode
&& out_n
== 2
4138 && in_mode
== DFmode
&& in_n
== 2)
4139 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
4141 case RS6000_BUILTIN_RECIPF
:
4142 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
4143 && out_mode
== SFmode
&& out_n
== 4
4144 && in_mode
== SFmode
&& in_n
== 4)
4145 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRECIPFP
];
4147 case RS6000_BUILTIN_RECIP
:
4148 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4149 && out_mode
== DFmode
&& out_n
== 2
4150 && in_mode
== DFmode
&& in_n
== 2)
4151 return rs6000_builtin_decls
[VSX_BUILTIN_RECIP_V2DF
];
4158 /* Generate calls to libmass if appropriate. */
4159 if (rs6000_veclib_handler
)
4160 return rs6000_veclib_handler (fndecl
, type_out
, type_in
);
4166 /* Implement TARGET_HANDLE_OPTION. */
4169 rs6000_handle_option (struct gcc_options
*opts
, struct gcc_options
*opts_set
,
4170 const struct cl_decoded_option
*decoded
,
4173 enum fpu_type_t fpu_type
= FPU_NONE
;
4175 size_t code
= decoded
->opt_index
;
4176 const char *arg
= decoded
->arg
;
4177 int value
= decoded
->value
;
4179 gcc_assert (opts
== &global_options
);
4180 gcc_assert (opts_set
== &global_options_set
);
4185 opts
->x_target_flags
&= ~(MASK_POWER
| MASK_POWER2
4186 | MASK_MULTIPLE
| MASK_STRING
);
4187 opts_set
->x_target_flags
|= (MASK_POWER
| MASK_POWER2
4188 | MASK_MULTIPLE
| MASK_STRING
);
4190 case OPT_mno_powerpc
:
4191 opts
->x_target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
4192 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
4193 opts_set
->x_target_flags
|= (MASK_POWERPC
| MASK_PPC_GPOPT
4194 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
4197 opts
->x_target_flags
&= ~MASK_MINIMAL_TOC
;
4198 opts
->x_TARGET_NO_FP_IN_TOC
= 0;
4199 opts
->x_TARGET_NO_SUM_IN_TOC
= 0;
4200 opts_set
->x_target_flags
|= MASK_MINIMAL_TOC
;
4201 #ifdef TARGET_USES_SYSV4_OPT
4202 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4203 just the same as -mminimal-toc. */
4204 opts
->x_target_flags
|= MASK_MINIMAL_TOC
;
4205 opts_set
->x_target_flags
|= MASK_MINIMAL_TOC
;
4209 #ifdef TARGET_USES_SYSV4_OPT
4211 /* Make -mtoc behave like -mminimal-toc. */
4212 opts
->x_target_flags
|= MASK_MINIMAL_TOC
;
4213 opts_set
->x_target_flags
|= MASK_MINIMAL_TOC
;
4217 #ifdef TARGET_USES_AIX64_OPT
4222 opts
->x_target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
4223 opts
->x_target_flags
|= ~opts_set
->x_target_flags
& MASK_PPC_GFXOPT
;
4224 opts_set
->x_target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
4227 #ifdef TARGET_USES_AIX64_OPT
4232 opts
->x_target_flags
&= ~MASK_POWERPC64
;
4233 opts_set
->x_target_flags
|= MASK_POWERPC64
;
4236 case OPT_mminimal_toc
:
4239 opts
->x_TARGET_NO_FP_IN_TOC
= 0;
4240 opts
->x_TARGET_NO_SUM_IN_TOC
= 0;
4247 opts
->x_target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
4248 opts_set
->x_target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
4255 opts
->x_target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
4256 opts_set
->x_target_flags
|= (MASK_POWER
4262 case OPT_mpowerpc_gpopt
:
4263 case OPT_mpowerpc_gfxopt
:
4266 opts
->x_target_flags
|= MASK_POWERPC
;
4267 opts_set
->x_target_flags
|= MASK_POWERPC
;
4273 opts
->x_rs6000_debug
= 0;
4275 while ((q
= strtok (p
, ",")) != NULL
)
4289 if (! strcmp (q
, "all"))
4290 mask
= MASK_DEBUG_ALL
;
4291 else if (! strcmp (q
, "stack"))
4292 mask
= MASK_DEBUG_STACK
;
4293 else if (! strcmp (q
, "arg"))
4294 mask
= MASK_DEBUG_ARG
;
4295 else if (! strcmp (q
, "reg"))
4296 mask
= MASK_DEBUG_REG
;
4297 else if (! strcmp (q
, "addr"))
4298 mask
= MASK_DEBUG_ADDR
;
4299 else if (! strcmp (q
, "cost"))
4300 mask
= MASK_DEBUG_COST
;
4301 else if (! strcmp (q
, "target"))
4302 mask
= MASK_DEBUG_TARGET
;
4304 error_at (loc
, "unknown -mdebug-%s switch", q
);
4307 opts
->x_rs6000_debug
&= ~mask
;
4309 opts
->x_rs6000_debug
|= mask
;
4313 #ifdef TARGET_USES_SYSV4_OPT
4314 case OPT_mrelocatable
:
4317 opts
->x_target_flags
|= MASK_MINIMAL_TOC
;
4318 opts_set
->x_target_flags
|= MASK_MINIMAL_TOC
;
4319 opts
->x_TARGET_NO_FP_IN_TOC
= 1;
4323 case OPT_mrelocatable_lib
:
4326 opts
->x_target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4327 opts_set
->x_target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4328 opts
->x_TARGET_NO_FP_IN_TOC
= 1;
4332 opts
->x_target_flags
&= ~MASK_RELOCATABLE
;
4333 opts_set
->x_target_flags
|= MASK_RELOCATABLE
;
4339 if (!strcmp (arg
, "altivec"))
4341 opts_set
->x_rs6000_altivec_abi
= true;
4342 opts
->x_rs6000_altivec_abi
= 1;
4344 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4345 opts
->x_rs6000_spe_abi
= 0;
4347 else if (! strcmp (arg
, "no-altivec"))
4349 opts_set
->x_rs6000_altivec_abi
= true;
4350 opts
->x_rs6000_altivec_abi
= 0;
4352 else if (! strcmp (arg
, "spe"))
4354 opts_set
->x_rs6000_spe_abi
= true;
4355 opts
->x_rs6000_spe_abi
= 1;
4356 opts
->x_rs6000_altivec_abi
= 0;
4357 if (!TARGET_SPE_ABI
)
4358 error_at (loc
, "not configured for ABI: '%s'", arg
);
4360 else if (! strcmp (arg
, "no-spe"))
4362 opts_set
->x_rs6000_spe_abi
= true;
4363 opts
->x_rs6000_spe_abi
= 0;
4366 /* These are here for testing during development only, do not
4367 document in the manual please. */
4368 else if (! strcmp (arg
, "d64"))
4370 opts
->x_rs6000_darwin64_abi
= 1;
4371 warning_at (loc
, 0, "using darwin64 ABI");
4373 else if (! strcmp (arg
, "d32"))
4375 opts
->x_rs6000_darwin64_abi
= 0;
4376 warning_at (loc
, 0, "using old darwin ABI");
4379 else if (! strcmp (arg
, "ibmlongdouble"))
4381 opts_set
->x_rs6000_ieeequad
= true;
4382 opts
->x_rs6000_ieeequad
= 0;
4383 warning_at (loc
, 0, "using IBM extended precision long double");
4385 else if (! strcmp (arg
, "ieeelongdouble"))
4387 opts_set
->x_rs6000_ieeequad
= true;
4388 opts
->x_rs6000_ieeequad
= 1;
4389 warning_at (loc
, 0, "using IEEE extended precision long double");
4394 error_at (loc
, "unknown ABI specified: '%s'", arg
);
4400 rs6000_select
[1].string
= arg
;
4401 opts
->x_rs6000_cpu_index
= rs6000_cpu_name_lookup (arg
);
4402 if (opts
->x_rs6000_cpu_index
< 0)
4403 error_at (loc
, "bad value (%s) for -mcpu", arg
);
4407 rs6000_select
[2].string
= arg
;
4408 opts
->x_rs6000_tune_index
= rs6000_cpu_name_lookup (arg
);
4409 if (opts
->x_rs6000_tune_index
< 0)
4410 error_at (loc
, "bad value (%s) for -mtune", arg
);
4413 case OPT_mlong_double_
:
4414 if (value
!= 64 && value
!= 128)
4416 error_at (loc
, "unknown switch -mlong-double-%s", arg
);
4417 opts
->x_rs6000_long_double_type_size
4418 = RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
4423 case OPT_msingle_float
:
4424 if (!TARGET_SINGLE_FPU
)
4426 "-msingle-float option equivalent to -mhard-float");
4427 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4428 opts
->x_rs6000_double_float
= 0;
4429 opts
->x_target_flags
&= ~MASK_SOFT_FLOAT
;
4430 opts_set
->x_target_flags
|= MASK_SOFT_FLOAT
;
4433 case OPT_mdouble_float
:
4434 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4435 opts
->x_rs6000_single_float
= 1;
4436 opts
->x_target_flags
&= ~MASK_SOFT_FLOAT
;
4437 opts_set
->x_target_flags
|= MASK_SOFT_FLOAT
;
4440 case OPT_msimple_fpu
:
4441 if (!TARGET_SINGLE_FPU
)
4442 warning_at (loc
, 0, "-msimple-fpu option ignored");
4445 case OPT_mhard_float
:
4446 /* -mhard_float implies -msingle-float and -mdouble-float. */
4447 opts
->x_rs6000_single_float
= opts
->x_rs6000_double_float
= 1;
4450 case OPT_msoft_float
:
4451 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4452 opts
->x_rs6000_single_float
= opts
->x_rs6000_double_float
= 0;
4456 fpu_type
= (enum fpu_type_t
) value
;
4457 if (fpu_type
!= FPU_NONE
)
4459 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on
4461 opts
->x_target_flags
&= ~MASK_SOFT_FLOAT
;
4462 opts_set
->x_target_flags
|= MASK_SOFT_FLOAT
;
4463 opts
->x_rs6000_xilinx_fpu
= 1;
4464 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_SF_FULL
)
4465 opts
->x_rs6000_single_float
= 1;
4466 if (fpu_type
== FPU_DF_LITE
|| fpu_type
== FPU_DF_FULL
)
4467 opts
->x_rs6000_single_float
= opts
->x_rs6000_double_float
= 1;
4468 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_DF_LITE
)
4469 opts
->x_rs6000_simple_fpu
= 1;
4473 /* -mfpu=none is equivalent to -msoft-float. */
4474 opts
->x_target_flags
|= MASK_SOFT_FLOAT
;
4475 opts_set
->x_target_flags
|= MASK_SOFT_FLOAT
;
4476 opts
->x_rs6000_single_float
= opts
->x_rs6000_double_float
= 0;
4481 opts
->x_rs6000_recip_name
= (value
) ? "default" : "none";
4487 /* Do anything needed at the start of the asm file. */
4490 rs6000_file_start (void)
4494 const char *start
= buffer
;
4495 struct rs6000_cpu_select
*ptr
;
4496 const char *default_cpu
= TARGET_CPU_DEFAULT
;
4497 FILE *file
= asm_out_file
;
4499 default_file_start ();
4501 #ifdef TARGET_BI_ARCH
4502 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
4506 if (flag_verbose_asm
)
4508 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
4509 rs6000_select
[0].string
= default_cpu
;
4511 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
4513 ptr
= &rs6000_select
[i
];
4514 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
4516 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
4521 if (PPC405_ERRATUM77
)
4523 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
4527 #ifdef USING_ELFOS_H
4528 switch (rs6000_sdata
)
4530 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
4531 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
4532 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
4533 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
4536 if (rs6000_sdata
&& g_switch_value
)
4538 fprintf (file
, "%s -G %d", start
,
4548 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
4550 switch_to_section (toc_section
);
4551 switch_to_section (text_section
);
4556 /* Return nonzero if this function is known to have a null epilogue. */
4559 direct_return (void)
4561 if (reload_completed
)
4563 rs6000_stack_t
*info
= rs6000_stack_info ();
4565 if (info
->first_gp_reg_save
== 32
4566 && info
->first_fp_reg_save
== 64
4567 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
4568 && ! info
->lr_save_p
4569 && ! info
->cr_save_p
4570 && info
->vrsave_mask
== 0
4578 /* Return the number of instructions it takes to form a constant in an
4579 integer register. */
4582 num_insns_constant_wide (HOST_WIDE_INT value
)
4584 /* signed constant loadable with {cal|addi} */
4585 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
4588 /* constant loadable with {cau|addis} */
4589 else if ((value
& 0xffff) == 0
4590 && (value
>> 31 == -1 || value
>> 31 == 0))
4593 #if HOST_BITS_PER_WIDE_INT == 64
4594 else if (TARGET_POWERPC64
)
4596 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
4597 HOST_WIDE_INT high
= value
>> 31;
4599 if (high
== 0 || high
== -1)
4605 return num_insns_constant_wide (high
) + 1;
4607 return num_insns_constant_wide (low
) + 1;
4609 return (num_insns_constant_wide (high
)
4610 + num_insns_constant_wide (low
) + 1);
4619 num_insns_constant (rtx op
, enum machine_mode mode
)
4621 HOST_WIDE_INT low
, high
;
4623 switch (GET_CODE (op
))
4626 #if HOST_BITS_PER_WIDE_INT == 64
4627 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
4628 && mask64_operand (op
, mode
))
4632 return num_insns_constant_wide (INTVAL (op
));
4635 if (mode
== SFmode
|| mode
== SDmode
)
4640 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4641 if (DECIMAL_FLOAT_MODE_P (mode
))
4642 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
4644 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
4645 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
4648 if (mode
== VOIDmode
|| mode
== DImode
)
4650 high
= CONST_DOUBLE_HIGH (op
);
4651 low
= CONST_DOUBLE_LOW (op
);
4658 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4659 if (DECIMAL_FLOAT_MODE_P (mode
))
4660 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
4662 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
4663 high
= l
[WORDS_BIG_ENDIAN
== 0];
4664 low
= l
[WORDS_BIG_ENDIAN
!= 0];
4668 return (num_insns_constant_wide (low
)
4669 + num_insns_constant_wide (high
));
4672 if ((high
== 0 && low
>= 0)
4673 || (high
== -1 && low
< 0))
4674 return num_insns_constant_wide (low
);
4676 else if (mask64_operand (op
, mode
))
4680 return num_insns_constant_wide (high
) + 1;
4683 return (num_insns_constant_wide (high
)
4684 + num_insns_constant_wide (low
) + 1);
4692 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4693 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4694 corresponding element of the vector, but for V4SFmode and V2SFmode,
4695 the corresponding "float" is interpreted as an SImode integer. */
4698 const_vector_elt_as_int (rtx op
, unsigned int elt
)
4702 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4703 gcc_assert (GET_MODE (op
) != V2DImode
4704 && GET_MODE (op
) != V2DFmode
);
4706 tmp
= CONST_VECTOR_ELT (op
, elt
);
4707 if (GET_MODE (op
) == V4SFmode
4708 || GET_MODE (op
) == V2SFmode
)
4709 tmp
= gen_lowpart (SImode
, tmp
);
4710 return INTVAL (tmp
);
4713 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4714 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4715 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4716 all items are set to the same value and contain COPIES replicas of the
4717 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4718 operand and the others are set to the value of the operand's msb. */
4721 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
4723 enum machine_mode mode
= GET_MODE (op
);
4724 enum machine_mode inner
= GET_MODE_INNER (mode
);
4732 HOST_WIDE_INT splat_val
;
4733 HOST_WIDE_INT msb_val
;
4735 if (mode
== V2DImode
|| mode
== V2DFmode
)
4738 nunits
= GET_MODE_NUNITS (mode
);
4739 bitsize
= GET_MODE_BITSIZE (inner
);
4740 mask
= GET_MODE_MASK (inner
);
4742 val
= const_vector_elt_as_int (op
, nunits
- 1);
4744 msb_val
= val
> 0 ? 0 : -1;
4746 /* Construct the value to be splatted, if possible. If not, return 0. */
4747 for (i
= 2; i
<= copies
; i
*= 2)
4749 HOST_WIDE_INT small_val
;
4751 small_val
= splat_val
>> bitsize
;
4753 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
4755 splat_val
= small_val
;
4758 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4759 if (EASY_VECTOR_15 (splat_val
))
4762 /* Also check if we can splat, and then add the result to itself. Do so if
4763 the value is positive, of if the splat instruction is using OP's mode;
4764 for splat_val < 0, the splat and the add should use the same mode. */
4765 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
4766 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
4769 /* Also check if are loading up the most significant bit which can be done by
4770 loading up -1 and shifting the value left by -1. */
4771 else if (EASY_VECTOR_MSB (splat_val
, inner
))
4777 /* Check if VAL is present in every STEP-th element, and the
4778 other elements are filled with its most significant bit. */
4779 for (i
= 0; i
< nunits
- 1; ++i
)
4781 HOST_WIDE_INT desired_val
;
4782 if (((i
+ 1) & (step
- 1)) == 0)
4785 desired_val
= msb_val
;
4787 if (desired_val
!= const_vector_elt_as_int (op
, i
))
4795 /* Return true if OP is of the given MODE and can be synthesized
4796 with a vspltisb, vspltish or vspltisw. */
4799 easy_altivec_constant (rtx op
, enum machine_mode mode
)
4801 unsigned step
, copies
;
4803 if (mode
== VOIDmode
)
4804 mode
= GET_MODE (op
);
4805 else if (mode
!= GET_MODE (op
))
4808 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4810 if (mode
== V2DFmode
)
4811 return zero_constant (op
, mode
);
4813 if (mode
== V2DImode
)
4815 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4817 if (GET_CODE (CONST_VECTOR_ELT (op
, 0)) != CONST_INT
4818 || GET_CODE (CONST_VECTOR_ELT (op
, 1)) != CONST_INT
)
4821 if (zero_constant (op
, mode
))
4824 if (INTVAL (CONST_VECTOR_ELT (op
, 0)) == -1
4825 && INTVAL (CONST_VECTOR_ELT (op
, 1)) == -1)
4831 /* Start with a vspltisw. */
4832 step
= GET_MODE_NUNITS (mode
) / 4;
4835 if (vspltis_constant (op
, step
, copies
))
4838 /* Then try with a vspltish. */
4844 if (vspltis_constant (op
, step
, copies
))
4847 /* And finally a vspltisb. */
4853 if (vspltis_constant (op
, step
, copies
))
4859 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4860 result is OP. Abort if it is not possible. */
4863 gen_easy_altivec_constant (rtx op
)
4865 enum machine_mode mode
= GET_MODE (op
);
4866 int nunits
= GET_MODE_NUNITS (mode
);
4867 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
4868 unsigned step
= nunits
/ 4;
4869 unsigned copies
= 1;
4871 /* Start with a vspltisw. */
4872 if (vspltis_constant (op
, step
, copies
))
4873 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
4875 /* Then try with a vspltish. */
4881 if (vspltis_constant (op
, step
, copies
))
4882 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
4884 /* And finally a vspltisb. */
4890 if (vspltis_constant (op
, step
, copies
))
4891 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
4897 output_vec_const_move (rtx
*operands
)
4900 enum machine_mode mode
;
4905 mode
= GET_MODE (dest
);
4909 if (zero_constant (vec
, mode
))
4910 return "xxlxor %x0,%x0,%x0";
4912 if (mode
== V2DImode
4913 && INTVAL (CONST_VECTOR_ELT (vec
, 0)) == -1
4914 && INTVAL (CONST_VECTOR_ELT (vec
, 1)) == -1)
4915 return "vspltisw %0,-1";
4921 if (zero_constant (vec
, mode
))
4922 return "vxor %0,%0,%0";
4924 splat_vec
= gen_easy_altivec_constant (vec
);
4925 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
4926 operands
[1] = XEXP (splat_vec
, 0);
4927 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
4930 switch (GET_MODE (splat_vec
))
4933 return "vspltisw %0,%1";
4936 return "vspltish %0,%1";
4939 return "vspltisb %0,%1";
4946 gcc_assert (TARGET_SPE
);
4948 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4949 pattern of V1DI, V4HI, and V2SF.
4951 FIXME: We should probably return # and add post reload
4952 splitters for these, but this way is so easy ;-). */
4953 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
4954 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
4955 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
4956 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
4958 return "li %0,%1\n\tevmergelo %0,%0,%0";
4960 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4963 /* Initialize TARGET of vector PAIRED to VALS. */
4966 paired_expand_vector_init (rtx target
, rtx vals
)
4968 enum machine_mode mode
= GET_MODE (target
);
4969 int n_elts
= GET_MODE_NUNITS (mode
);
4971 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
4974 for (i
= 0; i
< n_elts
; ++i
)
4976 x
= XVECEXP (vals
, 0, i
);
4977 if (!CONSTANT_P (x
))
4982 /* Load from constant pool. */
4983 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
4989 /* The vector is initialized only with non-constants. */
4990 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
4991 XVECEXP (vals
, 0, 1));
4993 emit_move_insn (target
, new_rtx
);
4997 /* One field is non-constant and the other one is a constant. Load the
4998 constant from the constant pool and use ps_merge instruction to
4999 construct the whole vector. */
5000 op1
= XVECEXP (vals
, 0, 0);
5001 op2
= XVECEXP (vals
, 0, 1);
5003 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
5005 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
5006 emit_move_insn (tmp
, constant_op
);
5008 if (CONSTANT_P (op1
))
5009 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
5011 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
5013 emit_move_insn (target
, new_rtx
);
5017 paired_expand_vector_move (rtx operands
[])
5019 rtx op0
= operands
[0], op1
= operands
[1];
5021 emit_move_insn (op0
, op1
);
5024 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5025 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5026 operands for the relation operation COND. This is a recursive
5030 paired_emit_vector_compare (enum rtx_code rcode
,
5031 rtx dest
, rtx op0
, rtx op1
,
5032 rtx cc_op0
, rtx cc_op1
)
5034 rtx tmp
= gen_reg_rtx (V2SFmode
);
5037 gcc_assert (TARGET_PAIRED_FLOAT
);
5038 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
5044 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5048 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
5049 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
5053 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
5056 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5059 tmp1
= gen_reg_rtx (V2SFmode
);
5060 max
= gen_reg_rtx (V2SFmode
);
5061 min
= gen_reg_rtx (V2SFmode
);
5062 gen_reg_rtx (V2SFmode
);
5064 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
5065 emit_insn (gen_selv2sf4
5066 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
5067 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
5068 emit_insn (gen_selv2sf4
5069 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
5070 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
5071 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
5074 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5077 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5080 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5083 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5086 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5095 /* Emit vector conditional expression.
5096 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5097 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5100 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
5101 rtx cond
, rtx cc_op0
, rtx cc_op1
)
5103 enum rtx_code rcode
= GET_CODE (cond
);
5105 if (!TARGET_PAIRED_FLOAT
)
5108 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
5113 /* Initialize vector TARGET to VALS. */
5116 rs6000_expand_vector_init (rtx target
, rtx vals
)
5118 enum machine_mode mode
= GET_MODE (target
);
5119 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5120 int n_elts
= GET_MODE_NUNITS (mode
);
5121 int n_var
= 0, one_var
= -1;
5122 bool all_same
= true, all_const_zero
= true;
5126 for (i
= 0; i
< n_elts
; ++i
)
5128 x
= XVECEXP (vals
, 0, i
);
5129 if (!CONSTANT_P (x
))
5130 ++n_var
, one_var
= i
;
5131 else if (x
!= CONST0_RTX (inner_mode
))
5132 all_const_zero
= false;
5134 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
5140 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
5141 bool int_vector_p
= (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
5142 if ((int_vector_p
|| TARGET_VSX
) && all_const_zero
)
5144 /* Zero register. */
5145 emit_insn (gen_rtx_SET (VOIDmode
, target
,
5146 gen_rtx_XOR (mode
, target
, target
)));
5149 else if (int_vector_p
&& easy_vector_constant (const_vec
, mode
))
5151 /* Splat immediate. */
5152 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
5157 /* Load from constant pool. */
5158 emit_move_insn (target
, const_vec
);
5163 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5164 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5168 rtx element
= XVECEXP (vals
, 0, 0);
5169 if (mode
== V2DFmode
)
5170 emit_insn (gen_vsx_splat_v2df (target
, element
));
5172 emit_insn (gen_vsx_splat_v2di (target
, element
));
5176 if (mode
== V2DFmode
)
5178 rtx op0
= copy_to_mode_reg (DFmode
, XVECEXP (vals
, 0, 0));
5179 rtx op1
= copy_to_mode_reg (DFmode
, XVECEXP (vals
, 0, 1));
5180 emit_insn (gen_vsx_concat_v2df (target
, op0
, op1
));
5184 rtx op0
= copy_to_mode_reg (DImode
, XVECEXP (vals
, 0, 0));
5185 rtx op1
= copy_to_mode_reg (DImode
, XVECEXP (vals
, 0, 1));
5186 emit_insn (gen_vsx_concat_v2di (target
, op0
, op1
));
5192 /* With single precision floating point on VSX, know that internally single
5193 precision is actually represented as a double, and either make 2 V2DF
5194 vectors, and convert these vectors to single precision, or do one
5195 conversion, and splat the result to the other elements. */
5196 if (mode
== V4SFmode
&& VECTOR_MEM_VSX_P (mode
))
5200 rtx freg
= gen_reg_rtx (V4SFmode
);
5201 rtx sreg
= copy_to_reg (XVECEXP (vals
, 0, 0));
5203 emit_insn (gen_vsx_xscvdpsp_scalar (freg
, sreg
));
5204 emit_insn (gen_vsx_xxspltw_v4sf (target
, freg
, const0_rtx
));
5208 rtx dbl_even
= gen_reg_rtx (V2DFmode
);
5209 rtx dbl_odd
= gen_reg_rtx (V2DFmode
);
5210 rtx flt_even
= gen_reg_rtx (V4SFmode
);
5211 rtx flt_odd
= gen_reg_rtx (V4SFmode
);
5213 emit_insn (gen_vsx_concat_v2sf (dbl_even
,
5214 copy_to_reg (XVECEXP (vals
, 0, 0)),
5215 copy_to_reg (XVECEXP (vals
, 0, 1))));
5216 emit_insn (gen_vsx_concat_v2sf (dbl_odd
,
5217 copy_to_reg (XVECEXP (vals
, 0, 2)),
5218 copy_to_reg (XVECEXP (vals
, 0, 3))));
5219 emit_insn (gen_vsx_xvcvdpsp (flt_even
, dbl_even
));
5220 emit_insn (gen_vsx_xvcvdpsp (flt_odd
, dbl_odd
));
5221 emit_insn (gen_vec_extract_evenv4sf (target
, flt_even
, flt_odd
));
5226 /* Store value to stack temp. Load vector element. Splat. However, splat
5227 of 64-bit items is not supported on Altivec. */
5228 if (all_same
&& GET_MODE_SIZE (mode
) <= 4)
5230 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5231 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
5232 XVECEXP (vals
, 0, 0));
5233 x
= gen_rtx_UNSPEC (VOIDmode
,
5234 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5235 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5237 gen_rtx_SET (VOIDmode
,
5240 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
5241 gen_rtx_PARALLEL (VOIDmode
,
5242 gen_rtvec (1, const0_rtx
)));
5243 emit_insn (gen_rtx_SET (VOIDmode
, target
,
5244 gen_rtx_VEC_DUPLICATE (mode
, x
)));
5248 /* One field is non-constant. Load constant then overwrite
5252 rtx copy
= copy_rtx (vals
);
5254 /* Load constant part of vector, substitute neighboring value for
5256 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
5257 rs6000_expand_vector_init (target
, copy
);
5259 /* Insert variable. */
5260 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
5264 /* Construct the vector in memory one field at a time
5265 and load the whole vector. */
5266 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5267 for (i
= 0; i
< n_elts
; i
++)
5268 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
5269 i
* GET_MODE_SIZE (inner_mode
)),
5270 XVECEXP (vals
, 0, i
));
5271 emit_move_insn (target
, mem
);
5274 /* Set field ELT of TARGET to VAL. */
5277 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
5279 enum machine_mode mode
= GET_MODE (target
);
5280 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5281 rtx reg
= gen_reg_rtx (mode
);
5283 int width
= GET_MODE_SIZE (inner_mode
);
5286 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5288 rtx (*set_func
) (rtx
, rtx
, rtx
, rtx
)
5289 = ((mode
== V2DFmode
) ? gen_vsx_set_v2df
: gen_vsx_set_v2di
);
5290 emit_insn (set_func (target
, target
, val
, GEN_INT (elt
)));
5294 /* Load single variable value. */
5295 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5296 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
5297 x
= gen_rtx_UNSPEC (VOIDmode
,
5298 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5299 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5301 gen_rtx_SET (VOIDmode
,
5305 /* Linear sequence. */
5306 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
5307 for (i
= 0; i
< 16; ++i
)
5308 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
5310 /* Set permute mask to insert element into target. */
5311 for (i
= 0; i
< width
; ++i
)
5312 XVECEXP (mask
, 0, elt
*width
+ i
)
5313 = GEN_INT (i
+ 0x10);
5314 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
5315 x
= gen_rtx_UNSPEC (mode
,
5316 gen_rtvec (3, target
, reg
,
5317 force_reg (V16QImode
, x
)),
5319 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
5322 /* Extract field ELT from VEC into TARGET. */
5325 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
5327 enum machine_mode mode
= GET_MODE (vec
);
5328 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5331 if (VECTOR_MEM_VSX_P (mode
))
5338 emit_insn (gen_vsx_extract_v2df (target
, vec
, GEN_INT (elt
)));
5341 emit_insn (gen_vsx_extract_v2di (target
, vec
, GEN_INT (elt
)));
5344 emit_insn (gen_vsx_extract_v4sf (target
, vec
, GEN_INT (elt
)));
5349 /* Allocate mode-sized buffer. */
5350 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5352 emit_move_insn (mem
, vec
);
5354 /* Add offset to field within buffer matching vector element. */
5355 mem
= adjust_address_nv (mem
, inner_mode
, elt
* GET_MODE_SIZE (inner_mode
));
5357 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
5360 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5361 implement ANDing by the mask IN. */
5363 build_mask64_2_operands (rtx in
, rtx
*out
)
5365 #if HOST_BITS_PER_WIDE_INT >= 64
5366 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
5369 gcc_assert (GET_CODE (in
) == CONST_INT
);
5374 /* Assume c initially something like 0x00fff000000fffff. The idea
5375 is to rotate the word so that the middle ^^^^^^ group of zeros
5376 is at the MS end and can be cleared with an rldicl mask. We then
5377 rotate back and clear off the MS ^^ group of zeros with a
5379 c
= ~c
; /* c == 0xff000ffffff00000 */
5380 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
5381 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
5382 c
= ~c
; /* c == 0x00fff000000fffff */
5383 c
&= -lsb
; /* c == 0x00fff00000000000 */
5384 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5385 c
= ~c
; /* c == 0xff000fffffffffff */
5386 c
&= -lsb
; /* c == 0xff00000000000000 */
5388 while ((lsb
>>= 1) != 0)
5389 shift
++; /* shift == 44 on exit from loop */
5390 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
5391 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
5392 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
5396 /* Assume c initially something like 0xff000f0000000000. The idea
5397 is to rotate the word so that the ^^^ middle group of zeros
5398 is at the LS end and can be cleared with an rldicr mask. We then
5399 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5401 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
5402 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
5403 c
= ~c
; /* c == 0x00fff0ffffffffff */
5404 c
&= -lsb
; /* c == 0x00fff00000000000 */
5405 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5406 c
= ~c
; /* c == 0xff000fffffffffff */
5407 c
&= -lsb
; /* c == 0xff00000000000000 */
5409 while ((lsb
>>= 1) != 0)
5410 shift
++; /* shift == 44 on exit from loop */
5411 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
5412 m1
>>= shift
; /* m1 == 0x0000000000000fff */
5413 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
5416 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5417 masks will be all 1's. We are guaranteed more than one transition. */
5418 out
[0] = GEN_INT (64 - shift
);
5419 out
[1] = GEN_INT (m1
);
5420 out
[2] = GEN_INT (shift
);
5421 out
[3] = GEN_INT (m2
);
5429 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5432 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
5434 if (TARGET_E500_DOUBLE
)
5436 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5437 subreg:TI and reg:TF. Decimal float modes are like integer
5438 modes (only low part of each register used) for this
5440 if (GET_CODE (op
) == SUBREG
5441 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
5442 || mode
== DDmode
|| mode
== TDmode
)
5443 && REG_P (SUBREG_REG (op
))
5444 && (GET_MODE (SUBREG_REG (op
)) == DFmode
5445 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
5448 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5450 if (GET_CODE (op
) == SUBREG
5451 && (mode
== DFmode
|| mode
== TFmode
)
5452 && REG_P (SUBREG_REG (op
))
5453 && (GET_MODE (SUBREG_REG (op
)) == DImode
5454 || GET_MODE (SUBREG_REG (op
)) == TImode
5455 || GET_MODE (SUBREG_REG (op
)) == DDmode
5456 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
5461 && GET_CODE (op
) == SUBREG
5463 && REG_P (SUBREG_REG (op
))
5464 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
5470 /* AIX increases natural record alignment to doubleword if the first
5471 field is an FP double while the FP fields remain word aligned. */
5474 rs6000_special_round_type_align (tree type
, unsigned int computed
,
5475 unsigned int specified
)
5477 unsigned int align
= MAX (computed
, specified
);
5478 tree field
= TYPE_FIELDS (type
);
5480 /* Skip all non field decls */
5481 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5482 field
= DECL_CHAIN (field
);
5484 if (field
!= NULL
&& field
!= type
)
5486 type
= TREE_TYPE (field
);
5487 while (TREE_CODE (type
) == ARRAY_TYPE
)
5488 type
= TREE_TYPE (type
);
5490 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
5491 align
= MAX (align
, 64);
5497 /* Darwin increases record alignment to the natural alignment of
5501 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
5502 unsigned int specified
)
5504 unsigned int align
= MAX (computed
, specified
);
5506 if (TYPE_PACKED (type
))
5509 /* Find the first field, looking down into aggregates. */
5511 tree field
= TYPE_FIELDS (type
);
5512 /* Skip all non field decls */
5513 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5514 field
= DECL_CHAIN (field
);
5517 /* A packed field does not contribute any extra alignment. */
5518 if (DECL_PACKED (field
))
5520 type
= TREE_TYPE (field
);
5521 while (TREE_CODE (type
) == ARRAY_TYPE
)
5522 type
= TREE_TYPE (type
);
5523 } while (AGGREGATE_TYPE_P (type
));
5525 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
5526 align
= MAX (align
, TYPE_ALIGN (type
));
5531 /* Return 1 for an operand in small memory on V.4/eabi. */
5534 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
5535 enum machine_mode mode ATTRIBUTE_UNUSED
)
5540 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
5543 if (DEFAULT_ABI
!= ABI_V4
)
5546 /* Vector and float memory instructions have a limited offset on the
5547 SPE, so using a vector or float variable directly as an operand is
5550 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
5553 if (GET_CODE (op
) == SYMBOL_REF
)
5556 else if (GET_CODE (op
) != CONST
5557 || GET_CODE (XEXP (op
, 0)) != PLUS
5558 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
5559 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
5564 rtx sum
= XEXP (op
, 0);
5565 HOST_WIDE_INT summand
;
5567 /* We have to be careful here, because it is the referenced address
5568 that must be 32k from _SDA_BASE_, not just the symbol. */
5569 summand
= INTVAL (XEXP (sum
, 1));
5570 if (summand
< 0 || summand
> g_switch_value
)
5573 sym_ref
= XEXP (sum
, 0);
5576 return SYMBOL_REF_SMALL_P (sym_ref
);
5582 /* Return true if either operand is a general purpose register. */
5585 gpr_or_gpr_p (rtx op0
, rtx op1
)
5587 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
5588 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
5592 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5595 reg_offset_addressing_ok_p (enum machine_mode mode
)
5605 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5606 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
5614 /* Paired vector modes. Only reg+reg addressing is valid. */
5615 if (TARGET_PAIRED_FLOAT
)
5627 virtual_stack_registers_memory_p (rtx op
)
5631 if (GET_CODE (op
) == REG
)
5632 regnum
= REGNO (op
);
5634 else if (GET_CODE (op
) == PLUS
5635 && GET_CODE (XEXP (op
, 0)) == REG
5636 && GET_CODE (XEXP (op
, 1)) == CONST_INT
)
5637 regnum
= REGNO (XEXP (op
, 0));
5642 return (regnum
>= FIRST_VIRTUAL_REGISTER
5643 && regnum
<= LAST_VIRTUAL_POINTER_REGISTER
);
5646 /* Return true if memory accesses to OP are known to never straddle
5650 offsettable_ok_by_alignment (rtx op
, HOST_WIDE_INT offset
,
5651 enum machine_mode mode
)
5654 unsigned HOST_WIDE_INT dsize
, dalign
;
5656 if (GET_CODE (op
) != SYMBOL_REF
)
5659 decl
= SYMBOL_REF_DECL (op
);
5662 if (GET_MODE_SIZE (mode
) == 0)
5665 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5666 replacing memory addresses with an anchor plus offset. We
5667 could find the decl by rummaging around in the block->objects
5668 VEC for the given offset but that seems like too much work. */
5670 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op
)
5671 && SYMBOL_REF_ANCHOR_P (op
)
5672 && SYMBOL_REF_BLOCK (op
) != NULL
)
5674 struct object_block
*block
= SYMBOL_REF_BLOCK (op
);
5675 HOST_WIDE_INT lsb
, mask
;
5677 /* Given the alignment of the block.. */
5678 dalign
= block
->alignment
;
5679 mask
= dalign
/ BITS_PER_UNIT
- 1;
5681 /* ..and the combined offset of the anchor and any offset
5682 to this block object.. */
5683 offset
+= SYMBOL_REF_BLOCK_OFFSET (op
);
5684 lsb
= offset
& -offset
;
5686 /* ..find how many bits of the alignment we know for the
5691 return dalign
>= GET_MODE_SIZE (mode
);
5696 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5699 if (!DECL_SIZE_UNIT (decl
))
5702 if (!host_integerp (DECL_SIZE_UNIT (decl
), 1))
5705 dsize
= tree_low_cst (DECL_SIZE_UNIT (decl
), 1);
5709 dalign
= DECL_ALIGN_UNIT (decl
);
5710 return dalign
>= dsize
;
5713 type
= TREE_TYPE (decl
);
5715 if (TREE_CODE (decl
) == STRING_CST
)
5716 dsize
= TREE_STRING_LENGTH (decl
);
5717 else if (TYPE_SIZE_UNIT (type
)
5718 && host_integerp (TYPE_SIZE_UNIT (type
), 1))
5719 dsize
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
5725 dalign
= TYPE_ALIGN (type
);
5726 if (CONSTANT_CLASS_P (decl
))
5727 dalign
= CONSTANT_ALIGNMENT (decl
, dalign
);
5729 dalign
= DATA_ALIGNMENT (decl
, dalign
);
5730 dalign
/= BITS_PER_UNIT
;
5731 return dalign
>= dsize
;
5735 constant_pool_expr_p (rtx op
)
5739 split_const (op
, &base
, &offset
);
5740 return (GET_CODE (base
) == SYMBOL_REF
5741 && CONSTANT_POOL_ADDRESS_P (base
)
5742 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
5745 static rtx tocrel_base
, tocrel_offset
;
5748 toc_relative_expr_p (rtx op
)
5750 if (GET_CODE (op
) != CONST
)
5753 split_const (op
, &tocrel_base
, &tocrel_offset
);
5754 return (GET_CODE (tocrel_base
) == UNSPEC
5755 && XINT (tocrel_base
, 1) == UNSPEC_TOCREL
);
5758 /* Return true if X is a constant pool address, and also for cmodel=medium
5759 if X is a toc-relative address known to be offsettable within MODE. */
5762 legitimate_constant_pool_address_p (const_rtx x
, enum machine_mode mode
,
5766 && (GET_CODE (x
) == PLUS
|| GET_CODE (x
) == LO_SUM
)
5767 && GET_CODE (XEXP (x
, 0)) == REG
5768 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
5769 || ((TARGET_MINIMAL_TOC
5770 || TARGET_CMODEL
!= CMODEL_SMALL
)
5771 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
)))
5772 && toc_relative_expr_p (XEXP (x
, 1))
5773 && (TARGET_CMODEL
!= CMODEL_MEDIUM
5774 || constant_pool_expr_p (XVECEXP (tocrel_base
, 0, 0))
5776 || offsettable_ok_by_alignment (XVECEXP (tocrel_base
, 0, 0),
5777 INTVAL (tocrel_offset
), mode
)));
5781 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
5783 return (DEFAULT_ABI
== ABI_V4
5784 && !flag_pic
&& !TARGET_TOC
5785 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
5786 && small_data_operand (x
, mode
));
5789 /* SPE offset addressing is limited to 5-bits worth of double words. */
5790 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5793 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
5795 unsigned HOST_WIDE_INT offset
, extra
;
5797 if (GET_CODE (x
) != PLUS
)
5799 if (GET_CODE (XEXP (x
, 0)) != REG
)
5801 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5803 if (!reg_offset_addressing_ok_p (mode
))
5804 return virtual_stack_registers_memory_p (x
);
5805 if (legitimate_constant_pool_address_p (x
, mode
, strict
))
5807 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5810 offset
= INTVAL (XEXP (x
, 1));
5818 /* SPE vector modes. */
5819 return SPE_CONST_OFFSET_OK (offset
);
5822 if (TARGET_E500_DOUBLE
)
5823 return SPE_CONST_OFFSET_OK (offset
);
5825 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5827 if (VECTOR_MEM_VSX_P (DFmode
))
5832 /* On e500v2, we may have:
5834 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5836 Which gets addressed with evldd instructions. */
5837 if (TARGET_E500_DOUBLE
)
5838 return SPE_CONST_OFFSET_OK (offset
);
5840 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
5842 else if (offset
& 3)
5847 if (TARGET_E500_DOUBLE
)
5848 return (SPE_CONST_OFFSET_OK (offset
)
5849 && SPE_CONST_OFFSET_OK (offset
+ 8));
5853 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
5855 else if (offset
& 3)
5866 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
5870 legitimate_indexed_address_p (rtx x
, int strict
)
5874 if (GET_CODE (x
) != PLUS
)
5880 /* Recognize the rtl generated by reload which we know will later be
5881 replaced with proper base and index regs. */
5883 && reload_in_progress
5884 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
5888 return (REG_P (op0
) && REG_P (op1
)
5889 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
5890 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
5891 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
5892 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
5896 avoiding_indexed_address_p (enum machine_mode mode
)
5898 /* Avoid indexed addressing for modes that have non-indexed
5899 load/store instruction forms. */
5900 return (TARGET_AVOID_XFORM
&& VECTOR_MEM_NONE_P (mode
));
5904 legitimate_indirect_address_p (rtx x
, int strict
)
5906 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
5910 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
5912 if (!TARGET_MACHO
|| !flag_pic
5913 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
5917 if (GET_CODE (x
) != LO_SUM
)
5919 if (GET_CODE (XEXP (x
, 0)) != REG
)
5921 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
5925 return CONSTANT_P (x
);
5929 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
5931 if (GET_CODE (x
) != LO_SUM
)
5933 if (GET_CODE (XEXP (x
, 0)) != REG
)
5935 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5937 /* Restrict addressing for DI because of our SUBREG hackery. */
5938 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5939 || mode
== DDmode
|| mode
== TDmode
5944 if (TARGET_ELF
|| TARGET_MACHO
)
5946 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
5950 if (GET_MODE_NUNITS (mode
) != 1)
5952 if (GET_MODE_BITSIZE (mode
) > 64
5953 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
5954 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
5955 && (mode
== DFmode
|| mode
== DDmode
))))
5958 return CONSTANT_P (x
);
5965 /* Try machine-dependent ways of modifying an illegitimate address
5966 to be legitimate. If we find one, return the new, valid address.
5967 This is used from only one place: `memory_address' in explow.c.
5969 OLDX is the address as it was before break_out_memory_refs was
5970 called. In some cases it is useful to look at this to decide what
5973 It is always safe for this function to do nothing. It exists to
5974 recognize opportunities to optimize the output.
5976 On RS/6000, first check for the sum of a register with a constant
5977 integer that is out of range. If so, generate code to add the
5978 constant with the low-order 16 bits masked to the register and force
5979 this result into another register (this can be done with `cau').
5980 Then generate an address of REG+(CONST&0xffff), allowing for the
5981 possibility of bit 16 being a one.
5983 Then check for the sum of a register and something not constant, try to
5984 load the other things into a register and return the sum. */
5987 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
5988 enum machine_mode mode
)
5990 unsigned int extra
= 0;
5992 if (!reg_offset_addressing_ok_p (mode
))
5994 if (virtual_stack_registers_memory_p (x
))
5997 /* In theory we should not be seeing addresses of the form reg+0,
5998 but just in case it is generated, optimize it away. */
5999 if (GET_CODE (x
) == PLUS
&& XEXP (x
, 1) == const0_rtx
)
6000 return force_reg (Pmode
, XEXP (x
, 0));
6002 /* Make sure both operands are registers. */
6003 else if (GET_CODE (x
) == PLUS
)
6004 return gen_rtx_PLUS (Pmode
,
6005 force_reg (Pmode
, XEXP (x
, 0)),
6006 force_reg (Pmode
, XEXP (x
, 1)));
6008 return force_reg (Pmode
, x
);
6010 if (GET_CODE (x
) == SYMBOL_REF
)
6012 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
6014 return rs6000_legitimize_tls_address (x
, model
);
6024 if (!TARGET_POWERPC64
)
6032 extra
= TARGET_POWERPC64
? 8 : 12;
6038 if (GET_CODE (x
) == PLUS
6039 && GET_CODE (XEXP (x
, 0)) == REG
6040 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6041 && ((unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000)
6043 && !((TARGET_POWERPC64
6044 && (mode
== DImode
|| mode
== TImode
)
6045 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
6046 || SPE_VECTOR_MODE (mode
)
6047 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6048 || mode
== DImode
|| mode
== DDmode
6049 || mode
== TDmode
))))
6051 HOST_WIDE_INT high_int
, low_int
;
6053 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6054 if (low_int
>= 0x8000 - extra
)
6056 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
6057 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
6058 GEN_INT (high_int
)), 0);
6059 return plus_constant (sum
, low_int
);
6061 else if (GET_CODE (x
) == PLUS
6062 && GET_CODE (XEXP (x
, 0)) == REG
6063 && GET_CODE (XEXP (x
, 1)) != CONST_INT
6064 && GET_MODE_NUNITS (mode
) == 1
6065 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6067 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
6068 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
6069 && (TARGET_POWERPC64
|| mode
!= DImode
)
6070 && !avoiding_indexed_address_p (mode
)
6075 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
6076 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
6078 else if (SPE_VECTOR_MODE (mode
)
6079 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6080 || mode
== DDmode
|| mode
== TDmode
6081 || mode
== DImode
)))
6085 /* We accept [reg + reg] and [reg + OFFSET]. */
6087 if (GET_CODE (x
) == PLUS
)
6089 rtx op1
= XEXP (x
, 0);
6090 rtx op2
= XEXP (x
, 1);
6093 op1
= force_reg (Pmode
, op1
);
6095 if (GET_CODE (op2
) != REG
6096 && (GET_CODE (op2
) != CONST_INT
6097 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
6098 || (GET_MODE_SIZE (mode
) > 8
6099 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
6100 op2
= force_reg (Pmode
, op2
);
6102 /* We can't always do [reg + reg] for these, because [reg +
6103 reg + offset] is not a legitimate addressing mode. */
6104 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
6106 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
6107 return force_reg (Pmode
, y
);
6112 return force_reg (Pmode
, x
);
6118 && GET_CODE (x
) != CONST_INT
6119 && GET_CODE (x
) != CONST_DOUBLE
6121 && GET_MODE_NUNITS (mode
) == 1
6122 && (GET_MODE_BITSIZE (mode
) <= 32
6123 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6124 && (mode
== DFmode
|| mode
== DDmode
))))
6126 rtx reg
= gen_reg_rtx (Pmode
);
6127 emit_insn (gen_elf_high (reg
, x
));
6128 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
6130 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
6133 && ! MACHO_DYNAMIC_NO_PIC_P
6135 && GET_CODE (x
) != CONST_INT
6136 && GET_CODE (x
) != CONST_DOUBLE
6138 && GET_MODE_NUNITS (mode
) == 1
6139 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6140 || (mode
!= DFmode
&& mode
!= DDmode
))
6144 rtx reg
= gen_reg_rtx (Pmode
);
6145 emit_insn (gen_macho_high (reg
, x
));
6146 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
6149 && GET_CODE (x
) == SYMBOL_REF
6150 && constant_pool_expr_p (x
)
6151 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
6153 rtx reg
= TARGET_CMODEL
!= CMODEL_SMALL
? gen_reg_rtx (Pmode
) : NULL_RTX
;
6154 return create_TOC_reference (x
, reg
);
6160 /* Debug version of rs6000_legitimize_address. */
6162 rs6000_debug_legitimize_address (rtx x
, rtx oldx
, enum machine_mode mode
)
6168 ret
= rs6000_legitimize_address (x
, oldx
, mode
);
6169 insns
= get_insns ();
6175 "\nrs6000_legitimize_address: mode %s, old code %s, "
6176 "new code %s, modified\n",
6177 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)),
6178 GET_RTX_NAME (GET_CODE (ret
)));
6180 fprintf (stderr
, "Original address:\n");
6183 fprintf (stderr
, "oldx:\n");
6186 fprintf (stderr
, "New address:\n");
6191 fprintf (stderr
, "Insns added:\n");
6192 debug_rtx_list (insns
, 20);
6198 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6199 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)));
6210 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6211 We need to emit DTP-relative relocations. */
6214 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
6219 fputs ("\t.long\t", file
);
6222 fputs (DOUBLE_INT_ASM_OP
, file
);
6227 output_addr_const (file
, x
);
6228 fputs ("@dtprel+0x8000", file
);
6231 /* In the name of slightly smaller debug output, and to cater to
6232 general assembler lossage, recognize various UNSPEC sequences
6233 and turn them back into a direct symbol reference. */
6236 rs6000_delegitimize_address (rtx orig_x
)
6240 orig_x
= delegitimize_mem_from_attrs (orig_x
);
6245 if (GET_CODE (x
) == (TARGET_CMODEL
!= CMODEL_SMALL
? LO_SUM
: PLUS
)
6246 && GET_CODE (XEXP (x
, 1)) == CONST
)
6248 rtx offset
= NULL_RTX
;
6250 y
= XEXP (XEXP (x
, 1), 0);
6251 if (GET_CODE (y
) == PLUS
6252 && GET_MODE (y
) == Pmode
6253 && CONST_INT_P (XEXP (y
, 1)))
6255 offset
= XEXP (y
, 1);
6258 if (GET_CODE (y
) == UNSPEC
6259 && XINT (y
, 1) == UNSPEC_TOCREL
6260 && ((GET_CODE (XEXP (x
, 0)) == REG
6261 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
6262 || TARGET_MINIMAL_TOC
6263 || TARGET_CMODEL
!= CMODEL_SMALL
))
6264 || (TARGET_CMODEL
!= CMODEL_SMALL
6265 && GET_CODE (XEXP (x
, 0)) == PLUS
6266 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6267 && REGNO (XEXP (XEXP (x
, 0), 0)) == TOC_REGISTER
6268 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6269 && rtx_equal_p (XEXP (x
, 1),
6270 XEXP (XEXP (XEXP (x
, 0), 1), 0)))))
6272 y
= XVECEXP (y
, 0, 0);
6273 if (offset
!= NULL_RTX
)
6274 y
= gen_rtx_PLUS (Pmode
, y
, offset
);
6275 if (!MEM_P (orig_x
))
6278 return replace_equiv_address_nv (orig_x
, y
);
6283 && GET_CODE (orig_x
) == LO_SUM
6284 && GET_CODE (XEXP (orig_x
, 1)) == CONST
)
6286 y
= XEXP (XEXP (orig_x
, 1), 0);
6287 if (GET_CODE (y
) == UNSPEC
6288 && XINT (y
, 1) == UNSPEC_MACHOPIC_OFFSET
)
6289 return XVECEXP (y
, 0, 0);
6295 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6297 static GTY(()) rtx rs6000_tls_symbol
;
6299 rs6000_tls_get_addr (void)
6301 if (!rs6000_tls_symbol
)
6302 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
6304 return rs6000_tls_symbol
;
6307 /* Construct the SYMBOL_REF for TLS GOT references. */
6309 static GTY(()) rtx rs6000_got_symbol
;
6311 rs6000_got_sym (void)
6313 if (!rs6000_got_symbol
)
6315 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6316 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
6317 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
6320 return rs6000_got_symbol
;
6323 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6324 this (thread-local) address. */
6327 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
6331 dest
= gen_reg_rtx (Pmode
);
6332 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
6338 tlsreg
= gen_rtx_REG (Pmode
, 13);
6339 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
6343 tlsreg
= gen_rtx_REG (Pmode
, 2);
6344 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
6348 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
6352 tmp
= gen_reg_rtx (Pmode
);
6355 tlsreg
= gen_rtx_REG (Pmode
, 13);
6356 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
6360 tlsreg
= gen_rtx_REG (Pmode
, 2);
6361 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
6365 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
6367 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
6372 rtx r3
, got
, tga
, tmp1
, tmp2
, call_insn
;
6374 /* We currently use relocations like @got@tlsgd for tls, which
6375 means the linker will handle allocation of tls entries, placing
6376 them in the .got section. So use a pointer to the .got section,
6377 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6378 or to secondary GOT sections used by 32-bit -fPIC. */
6380 got
= gen_rtx_REG (Pmode
, 2);
6384 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
6387 rtx gsym
= rs6000_got_sym ();
6388 got
= gen_reg_rtx (Pmode
);
6390 rs6000_emit_move (got
, gsym
, Pmode
);
6395 tmp1
= gen_reg_rtx (Pmode
);
6396 tmp2
= gen_reg_rtx (Pmode
);
6397 mem
= gen_const_mem (Pmode
, tmp1
);
6398 lab
= gen_label_rtx ();
6399 emit_insn (gen_load_toc_v4_PIC_1b (gsym
, lab
));
6400 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
6401 emit_move_insn (tmp2
, mem
);
6402 last
= emit_insn (gen_addsi3 (got
, tmp1
, tmp2
));
6403 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
6408 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
6410 tga
= rs6000_tls_get_addr ();
6411 emit_library_call_value (tga
, dest
, LCT_CONST
, Pmode
,
6412 1, const0_rtx
, Pmode
);
6414 r3
= gen_rtx_REG (Pmode
, 3);
6415 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6416 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
6417 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6418 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
6419 else if (DEFAULT_ABI
== ABI_V4
)
6420 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
6423 call_insn
= last_call_insn ();
6424 PATTERN (call_insn
) = insn
;
6425 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6426 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6427 pic_offset_table_rtx
);
6429 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
6431 tga
= rs6000_tls_get_addr ();
6432 tmp1
= gen_reg_rtx (Pmode
);
6433 emit_library_call_value (tga
, tmp1
, LCT_CONST
, Pmode
,
6434 1, const0_rtx
, Pmode
);
6436 r3
= gen_rtx_REG (Pmode
, 3);
6437 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6438 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
6439 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6440 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
6441 else if (DEFAULT_ABI
== ABI_V4
)
6442 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
6445 call_insn
= last_call_insn ();
6446 PATTERN (call_insn
) = insn
;
6447 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6448 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6449 pic_offset_table_rtx
);
6451 if (rs6000_tls_size
== 16)
6454 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
6456 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
6458 else if (rs6000_tls_size
== 32)
6460 tmp2
= gen_reg_rtx (Pmode
);
6462 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
6464 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
6467 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
6469 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
6473 tmp2
= gen_reg_rtx (Pmode
);
6475 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
6477 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
6479 insn
= gen_rtx_SET (Pmode
, dest
,
6480 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
6486 /* IE, or 64-bit offset LE. */
6487 tmp2
= gen_reg_rtx (Pmode
);
6489 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
6491 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
6494 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
6496 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
6504 /* Return 1 if X contains a thread-local symbol. */
6507 rs6000_tls_referenced_p (rtx x
)
6509 if (! TARGET_HAVE_TLS
)
6512 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
6515 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6518 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
6520 return rs6000_tls_referenced_p (x
);
6523 /* Return 1 if *X is a thread-local symbol. This is the same as
6524 rs6000_tls_symbol_ref except for the type of the unused argument. */
6527 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
6529 return RS6000_SYMBOL_REF_TLS_P (*x
);
6532 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6533 replace the input X, or the original X if no replacement is called for.
6534 The output parameter *WIN is 1 if the calling macro should goto WIN,
6537 For RS/6000, we wish to handle large displacements off a base
6538 register by splitting the addend across an addiu/addis and the mem insn.
6539 This cuts number of extra insns needed from 3 to 1.
6541 On Darwin, we use this to generate code for floating point constants.
6542 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6543 The Darwin code is inside #if TARGET_MACHO because only then are the
6544 machopic_* functions defined. */
6546 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6547 int opnum
, int type
,
6548 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
6550 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6552 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6553 DFmode/DImode MEM. */
6556 && ((mode
== DFmode
&& recog_data
.operand_mode
[0] == V2DFmode
)
6557 || (mode
== DImode
&& recog_data
.operand_mode
[0] == V2DImode
)))
6558 reg_offset_p
= false;
6560 /* We must recognize output that we have already generated ourselves. */
6561 if (GET_CODE (x
) == PLUS
6562 && GET_CODE (XEXP (x
, 0)) == PLUS
6563 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6564 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6565 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6567 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6568 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6569 opnum
, (enum reload_type
)type
);
6574 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6575 if (GET_CODE (x
) == LO_SUM
6576 && GET_CODE (XEXP (x
, 0)) == HIGH
)
6578 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6579 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6580 opnum
, (enum reload_type
)type
);
6586 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
6587 && GET_CODE (x
) == LO_SUM
6588 && GET_CODE (XEXP (x
, 0)) == PLUS
6589 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
6590 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6591 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
6592 && machopic_operand_p (XEXP (x
, 1)))
6594 /* Result of previous invocation of this function on Darwin
6595 floating point constant. */
6596 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6597 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6598 opnum
, (enum reload_type
)type
);
6604 if (TARGET_CMODEL
!= CMODEL_SMALL
6605 && GET_CODE (x
) == LO_SUM
6606 && GET_CODE (XEXP (x
, 0)) == PLUS
6607 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6608 && REGNO (XEXP (XEXP (x
, 0), 0)) == TOC_REGISTER
6609 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6610 && GET_CODE (XEXP (x
, 1)) == CONST
6611 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == UNSPEC
6612 && XINT (XEXP (XEXP (x
, 1), 0), 1) == UNSPEC_TOCREL
6613 && rtx_equal_p (XEXP (XEXP (XEXP (x
, 0), 1), 0), XEXP (x
, 1)))
6615 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6616 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6617 opnum
, (enum reload_type
) type
);
6622 /* Force ld/std non-word aligned offset into base register by wrapping
6624 if (GET_CODE (x
) == PLUS
6625 && GET_CODE (XEXP (x
, 0)) == REG
6626 && REGNO (XEXP (x
, 0)) < 32
6627 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6628 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6630 && (INTVAL (XEXP (x
, 1)) & 3) != 0
6631 && VECTOR_MEM_NONE_P (mode
)
6632 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
6633 && TARGET_POWERPC64
)
6635 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
6636 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6637 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6638 opnum
, (enum reload_type
) type
);
6643 if (GET_CODE (x
) == PLUS
6644 && GET_CODE (XEXP (x
, 0)) == REG
6645 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
6646 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6647 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6649 && !SPE_VECTOR_MODE (mode
)
6650 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6651 || mode
== DDmode
|| mode
== TDmode
6653 && VECTOR_MEM_NONE_P (mode
))
6655 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
6656 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
6658 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6660 /* Check for 32-bit overflow. */
6661 if (high
+ low
!= val
)
6667 /* Reload the high part into a base reg; leave the low part
6668 in the mem directly. */
6670 x
= gen_rtx_PLUS (GET_MODE (x
),
6671 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
6675 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6676 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6677 opnum
, (enum reload_type
)type
);
6682 if (GET_CODE (x
) == SYMBOL_REF
6684 && VECTOR_MEM_NONE_P (mode
)
6685 && !SPE_VECTOR_MODE (mode
)
6687 && DEFAULT_ABI
== ABI_DARWIN
6688 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
6690 && DEFAULT_ABI
== ABI_V4
6693 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6694 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6698 && (mode
!= DImode
|| TARGET_POWERPC64
)
6699 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
6700 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
6705 rtx offset
= machopic_gen_offset (x
);
6706 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6707 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
6708 gen_rtx_HIGH (Pmode
, offset
)), offset
);
6712 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6713 gen_rtx_HIGH (Pmode
, x
), x
);
6715 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6716 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6717 opnum
, (enum reload_type
)type
);
6722 /* Reload an offset address wrapped by an AND that represents the
6723 masking of the lower bits. Strip the outer AND and let reload
6724 convert the offset address into an indirect address. For VSX,
6725 force reload to create the address with an AND in a separate
6726 register, because we can't guarantee an altivec register will
6728 if (VECTOR_MEM_ALTIVEC_P (mode
)
6729 && GET_CODE (x
) == AND
6730 && GET_CODE (XEXP (x
, 0)) == PLUS
6731 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6732 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6733 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6734 && INTVAL (XEXP (x
, 1)) == -16)
6743 && GET_CODE (x
) == SYMBOL_REF
6744 && constant_pool_expr_p (x
)
6745 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
6747 x
= create_TOC_reference (x
, NULL_RTX
);
6748 if (TARGET_CMODEL
!= CMODEL_SMALL
)
6749 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6750 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6751 opnum
, (enum reload_type
) type
);
6759 /* Debug version of rs6000_legitimize_reload_address. */
6761 rs6000_debug_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6762 int opnum
, int type
,
6763 int ind_levels
, int *win
)
6765 rtx ret
= rs6000_legitimize_reload_address (x
, mode
, opnum
, type
,
6768 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6769 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6770 GET_MODE_NAME (mode
), opnum
, type
, ind_levels
, *win
);
6774 fprintf (stderr
, "Same address returned\n");
6776 fprintf (stderr
, "NULL returned\n");
6779 fprintf (stderr
, "New address:\n");
6786 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6787 that is a valid memory address for an instruction.
6788 The MODE argument is the machine mode for the MEM expression
6789 that wants to use this address.
6791 On the RS/6000, there are four valid address: a SYMBOL_REF that
6792 refers to a constant pool entry of an address (or the sum of it
6793 plus a constant), a short (16-bit signed) constant plus a register,
6794 the sum of two registers, or a register indirect, possibly with an
6795 auto-increment. For DFmode, DDmode and DImode with a constant plus
6796 register, we must ensure that both words are addressable or PowerPC64
6797 with offset word aligned.
6799 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6800 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6801 because adjacent memory cells are accessed by adding word-sized offsets
6802 during assembly output. */
6804 rs6000_legitimate_address_p (enum machine_mode mode
, rtx x
, bool reg_ok_strict
)
6806 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6808 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6809 if (VECTOR_MEM_ALTIVEC_P (mode
)
6810 && GET_CODE (x
) == AND
6811 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6812 && INTVAL (XEXP (x
, 1)) == -16)
6815 if (RS6000_SYMBOL_REF_TLS_P (x
))
6817 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
6819 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
6820 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6821 && !SPE_VECTOR_MODE (mode
)
6824 /* Restrict addressing for DI because of our SUBREG hackery. */
6825 && !(TARGET_E500_DOUBLE
6826 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6828 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
6830 if (virtual_stack_registers_memory_p (x
))
6832 if (reg_offset_p
&& legitimate_small_data_p (mode
, x
))
6835 && legitimate_constant_pool_address_p (x
, mode
, reg_ok_strict
))
6837 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6840 && GET_CODE (x
) == PLUS
6841 && GET_CODE (XEXP (x
, 0)) == REG
6842 && (XEXP (x
, 0) == virtual_stack_vars_rtx
6843 || XEXP (x
, 0) == arg_pointer_rtx
)
6844 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6846 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
6851 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6853 || (mode
!= DFmode
&& mode
!= DDmode
)
6854 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
6855 && (TARGET_POWERPC64
|| mode
!= DImode
)
6856 && !avoiding_indexed_address_p (mode
)
6857 && legitimate_indexed_address_p (x
, reg_ok_strict
))
6859 if (GET_CODE (x
) == PRE_MODIFY
6863 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6865 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
6866 && (TARGET_POWERPC64
|| mode
!= DImode
)
6867 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6868 && !SPE_VECTOR_MODE (mode
)
6869 /* Restrict addressing for DI because of our SUBREG hackery. */
6870 && !(TARGET_E500_DOUBLE
6871 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6873 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
6874 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
6875 || (!avoiding_indexed_address_p (mode
)
6876 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
6877 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
6879 if (reg_offset_p
&& legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
6884 /* Debug version of rs6000_legitimate_address_p. */
6886 rs6000_debug_legitimate_address_p (enum machine_mode mode
, rtx x
,
6889 bool ret
= rs6000_legitimate_address_p (mode
, x
, reg_ok_strict
);
6891 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6892 "strict = %d, code = %s\n",
6893 ret
? "true" : "false",
6894 GET_MODE_NAME (mode
),
6896 GET_RTX_NAME (GET_CODE (x
)));
6902 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6905 rs6000_mode_dependent_address_p (const_rtx addr
)
6907 return rs6000_mode_dependent_address_ptr (addr
);
6910 /* Go to LABEL if ADDR (a legitimate address expression)
6911 has an effect that depends on the machine mode it is used for.
6913 On the RS/6000 this is true of all integral offsets (since AltiVec
6914 and VSX modes don't allow them) or is a pre-increment or decrement.
6916 ??? Except that due to conceptual problems in offsettable_address_p
6917 we can't really report the problems of integral offsets. So leave
6918 this assuming that the adjustable offset must be valid for the
6919 sub-words of a TFmode operand, which is what we had before. */
6922 rs6000_mode_dependent_address (const_rtx addr
)
6924 switch (GET_CODE (addr
))
6927 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6928 is considered a legitimate address before reload, so there
6929 are no offset restrictions in that case. Note that this
6930 condition is safe in strict mode because any address involving
6931 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6932 been rejected as illegitimate. */
6933 if (XEXP (addr
, 0) != virtual_stack_vars_rtx
6934 && XEXP (addr
, 0) != arg_pointer_rtx
6935 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
6937 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
6938 return val
+ 12 + 0x8000 >= 0x10000;
6943 /* Anything in the constant pool is sufficiently aligned that
6944 all bytes have the same high part address. */
6945 return !legitimate_constant_pool_address_p (addr
, QImode
, false);
6947 /* Auto-increment cases are now treated generically in recog.c. */
6949 return TARGET_UPDATE
;
6951 /* AND is only allowed in Altivec loads. */
6962 /* Debug version of rs6000_mode_dependent_address. */
6964 rs6000_debug_mode_dependent_address (const_rtx addr
)
6966 bool ret
= rs6000_mode_dependent_address (addr
);
6968 fprintf (stderr
, "\nrs6000_mode_dependent_address: ret = %s\n",
6969 ret
? "true" : "false");
6975 /* Implement FIND_BASE_TERM. */
6978 rs6000_find_base_term (rtx op
)
6982 split_const (op
, &base
, &offset
);
6983 if (GET_CODE (base
) == UNSPEC
)
6984 switch (XINT (base
, 1))
6987 case UNSPEC_MACHOPIC_OFFSET
:
6988 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6989 for aliasing purposes. */
6990 return XVECEXP (base
, 0, 0);
6996 /* More elaborate version of recog's offsettable_memref_p predicate
6997 that works around the ??? note of rs6000_mode_dependent_address.
6998 In particular it accepts
7000 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7002 in 32-bit mode, that the recog predicate rejects. */
7005 rs6000_offsettable_memref_p (rtx op
)
7010 /* First mimic offsettable_memref_p. */
7011 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
7014 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7015 the latter predicate knows nothing about the mode of the memory
7016 reference and, therefore, assumes that it is the largest supported
7017 mode (TFmode). As a consequence, legitimate offsettable memory
7018 references are rejected. rs6000_legitimate_offset_address_p contains
7019 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7020 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
7023 /* Change register usage conditional on target flags. */
7025 rs6000_conditional_register_usage (void)
7029 if (TARGET_DEBUG_TARGET
)
7030 fprintf (stderr
, "rs6000_conditional_register_usage called\n");
7032 /* Set MQ register fixed (already call_used) if not POWER
7033 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7038 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7040 fixed_regs
[13] = call_used_regs
[13]
7041 = call_really_used_regs
[13] = 1;
7043 /* Conditionally disable FPRs. */
7044 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
7045 for (i
= 32; i
< 64; i
++)
7046 fixed_regs
[i
] = call_used_regs
[i
]
7047 = call_really_used_regs
[i
] = 1;
7049 /* The TOC register is not killed across calls in a way that is
7050 visible to the compiler. */
7051 if (DEFAULT_ABI
== ABI_AIX
)
7052 call_really_used_regs
[2] = 0;
7054 if (DEFAULT_ABI
== ABI_V4
7055 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
7057 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7059 if (DEFAULT_ABI
== ABI_V4
7060 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
7062 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7063 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7064 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7066 if (DEFAULT_ABI
== ABI_DARWIN
7067 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
7068 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7069 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7070 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7072 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
7073 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7074 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7078 global_regs
[SPEFSCR_REGNO
] = 1;
7079 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7080 registers in prologues and epilogues. We no longer use r14
7081 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7082 pool for link-compatibility with older versions of GCC. Once
7083 "old" code has died out, we can return r14 to the allocation
7086 = call_used_regs
[14]
7087 = call_really_used_regs
[14] = 1;
7090 if (!TARGET_ALTIVEC
&& !TARGET_VSX
)
7092 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
7093 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
7094 call_really_used_regs
[VRSAVE_REGNO
] = 1;
7097 if (TARGET_ALTIVEC
|| TARGET_VSX
)
7098 global_regs
[VSCR_REGNO
] = 1;
7100 if (TARGET_ALTIVEC_ABI
)
7102 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
7103 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
7105 /* AIX reserves VR20:31 in non-extended ABI mode. */
7107 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
7108 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
7112 /* Try to output insns to set TARGET equal to the constant C if it can
7113 be done in less than N insns. Do all computations in MODE.
7114 Returns the place where the output has been placed if it can be
7115 done and the insns have been emitted. If it would take more than N
7116 insns, zero is returned and no insns and emitted. */
7119 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
7120 rtx source
, int n ATTRIBUTE_UNUSED
)
7122 rtx result
, insn
, set
;
7123 HOST_WIDE_INT c0
, c1
;
7130 dest
= gen_reg_rtx (mode
);
7131 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
7135 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
7137 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
7138 GEN_INT (INTVAL (source
)
7139 & (~ (HOST_WIDE_INT
) 0xffff))));
7140 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
7141 gen_rtx_IOR (SImode
, copy_rtx (result
),
7142 GEN_INT (INTVAL (source
) & 0xffff))));
7147 switch (GET_CODE (source
))
7150 c0
= INTVAL (source
);
7155 #if HOST_BITS_PER_WIDE_INT >= 64
7156 c0
= CONST_DOUBLE_LOW (source
);
7159 c0
= CONST_DOUBLE_LOW (source
);
7160 c1
= CONST_DOUBLE_HIGH (source
);
7168 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
7175 insn
= get_last_insn ();
7176 set
= single_set (insn
);
7177 if (! CONSTANT_P (SET_SRC (set
)))
7178 set_unique_reg_note (insn
, REG_EQUAL
, source
);
7183 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7184 fall back to a straight forward decomposition. We do this to avoid
7185 exponential run times encountered when looking for longer sequences
7186 with rs6000_emit_set_const. */
7188 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
7190 if (!TARGET_POWERPC64
)
7192 rtx operand1
, operand2
;
7194 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
7196 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
7198 emit_move_insn (operand1
, GEN_INT (c1
));
7199 emit_move_insn (operand2
, GEN_INT (c2
));
7203 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
7206 ud2
= (c1
& 0xffff0000) >> 16;
7207 #if HOST_BITS_PER_WIDE_INT >= 64
7211 ud4
= (c2
& 0xffff0000) >> 16;
7213 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
7214 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
7217 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
7219 emit_move_insn (dest
, GEN_INT (ud1
));
7222 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
7223 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
7226 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
7229 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
7231 emit_move_insn (copy_rtx (dest
),
7232 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7235 else if (ud3
== 0 && ud4
== 0)
7237 gcc_assert (ud2
& 0x8000);
7238 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
7241 emit_move_insn (copy_rtx (dest
),
7242 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7244 emit_move_insn (copy_rtx (dest
),
7245 gen_rtx_ZERO_EXTEND (DImode
,
7246 gen_lowpart (SImode
,
7249 else if ((ud4
== 0xffff && (ud3
& 0x8000))
7250 || (ud4
== 0 && ! (ud3
& 0x8000)))
7253 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
7256 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
7259 emit_move_insn (copy_rtx (dest
),
7260 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7262 emit_move_insn (copy_rtx (dest
),
7263 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
7266 emit_move_insn (copy_rtx (dest
),
7267 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7273 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
7276 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
7279 emit_move_insn (copy_rtx (dest
),
7280 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7283 emit_move_insn (copy_rtx (dest
),
7284 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
7287 emit_move_insn (copy_rtx (dest
),
7288 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7289 GEN_INT (ud2
<< 16)));
7291 emit_move_insn (copy_rtx (dest
),
7292 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
7298 /* Helper for the following. Get rid of [r+r] memory refs
7299 in cases where it won't work (TImode, TFmode, TDmode). */
7302 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
7304 if (reload_in_progress
)
7307 if (GET_CODE (operands
[0]) == MEM
7308 && GET_CODE (XEXP (operands
[0], 0)) != REG
7309 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0),
7310 GET_MODE (operands
[0]), false))
7312 = replace_equiv_address (operands
[0],
7313 copy_addr_to_reg (XEXP (operands
[0], 0)));
7315 if (GET_CODE (operands
[1]) == MEM
7316 && GET_CODE (XEXP (operands
[1], 0)) != REG
7317 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0),
7318 GET_MODE (operands
[1]), false))
7320 = replace_equiv_address (operands
[1],
7321 copy_addr_to_reg (XEXP (operands
[1], 0)));
7324 /* Emit a move from SOURCE to DEST in mode MODE. */
7326 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
7330 operands
[1] = source
;
7332 if (TARGET_DEBUG_ADDR
)
7335 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7336 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7337 GET_MODE_NAME (mode
),
7340 can_create_pseudo_p ());
7342 fprintf (stderr
, "source:\n");
7346 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7347 if (GET_CODE (operands
[1]) == CONST_DOUBLE
7348 && ! FLOAT_MODE_P (mode
)
7349 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
7351 /* FIXME. This should never happen. */
7352 /* Since it seems that it does, do the safe thing and convert
7354 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
7356 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
7357 || FLOAT_MODE_P (mode
)
7358 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
7359 || CONST_DOUBLE_LOW (operands
[1]) < 0)
7360 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
7361 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
7363 /* Check if GCC is setting up a block move that will end up using FP
7364 registers as temporaries. We must make sure this is acceptable. */
7365 if (GET_CODE (operands
[0]) == MEM
7366 && GET_CODE (operands
[1]) == MEM
7368 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
7369 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
7370 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
7371 ? 32 : MEM_ALIGN (operands
[0])))
7372 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
7374 : MEM_ALIGN (operands
[1]))))
7375 && ! MEM_VOLATILE_P (operands
[0])
7376 && ! MEM_VOLATILE_P (operands
[1]))
7378 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
7379 adjust_address (operands
[1], SImode
, 0));
7380 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
7381 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
7385 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
7386 && !gpc_reg_operand (operands
[1], mode
))
7387 operands
[1] = force_reg (mode
, operands
[1]);
7389 if (mode
== SFmode
&& ! TARGET_POWERPC
7390 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
7391 && GET_CODE (operands
[0]) == MEM
)
7395 if (reload_in_progress
|| reload_completed
)
7396 regnum
= true_regnum (operands
[1]);
7397 else if (GET_CODE (operands
[1]) == REG
)
7398 regnum
= REGNO (operands
[1]);
7402 /* If operands[1] is a register, on POWER it may have
7403 double-precision data in it, so truncate it to single
7405 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
7408 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
7409 : gen_reg_rtx (mode
));
7410 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
7411 operands
[1] = newreg
;
7415 /* Recognize the case where operand[1] is a reference to thread-local
7416 data and load its address to a register. */
7417 if (rs6000_tls_referenced_p (operands
[1]))
7419 enum tls_model model
;
7420 rtx tmp
= operands
[1];
7423 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
7425 addend
= XEXP (XEXP (tmp
, 0), 1);
7426 tmp
= XEXP (XEXP (tmp
, 0), 0);
7429 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
7430 model
= SYMBOL_REF_TLS_MODEL (tmp
);
7431 gcc_assert (model
!= 0);
7433 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
7436 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
7437 tmp
= force_operand (tmp
, operands
[0]);
7442 /* Handle the case where reload calls us with an invalid address. */
7443 if (reload_in_progress
&& mode
== Pmode
7444 && (! general_operand (operands
[1], mode
)
7445 || ! nonimmediate_operand (operands
[0], mode
)))
7448 /* 128-bit constant floating-point values on Darwin should really be
7449 loaded as two parts. */
7450 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
7451 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
7453 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7454 know how to get a DFmode SUBREG of a TFmode. */
7455 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
7456 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
7457 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
7459 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
7460 GET_MODE_SIZE (imode
)),
7461 simplify_gen_subreg (imode
, operands
[1], mode
,
7462 GET_MODE_SIZE (imode
)),
7467 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
7468 cfun
->machine
->sdmode_stack_slot
=
7469 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
7471 if (reload_in_progress
7473 && MEM_P (operands
[0])
7474 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
7475 && REG_P (operands
[1]))
7477 if (FP_REGNO_P (REGNO (operands
[1])))
7479 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
7480 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7481 emit_insn (gen_movsd_store (mem
, operands
[1]));
7483 else if (INT_REGNO_P (REGNO (operands
[1])))
7485 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
7486 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7487 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
7493 if (reload_in_progress
7495 && REG_P (operands
[0])
7496 && MEM_P (operands
[1])
7497 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
7499 if (FP_REGNO_P (REGNO (operands
[0])))
7501 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
7502 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7503 emit_insn (gen_movsd_load (operands
[0], mem
));
7505 else if (INT_REGNO_P (REGNO (operands
[0])))
7507 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
7508 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7509 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
7516 /* FIXME: In the long term, this switch statement should go away
7517 and be replaced by a sequence of tests based on things like
7523 if (CONSTANT_P (operands
[1])
7524 && GET_CODE (operands
[1]) != CONST_INT
)
7525 operands
[1] = force_const_mem (mode
, operands
[1]);
7530 rs6000_eliminate_indexed_memrefs (operands
);
7537 if (CONSTANT_P (operands
[1])
7538 && ! easy_fp_constant (operands
[1], mode
))
7539 operands
[1] = force_const_mem (mode
, operands
[1]);
7552 if (CONSTANT_P (operands
[1])
7553 && !easy_vector_constant (operands
[1], mode
))
7554 operands
[1] = force_const_mem (mode
, operands
[1]);
7559 /* Use default pattern for address of ELF small data */
7562 && DEFAULT_ABI
== ABI_V4
7563 && (GET_CODE (operands
[1]) == SYMBOL_REF
7564 || GET_CODE (operands
[1]) == CONST
)
7565 && small_data_operand (operands
[1], mode
))
7567 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7571 if (DEFAULT_ABI
== ABI_V4
7572 && mode
== Pmode
&& mode
== SImode
7573 && flag_pic
== 1 && got_operand (operands
[1], mode
))
7575 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
7579 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
7583 && CONSTANT_P (operands
[1])
7584 && GET_CODE (operands
[1]) != HIGH
7585 && GET_CODE (operands
[1]) != CONST_INT
)
7587 rtx target
= (!can_create_pseudo_p ()
7589 : gen_reg_rtx (mode
));
7591 /* If this is a function address on -mcall-aixdesc,
7592 convert it to the address of the descriptor. */
7593 if (DEFAULT_ABI
== ABI_AIX
7594 && GET_CODE (operands
[1]) == SYMBOL_REF
7595 && XSTR (operands
[1], 0)[0] == '.')
7597 const char *name
= XSTR (operands
[1], 0);
7599 while (*name
== '.')
7601 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
7602 CONSTANT_POOL_ADDRESS_P (new_ref
)
7603 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
7604 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
7605 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
7606 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
7607 operands
[1] = new_ref
;
7610 if (DEFAULT_ABI
== ABI_DARWIN
)
7613 if (MACHO_DYNAMIC_NO_PIC_P
)
7615 /* Take care of any required data indirection. */
7616 operands
[1] = rs6000_machopic_legitimize_pic_address (
7617 operands
[1], mode
, operands
[0]);
7618 if (operands
[0] != operands
[1])
7619 emit_insn (gen_rtx_SET (VOIDmode
,
7620 operands
[0], operands
[1]));
7624 emit_insn (gen_macho_high (target
, operands
[1]));
7625 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
7629 emit_insn (gen_elf_high (target
, operands
[1]));
7630 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
7634 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7635 and we have put it in the TOC, we just need to make a TOC-relative
7638 && GET_CODE (operands
[1]) == SYMBOL_REF
7639 && constant_pool_expr_p (operands
[1])
7640 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
7641 get_pool_mode (operands
[1])))
7642 || (TARGET_CMODEL
== CMODEL_MEDIUM
7643 && GET_CODE (operands
[1]) == SYMBOL_REF
7644 && !CONSTANT_POOL_ADDRESS_P (operands
[1])
7645 && SYMBOL_REF_LOCAL_P (operands
[1])))
7648 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7650 if (can_create_pseudo_p ())
7651 reg
= gen_reg_rtx (Pmode
);
7655 operands
[1] = create_TOC_reference (operands
[1], reg
);
7657 else if (mode
== Pmode
7658 && CONSTANT_P (operands
[1])
7659 && ((GET_CODE (operands
[1]) != CONST_INT
7660 && ! easy_fp_constant (operands
[1], mode
))
7661 || (GET_CODE (operands
[1]) == CONST_INT
7662 && (num_insns_constant (operands
[1], mode
)
7663 > (TARGET_CMODEL
!= CMODEL_SMALL
? 3 : 2)))
7664 || (GET_CODE (operands
[0]) == REG
7665 && FP_REGNO_P (REGNO (operands
[0]))))
7666 && GET_CODE (operands
[1]) != HIGH
7667 && ! legitimate_constant_pool_address_p (operands
[1], mode
,
7669 && ! toc_relative_expr_p (operands
[1])
7670 && (TARGET_CMODEL
== CMODEL_SMALL
7671 || can_create_pseudo_p ()
7672 || (REG_P (operands
[0])
7673 && INT_REG_OK_FOR_BASE_P (operands
[0], true))))
7677 /* Darwin uses a special PIC legitimizer. */
7678 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
7681 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
7683 if (operands
[0] != operands
[1])
7684 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7689 /* If we are to limit the number of things we put in the TOC and
7690 this is a symbol plus a constant we can add in one insn,
7691 just put the symbol in the TOC and add the constant. Don't do
7692 this if reload is in progress. */
7693 if (GET_CODE (operands
[1]) == CONST
7694 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
7695 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
7696 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
7697 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
7698 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
7699 && ! side_effects_p (operands
[0]))
7702 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
7703 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
7705 sym
= force_reg (mode
, sym
);
7706 emit_insn (gen_add3_insn (operands
[0], sym
, other
));
7710 operands
[1] = force_const_mem (mode
, operands
[1]);
7713 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
7714 && constant_pool_expr_p (XEXP (operands
[1], 0))
7715 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7716 get_pool_constant (XEXP (operands
[1], 0)),
7717 get_pool_mode (XEXP (operands
[1], 0))))
7721 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7723 if (can_create_pseudo_p ())
7724 reg
= gen_reg_rtx (Pmode
);
7728 tocref
= create_TOC_reference (XEXP (operands
[1], 0), reg
);
7729 operands
[1] = gen_const_mem (mode
, tocref
);
7730 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
7736 rs6000_eliminate_indexed_memrefs (operands
);
7740 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
7742 gen_rtx_SET (VOIDmode
,
7743 operands
[0], operands
[1]),
7744 gen_rtx_CLOBBER (VOIDmode
,
7745 gen_rtx_SCRATCH (SImode
)))));
7751 fatal_insn ("bad move", gen_rtx_SET (VOIDmode
, dest
, source
));
7754 /* Above, we may have called force_const_mem which may have returned
7755 an invalid address. If we can, fix this up; otherwise, reload will
7756 have to deal with it. */
7757 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
7758 operands
[1] = validize_mem (operands
[1]);
7761 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7764 /* Nonzero if we can use a floating-point register to pass this arg. */
7765 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7766 (SCALAR_FLOAT_MODE_P (MODE) \
7767 && (CUM)->fregno <= FP_ARG_MAX_REG \
7768 && TARGET_HARD_FLOAT && TARGET_FPRS)
7770 /* Nonzero if we can use an AltiVec register to pass this arg. */
7771 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7772 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7773 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7774 && TARGET_ALTIVEC_ABI \
7777 /* Return a nonzero value to say to return the function value in
7778 memory, just as large structures are always returned. TYPE will be
7779 the data type of the value, and FNTYPE will be the type of the
7780 function doing the returning, or @code{NULL} for libcalls.
7782 The AIX ABI for the RS/6000 specifies that all structures are
7783 returned in memory. The Darwin ABI does the same.
7785 For the Darwin 64 Bit ABI, a function result can be returned in
7786 registers or in memory, depending on the size of the return data
7787 type. If it is returned in registers, the value occupies the same
7788 registers as it would if it were the first and only function
7789 argument. Otherwise, the function places its result in memory at
7790 the location pointed to by GPR3.
7792 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7793 but a draft put them in memory, and GCC used to implement the draft
7794 instead of the final standard. Therefore, aix_struct_return
7795 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7796 compatibility can change DRAFT_V4_STRUCT_RET to override the
7797 default, and -m switches get the final word. See
7798 rs6000_option_override_internal for more details.
7800 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7801 long double support is enabled. These values are returned in memory.
7803 int_size_in_bytes returns -1 for variable size objects, which go in
7804 memory always. The cast to unsigned makes -1 > 8. */
7807 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7809 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7811 && rs6000_darwin64_abi
7812 && TREE_CODE (type
) == RECORD_TYPE
7813 && int_size_in_bytes (type
) > 0)
7815 CUMULATIVE_ARGS valcum
;
7819 valcum
.fregno
= FP_ARG_MIN_REG
;
7820 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
7821 /* Do a trial code generation as if this were going to be passed
7822 as an argument; if any part goes in memory, we return NULL. */
7823 valret
= rs6000_darwin64_record_arg (&valcum
, type
, true, true);
7826 /* Otherwise fall through to more conventional ABI rules. */
7829 if (AGGREGATE_TYPE_P (type
)
7830 && (aix_struct_return
7831 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
7834 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7835 modes only exist for GCC vector types if -maltivec. */
7836 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
7837 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7840 /* Return synthetic vectors in memory. */
7841 if (TREE_CODE (type
) == VECTOR_TYPE
7842 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
7844 static bool warned_for_return_big_vectors
= false;
7845 if (!warned_for_return_big_vectors
)
7847 warning (0, "GCC vector returned by reference: "
7848 "non-standard ABI extension with no compatibility guarantee");
7849 warned_for_return_big_vectors
= true;
7854 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
7860 #ifdef HAVE_AS_GNU_ATTRIBUTE
7861 /* Return TRUE if a call to function FNDECL may be one that
7862 potentially affects the function calling ABI of the object file. */
7865 call_ABI_of_interest (tree fndecl
)
7867 if (cgraph_state
== CGRAPH_STATE_EXPANSION
)
7869 struct cgraph_node
*c_node
;
7871 /* Libcalls are always interesting. */
7872 if (fndecl
== NULL_TREE
)
7875 /* Any call to an external function is interesting. */
7876 if (DECL_EXTERNAL (fndecl
))
7879 /* Interesting functions that we are emitting in this object file. */
7880 c_node
= cgraph_get_node (fndecl
);
7881 return !cgraph_only_called_directly_p (c_node
);
7887 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7888 for a call to a function whose data type is FNTYPE.
7889 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7891 For incoming args we set the number of arguments in the prototype large
7892 so we never return a PARALLEL. */
7895 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
7896 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
7897 int libcall
, int n_named_args
,
7898 tree fndecl ATTRIBUTE_UNUSED
,
7899 enum machine_mode return_mode ATTRIBUTE_UNUSED
)
7901 static CUMULATIVE_ARGS zero_cumulative
;
7903 *cum
= zero_cumulative
;
7905 cum
->fregno
= FP_ARG_MIN_REG
;
7906 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
7907 cum
->prototype
= (fntype
&& prototype_p (fntype
));
7908 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
7909 ? CALL_LIBCALL
: CALL_NORMAL
);
7910 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
7911 cum
->stdarg
= stdarg_p (fntype
);
7913 cum
->nargs_prototype
= 0;
7914 if (incoming
|| cum
->prototype
)
7915 cum
->nargs_prototype
= n_named_args
;
7917 /* Check for a longcall attribute. */
7918 if ((!fntype
&& rs6000_default_long_calls
)
7920 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
7921 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
7922 cum
->call_cookie
|= CALL_LONG
;
7924 if (TARGET_DEBUG_ARG
)
7926 fprintf (stderr
, "\ninit_cumulative_args:");
7929 tree ret_type
= TREE_TYPE (fntype
);
7930 fprintf (stderr
, " ret code = %s,",
7931 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
7934 if (cum
->call_cookie
& CALL_LONG
)
7935 fprintf (stderr
, " longcall,");
7937 fprintf (stderr
, " proto = %d, nargs = %d\n",
7938 cum
->prototype
, cum
->nargs_prototype
);
7941 #ifdef HAVE_AS_GNU_ATTRIBUTE
7942 if (DEFAULT_ABI
== ABI_V4
)
7944 cum
->escapes
= call_ABI_of_interest (fndecl
);
7951 return_type
= TREE_TYPE (fntype
);
7952 return_mode
= TYPE_MODE (return_type
);
7955 return_type
= lang_hooks
.types
.type_for_mode (return_mode
, 0);
7957 if (return_type
!= NULL
)
7959 if (TREE_CODE (return_type
) == RECORD_TYPE
7960 && TYPE_TRANSPARENT_AGGR (return_type
))
7962 return_type
= TREE_TYPE (first_field (return_type
));
7963 return_mode
= TYPE_MODE (return_type
);
7965 if (AGGREGATE_TYPE_P (return_type
)
7966 && ((unsigned HOST_WIDE_INT
) int_size_in_bytes (return_type
)
7968 rs6000_returns_struct
= true;
7970 if (SCALAR_FLOAT_MODE_P (return_mode
))
7971 rs6000_passes_float
= true;
7972 else if (ALTIVEC_VECTOR_MODE (return_mode
)
7973 || VSX_VECTOR_MODE (return_mode
)
7974 || SPE_VECTOR_MODE (return_mode
))
7975 rs6000_passes_vector
= true;
7982 && TARGET_ALTIVEC_ABI
7983 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
7985 error ("cannot return value in vector register because"
7986 " altivec instructions are disabled, use -maltivec"
7991 /* Return true if TYPE must be passed on the stack and not in registers. */
7994 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
7996 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
7997 return must_pass_in_stack_var_size (mode
, type
);
7999 return must_pass_in_stack_var_size_or_pad (mode
, type
);
8002 /* If defined, a C expression which determines whether, and in which
8003 direction, to pad out an argument with extra space. The value
8004 should be of type `enum direction': either `upward' to pad above
8005 the argument, `downward' to pad below, or `none' to inhibit
8008 For the AIX ABI structs are always stored left shifted in their
8012 function_arg_padding (enum machine_mode mode
, const_tree type
)
8014 #ifndef AGGREGATE_PADDING_FIXED
8015 #define AGGREGATE_PADDING_FIXED 0
8017 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8018 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8021 if (!AGGREGATE_PADDING_FIXED
)
8023 /* GCC used to pass structures of the same size as integer types as
8024 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8025 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8026 passed padded downward, except that -mstrict-align further
8027 muddied the water in that multi-component structures of 2 and 4
8028 bytes in size were passed padded upward.
8030 The following arranges for best compatibility with previous
8031 versions of gcc, but removes the -mstrict-align dependency. */
8032 if (BYTES_BIG_ENDIAN
)
8034 HOST_WIDE_INT size
= 0;
8036 if (mode
== BLKmode
)
8038 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
8039 size
= int_size_in_bytes (type
);
8042 size
= GET_MODE_SIZE (mode
);
8044 if (size
== 1 || size
== 2 || size
== 4)
8050 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
8052 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
8056 /* Fall back to the default. */
8057 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
8060 /* If defined, a C expression that gives the alignment boundary, in bits,
8061 of an argument with the specified mode and type. If it is not defined,
8062 PARM_BOUNDARY is used for all arguments.
8064 V.4 wants long longs and doubles to be double word aligned. Just
8065 testing the mode size is a boneheaded way to do this as it means
8066 that other types such as complex int are also double word aligned.
8067 However, we're stuck with this because changing the ABI might break
8068 existing library interfaces.
8070 Doubleword align SPE vectors.
8071 Quadword align Altivec vectors.
8072 Quadword align large synthetic vector types. */
8075 rs6000_function_arg_boundary (enum machine_mode mode
, const_tree type
)
8077 if (DEFAULT_ABI
== ABI_V4
8078 && (GET_MODE_SIZE (mode
) == 8
8079 || (TARGET_HARD_FLOAT
8081 && (mode
== TFmode
|| mode
== TDmode
))))
8083 else if (SPE_VECTOR_MODE (mode
)
8084 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8085 && int_size_in_bytes (type
) >= 8
8086 && int_size_in_bytes (type
) < 16))
8088 else if ((ALTIVEC_VECTOR_MODE (mode
) || VSX_VECTOR_MODE (mode
))
8089 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8090 && int_size_in_bytes (type
) >= 16))
8092 else if (TARGET_MACHO
8093 && rs6000_darwin64_abi
8095 && type
&& TYPE_ALIGN (type
) > 64)
8098 return PARM_BOUNDARY
;
8101 /* For a function parm of MODE and TYPE, return the starting word in
8102 the parameter area. NWORDS of the parameter area are already used. */
8105 rs6000_parm_start (enum machine_mode mode
, const_tree type
,
8106 unsigned int nwords
)
8109 unsigned int parm_offset
;
8111 align
= rs6000_function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
8112 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
8113 return nwords
+ (-(parm_offset
+ nwords
) & align
);
8116 /* Compute the size (in words) of a function argument. */
8118 static unsigned long
8119 rs6000_arg_size (enum machine_mode mode
, const_tree type
)
8123 if (mode
!= BLKmode
)
8124 size
= GET_MODE_SIZE (mode
);
8126 size
= int_size_in_bytes (type
);
8129 return (size
+ 3) >> 2;
8131 return (size
+ 7) >> 3;
8134 /* Use this to flush pending int fields. */
8137 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
8138 HOST_WIDE_INT bitpos
, int final
)
8140 unsigned int startbit
, endbit
;
8141 int intregs
, intoffset
;
8142 enum machine_mode mode
;
8144 /* Handle the situations where a float is taking up the first half
8145 of the GPR, and the other half is empty (typically due to
8146 alignment restrictions). We can detect this by a 8-byte-aligned
8147 int field, or by seeing that this is the final flush for this
8148 argument. Count the word and continue on. */
8149 if (cum
->floats_in_gpr
== 1
8150 && (cum
->intoffset
% 64 == 0
8151 || (cum
->intoffset
== -1 && final
)))
8154 cum
->floats_in_gpr
= 0;
8157 if (cum
->intoffset
== -1)
8160 intoffset
= cum
->intoffset
;
8161 cum
->intoffset
= -1;
8162 cum
->floats_in_gpr
= 0;
8164 if (intoffset
% BITS_PER_WORD
!= 0)
8166 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
8168 if (mode
== BLKmode
)
8170 /* We couldn't find an appropriate mode, which happens,
8171 e.g., in packed structs when there are 3 bytes to load.
8172 Back intoffset back to the beginning of the word in this
8174 intoffset
= intoffset
& -BITS_PER_WORD
;
8178 startbit
= intoffset
& -BITS_PER_WORD
;
8179 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
8180 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
8181 cum
->words
+= intregs
;
8182 /* words should be unsigned. */
8183 if ((unsigned)cum
->words
< (endbit
/BITS_PER_WORD
))
8185 int pad
= (endbit
/BITS_PER_WORD
) - cum
->words
;
8190 /* The darwin64 ABI calls for us to recurse down through structs,
8191 looking for elements passed in registers. Unfortunately, we have
8192 to track int register count here also because of misalignments
8193 in powerpc alignment mode. */
8196 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
8198 HOST_WIDE_INT startbitpos
)
8202 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
8203 if (TREE_CODE (f
) == FIELD_DECL
)
8205 HOST_WIDE_INT bitpos
= startbitpos
;
8206 tree ftype
= TREE_TYPE (f
);
8207 enum machine_mode mode
;
8208 if (ftype
== error_mark_node
)
8210 mode
= TYPE_MODE (ftype
);
8212 if (DECL_SIZE (f
) != 0
8213 && host_integerp (bit_position (f
), 1))
8214 bitpos
+= int_bit_position (f
);
8216 /* ??? FIXME: else assume zero offset. */
8218 if (TREE_CODE (ftype
) == RECORD_TYPE
)
8219 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
8220 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
8222 unsigned n_fpregs
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8223 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
8224 cum
->fregno
+= n_fpregs
;
8225 /* Single-precision floats present a special problem for
8226 us, because they are smaller than an 8-byte GPR, and so
8227 the structure-packing rules combined with the standard
8228 varargs behavior mean that we want to pack float/float
8229 and float/int combinations into a single register's
8230 space. This is complicated by the arg advance flushing,
8231 which works on arbitrarily large groups of int-type
8235 if (cum
->floats_in_gpr
== 1)
8237 /* Two floats in a word; count the word and reset
8240 cum
->floats_in_gpr
= 0;
8242 else if (bitpos
% 64 == 0)
8244 /* A float at the beginning of an 8-byte word;
8245 count it and put off adjusting cum->words until
8246 we see if a arg advance flush is going to do it
8248 cum
->floats_in_gpr
++;
8252 /* The float is at the end of a word, preceded
8253 by integer fields, so the arg advance flush
8254 just above has already set cum->words and
8255 everything is taken care of. */
8259 cum
->words
+= n_fpregs
;
8261 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
8263 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
8267 else if (cum
->intoffset
== -1)
8268 cum
->intoffset
= bitpos
;
8272 /* Check for an item that needs to be considered specially under the darwin 64
8273 bit ABI. These are record types where the mode is BLK or the structure is
8276 rs6000_darwin64_struct_check_p (enum machine_mode mode
, const_tree type
)
8278 return rs6000_darwin64_abi
8279 && ((mode
== BLKmode
8280 && TREE_CODE (type
) == RECORD_TYPE
8281 && int_size_in_bytes (type
) > 0)
8282 || (type
&& TREE_CODE (type
) == RECORD_TYPE
8283 && int_size_in_bytes (type
) == 8)) ? 1 : 0;
8286 /* Update the data in CUM to advance over an argument
8287 of mode MODE and data type TYPE.
8288 (TYPE is null for libcalls where that information may not be available.)
8290 Note that for args passed by reference, function_arg will be called
8291 with MODE and TYPE set to that of the pointer to the arg, not the arg
8295 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8296 const_tree type
, bool named
, int depth
)
8298 /* Only tick off an argument if we're not recursing. */
8300 cum
->nargs_prototype
--;
8302 #ifdef HAVE_AS_GNU_ATTRIBUTE
8303 if (DEFAULT_ABI
== ABI_V4
8306 if (SCALAR_FLOAT_MODE_P (mode
))
8307 rs6000_passes_float
= true;
8308 else if (named
&& (ALTIVEC_VECTOR_MODE (mode
) || VSX_VECTOR_MODE (mode
)))
8309 rs6000_passes_vector
= true;
8310 else if (SPE_VECTOR_MODE (mode
)
8312 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
8313 rs6000_passes_vector
= true;
8317 if (TARGET_ALTIVEC_ABI
8318 && (ALTIVEC_VECTOR_MODE (mode
)
8319 || VSX_VECTOR_MODE (mode
)
8320 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8321 && int_size_in_bytes (type
) == 16)))
8325 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
8328 if (!TARGET_ALTIVEC
)
8329 error ("cannot pass argument in vector register because"
8330 " altivec instructions are disabled, use -maltivec"
8333 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8334 even if it is going to be passed in a vector register.
8335 Darwin does the same for variable-argument functions. */
8336 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
8337 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
8347 /* Vector parameters must be 16-byte aligned. This places
8348 them at 2 mod 4 in terms of words in 32-bit mode, since
8349 the parameter save area starts at offset 24 from the
8350 stack. In 64-bit mode, they just have to start on an
8351 even word, since the parameter save area is 16-byte
8352 aligned. Space for GPRs is reserved even if the argument
8353 will be passed in memory. */
8355 align
= (2 - cum
->words
) & 3;
8357 align
= cum
->words
& 1;
8358 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
8360 if (TARGET_DEBUG_ARG
)
8362 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
8364 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
8365 cum
->nargs_prototype
, cum
->prototype
,
8366 GET_MODE_NAME (mode
));
8370 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
8372 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
8375 else if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8377 int size
= int_size_in_bytes (type
);
8378 /* Variable sized types have size == -1 and are
8379 treated as if consisting entirely of ints.
8380 Pad to 16 byte boundary if needed. */
8381 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8382 && (cum
->words
% 2) != 0)
8384 /* For varargs, we can just go up by the size of the struct. */
8386 cum
->words
+= (size
+ 7) / 8;
8389 /* It is tempting to say int register count just goes up by
8390 sizeof(type)/8, but this is wrong in a case such as
8391 { int; double; int; } [powerpc alignment]. We have to
8392 grovel through the fields for these too. */
8394 cum
->floats_in_gpr
= 0;
8395 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
8396 rs6000_darwin64_record_arg_advance_flush (cum
,
8397 size
* BITS_PER_UNIT
, 1);
8399 if (TARGET_DEBUG_ARG
)
8401 fprintf (stderr
, "function_adv: words = %2d, align=%d, size=%d",
8402 cum
->words
, TYPE_ALIGN (type
), size
);
8404 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8405 cum
->nargs_prototype
, cum
->prototype
,
8406 GET_MODE_NAME (mode
));
8409 else if (DEFAULT_ABI
== ABI_V4
)
8411 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8412 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
8413 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
8414 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
8415 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8417 /* _Decimal128 must use an even/odd register pair. This assumes
8418 that the register number is odd when fregno is odd. */
8419 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8422 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
8423 <= FP_ARG_V4_MAX_REG
)
8424 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8427 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
8428 if (mode
== DFmode
|| mode
== TFmode
8429 || mode
== DDmode
|| mode
== TDmode
)
8430 cum
->words
+= cum
->words
& 1;
8431 cum
->words
+= rs6000_arg_size (mode
, type
);
8436 int n_words
= rs6000_arg_size (mode
, type
);
8437 int gregno
= cum
->sysv_gregno
;
8439 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8440 (r7,r8) or (r9,r10). As does any other 2 word item such
8441 as complex int due to a historical mistake. */
8443 gregno
+= (1 - gregno
) & 1;
8445 /* Multi-reg args are not split between registers and stack. */
8446 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8448 /* Long long and SPE vectors are aligned on the stack.
8449 So are other 2 word items such as complex int due to
8450 a historical mistake. */
8452 cum
->words
+= cum
->words
& 1;
8453 cum
->words
+= n_words
;
8456 /* Note: continuing to accumulate gregno past when we've started
8457 spilling to the stack indicates the fact that we've started
8458 spilling to the stack to expand_builtin_saveregs. */
8459 cum
->sysv_gregno
= gregno
+ n_words
;
8462 if (TARGET_DEBUG_ARG
)
8464 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8465 cum
->words
, cum
->fregno
);
8466 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
8467 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
8468 fprintf (stderr
, "mode = %4s, named = %d\n",
8469 GET_MODE_NAME (mode
), named
);
8474 int n_words
= rs6000_arg_size (mode
, type
);
8475 int start_words
= cum
->words
;
8476 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
8478 cum
->words
= align_words
+ n_words
;
8480 if (SCALAR_FLOAT_MODE_P (mode
)
8481 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8483 /* _Decimal128 must be passed in an even/odd float register pair.
8484 This assumes that the register number is odd when fregno is
8486 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8488 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8491 if (TARGET_DEBUG_ARG
)
8493 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8494 cum
->words
, cum
->fregno
);
8495 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
8496 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
8497 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
8498 named
, align_words
- start_words
, depth
);
8504 rs6000_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8505 const_tree type
, bool named
)
8507 rs6000_function_arg_advance_1 (cum
, mode
, type
, named
, 0);
8511 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
8518 r1
= gen_rtx_REG (DImode
, gregno
);
8519 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8520 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
8524 r1
= gen_rtx_REG (DImode
, gregno
);
8525 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8526 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8527 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8528 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
8531 r1
= gen_rtx_REG (DImode
, gregno
);
8532 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8533 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8534 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8535 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
8536 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
8537 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
8538 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
8539 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
8546 /* Determine where to put a SIMD argument on the SPE. */
8548 rs6000_spe_function_arg (const CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8551 int gregno
= cum
->sysv_gregno
;
8553 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8554 are passed and returned in a pair of GPRs for ABI compatibility. */
8555 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
8556 || mode
== DCmode
|| mode
== TCmode
))
8558 int n_words
= rs6000_arg_size (mode
, type
);
8560 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8562 gregno
+= (1 - gregno
) & 1;
8564 /* Multi-reg args are not split between registers and stack. */
8565 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8568 return spe_build_register_parallel (mode
, gregno
);
8572 int n_words
= rs6000_arg_size (mode
, type
);
8574 /* SPE vectors are put in odd registers. */
8575 if (n_words
== 2 && (gregno
& 1) == 0)
8578 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
8581 enum machine_mode m
= SImode
;
8583 r1
= gen_rtx_REG (m
, gregno
);
8584 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
8585 r2
= gen_rtx_REG (m
, gregno
+ 1);
8586 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
8587 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
8594 if (gregno
<= GP_ARG_MAX_REG
)
8595 return gen_rtx_REG (mode
, gregno
);
8601 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8602 structure between cum->intoffset and bitpos to integer registers. */
8605 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
8606 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
8608 enum machine_mode mode
;
8610 unsigned int startbit
, endbit
;
8611 int this_regno
, intregs
, intoffset
;
8614 if (cum
->intoffset
== -1)
8617 intoffset
= cum
->intoffset
;
8618 cum
->intoffset
= -1;
8620 /* If this is the trailing part of a word, try to only load that
8621 much into the register. Otherwise load the whole register. Note
8622 that in the latter case we may pick up unwanted bits. It's not a
8623 problem at the moment but may wish to revisit. */
8625 if (intoffset
% BITS_PER_WORD
!= 0)
8627 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
8629 if (mode
== BLKmode
)
8631 /* We couldn't find an appropriate mode, which happens,
8632 e.g., in packed structs when there are 3 bytes to load.
8633 Back intoffset back to the beginning of the word in this
8635 intoffset
= intoffset
& -BITS_PER_WORD
;
8642 startbit
= intoffset
& -BITS_PER_WORD
;
8643 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
8644 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
8645 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
8647 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
8650 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
8654 intoffset
/= BITS_PER_UNIT
;
8657 regno
= GP_ARG_MIN_REG
+ this_regno
;
8658 reg
= gen_rtx_REG (mode
, regno
);
8660 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
8663 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
8667 while (intregs
> 0);
8670 /* Recursive workhorse for the following. */
8673 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
8674 HOST_WIDE_INT startbitpos
, rtx rvec
[],
8679 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
8680 if (TREE_CODE (f
) == FIELD_DECL
)
8682 HOST_WIDE_INT bitpos
= startbitpos
;
8683 tree ftype
= TREE_TYPE (f
);
8684 enum machine_mode mode
;
8685 if (ftype
== error_mark_node
)
8687 mode
= TYPE_MODE (ftype
);
8689 if (DECL_SIZE (f
) != 0
8690 && host_integerp (bit_position (f
), 1))
8691 bitpos
+= int_bit_position (f
);
8693 /* ??? FIXME: else assume zero offset. */
8695 if (TREE_CODE (ftype
) == RECORD_TYPE
)
8696 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
8697 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
8699 unsigned n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8703 case SCmode
: mode
= SFmode
; break;
8704 case DCmode
: mode
= DFmode
; break;
8705 case TCmode
: mode
= TFmode
; break;
8709 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8710 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
8712 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
8713 && (mode
== TFmode
|| mode
== TDmode
));
8714 /* Long double or _Decimal128 split over regs and memory. */
8715 mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
8719 = gen_rtx_EXPR_LIST (VOIDmode
,
8720 gen_rtx_REG (mode
, cum
->fregno
++),
8721 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8722 if (mode
== TFmode
|| mode
== TDmode
)
8725 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
8727 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8729 = gen_rtx_EXPR_LIST (VOIDmode
,
8730 gen_rtx_REG (mode
, cum
->vregno
++),
8731 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8733 else if (cum
->intoffset
== -1)
8734 cum
->intoffset
= bitpos
;
8738 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8739 the register(s) to be used for each field and subfield of a struct
8740 being passed by value, along with the offset of where the
8741 register's value may be found in the block. FP fields go in FP
8742 register, vector fields go in vector registers, and everything
8743 else goes in int registers, packed as in memory.
8745 This code is also used for function return values. RETVAL indicates
8746 whether this is the case.
8748 Much of this is taken from the SPARC V9 port, which has a similar
8749 calling convention. */
8752 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
8753 bool named
, bool retval
)
8755 rtx rvec
[FIRST_PSEUDO_REGISTER
];
8756 int k
= 1, kbase
= 1;
8757 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
8758 /* This is a copy; modifications are not visible to our caller. */
8759 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
8760 CUMULATIVE_ARGS
*cum
= ©_cum
;
8762 /* Pad to 16 byte boundary if needed. */
8763 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8764 && (cum
->words
% 2) != 0)
8771 /* Put entries into rvec[] for individual FP and vector fields, and
8772 for the chunks of memory that go in int regs. Note we start at
8773 element 1; 0 is reserved for an indication of using memory, and
8774 may or may not be filled in below. */
8775 rs6000_darwin64_record_arg_recurse (cum
, type
, /* startbit pos= */ 0, rvec
, &k
);
8776 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
8778 /* If any part of the struct went on the stack put all of it there.
8779 This hack is because the generic code for
8780 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8781 parts of the struct are not at the beginning. */
8785 return NULL_RTX
; /* doesn't go in registers at all */
8787 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8789 if (k
> 1 || cum
->use_stack
)
8790 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
8795 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8798 rs6000_mixed_function_arg (enum machine_mode mode
, const_tree type
,
8803 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8805 if (align_words
>= GP_ARG_NUM_REG
)
8808 n_units
= rs6000_arg_size (mode
, type
);
8810 /* Optimize the simple case where the arg fits in one gpr, except in
8811 the case of BLKmode due to assign_parms assuming that registers are
8812 BITS_PER_WORD wide. */
8814 || (n_units
== 1 && mode
!= BLKmode
))
8815 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8818 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
8819 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8820 using a magic NULL_RTX component.
8821 This is not strictly correct. Only some of the arg belongs in
8822 memory, not all of it. However, the normal scheme using
8823 function_arg_partial_nregs can result in unusual subregs, eg.
8824 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8825 store the whole arg to memory is often more efficient than code
8826 to store pieces, and we know that space is available in the right
8827 place for the whole arg. */
8828 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8833 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
8834 rtx off
= GEN_INT (i
++ * 4);
8835 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8837 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
8839 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8842 /* Determine where to put an argument to a function.
8843 Value is zero to push the argument on the stack,
8844 or a hard register in which to store the argument.
8846 MODE is the argument's machine mode.
8847 TYPE is the data type of the argument (as a tree).
8848 This is null for libcalls where that information may
8850 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8851 the preceding args and about the function being called. It is
8852 not modified in this routine.
8853 NAMED is nonzero if this argument is a named parameter
8854 (otherwise it is an extra parameter matching an ellipsis).
8856 On RS/6000 the first eight words of non-FP are normally in registers
8857 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8858 Under V.4, the first 8 FP args are in registers.
8860 If this is floating-point and no prototype is specified, we use
8861 both an FP and integer register (or possibly FP reg and stack). Library
8862 functions (when CALL_LIBCALL is set) always have the proper types for args,
8863 so we can pass the FP value just in one register. emit_library_function
8864 doesn't support PARALLEL anyway.
8866 Note that for args passed by reference, function_arg will be called
8867 with MODE and TYPE set to that of the pointer to the arg, not the arg
8871 rs6000_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8872 const_tree type
, bool named
)
8874 enum rs6000_abi abi
= DEFAULT_ABI
;
8876 /* Return a marker to indicate whether CR1 needs to set or clear the
8877 bit that V.4 uses to say fp args were passed in registers.
8878 Assume that we don't need the marker for software floating point,
8879 or compiler generated library calls. */
8880 if (mode
== VOIDmode
)
8883 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
8885 || (cum
->nargs_prototype
< 0
8886 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
8888 /* For the SPE, we need to crxor CR6 always. */
8890 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
8891 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8892 return GEN_INT (cum
->call_cookie
8893 | ((cum
->fregno
== FP_ARG_MIN_REG
)
8894 ? CALL_V4_SET_FP_ARGS
8895 : CALL_V4_CLEAR_FP_ARGS
));
8898 return GEN_INT (cum
->call_cookie
& ~CALL_LIBCALL
);
8901 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8903 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, /*retval= */false);
8904 if (rslt
!= NULL_RTX
)
8906 /* Else fall through to usual handling. */
8909 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
8910 if (TARGET_64BIT
&& ! cum
->prototype
)
8912 /* Vector parameters get passed in vector register
8913 and also in GPRs or memory, in absence of prototype. */
8916 align_words
= (cum
->words
+ 1) & ~1;
8918 if (align_words
>= GP_ARG_NUM_REG
)
8924 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8926 return gen_rtx_PARALLEL (mode
,
8928 gen_rtx_EXPR_LIST (VOIDmode
,
8930 gen_rtx_EXPR_LIST (VOIDmode
,
8931 gen_rtx_REG (mode
, cum
->vregno
),
8935 return gen_rtx_REG (mode
, cum
->vregno
);
8936 else if (TARGET_ALTIVEC_ABI
8937 && (ALTIVEC_VECTOR_MODE (mode
)
8938 || VSX_VECTOR_MODE (mode
)
8939 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8940 && int_size_in_bytes (type
) == 16)))
8942 if (named
|| abi
== ABI_V4
)
8946 /* Vector parameters to varargs functions under AIX or Darwin
8947 get passed in memory and possibly also in GPRs. */
8948 int align
, align_words
, n_words
;
8949 enum machine_mode part_mode
;
8951 /* Vector parameters must be 16-byte aligned. This places them at
8952 2 mod 4 in terms of words in 32-bit mode, since the parameter
8953 save area starts at offset 24 from the stack. In 64-bit mode,
8954 they just have to start on an even word, since the parameter
8955 save area is 16-byte aligned. */
8957 align
= (2 - cum
->words
) & 3;
8959 align
= cum
->words
& 1;
8960 align_words
= cum
->words
+ align
;
8962 /* Out of registers? Memory, then. */
8963 if (align_words
>= GP_ARG_NUM_REG
)
8966 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8967 return rs6000_mixed_function_arg (mode
, type
, align_words
);
8969 /* The vector value goes in GPRs. Only the part of the
8970 value in GPRs is reported here. */
8972 n_words
= rs6000_arg_size (mode
, type
);
8973 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
8974 /* Fortunately, there are only two possibilities, the value
8975 is either wholly in GPRs or half in GPRs and half not. */
8978 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
8981 else if (TARGET_SPE_ABI
&& TARGET_SPE
8982 && (SPE_VECTOR_MODE (mode
)
8983 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
8986 || mode
== TCmode
))))
8987 return rs6000_spe_function_arg (cum
, mode
, type
);
8989 else if (abi
== ABI_V4
)
8991 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8992 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
8993 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
8994 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
8995 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8997 /* _Decimal128 must use an even/odd register pair. This assumes
8998 that the register number is odd when fregno is odd. */
8999 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
9002 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
9003 <= FP_ARG_V4_MAX_REG
)
9004 return gen_rtx_REG (mode
, cum
->fregno
);
9010 int n_words
= rs6000_arg_size (mode
, type
);
9011 int gregno
= cum
->sysv_gregno
;
9013 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9014 (r7,r8) or (r9,r10). As does any other 2 word item such
9015 as complex int due to a historical mistake. */
9017 gregno
+= (1 - gregno
) & 1;
9019 /* Multi-reg args are not split between registers and stack. */
9020 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
9023 if (TARGET_32BIT
&& TARGET_POWERPC64
)
9024 return rs6000_mixed_function_arg (mode
, type
,
9025 gregno
- GP_ARG_MIN_REG
);
9026 return gen_rtx_REG (mode
, gregno
);
9031 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
9033 /* _Decimal128 must be passed in an even/odd float register pair.
9034 This assumes that the register number is odd when fregno is odd. */
9035 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
9038 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
9040 rtx rvec
[GP_ARG_NUM_REG
+ 1];
9044 enum machine_mode fmode
= mode
;
9045 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
9047 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
9049 /* Currently, we only ever need one reg here because complex
9050 doubles are split. */
9051 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
9052 && (fmode
== TFmode
|| fmode
== TDmode
));
9054 /* Long double or _Decimal128 split over regs and memory. */
9055 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
9058 /* Do we also need to pass this arg in the parameter save
9061 && (cum
->nargs_prototype
<= 0
9062 || (DEFAULT_ABI
== ABI_AIX
9064 && align_words
>= GP_ARG_NUM_REG
)));
9066 if (!needs_psave
&& mode
== fmode
)
9067 return gen_rtx_REG (fmode
, cum
->fregno
);
9072 /* Describe the part that goes in gprs or the stack.
9073 This piece must come first, before the fprs. */
9074 if (align_words
< GP_ARG_NUM_REG
)
9076 unsigned long n_words
= rs6000_arg_size (mode
, type
);
9078 if (align_words
+ n_words
> GP_ARG_NUM_REG
9079 || (TARGET_32BIT
&& TARGET_POWERPC64
))
9081 /* If this is partially on the stack, then we only
9082 include the portion actually in registers here. */
9083 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
9086 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
9087 /* Not all of the arg fits in gprs. Say that it
9088 goes in memory too, using a magic NULL_RTX
9089 component. Also see comment in
9090 rs6000_mixed_function_arg for why the normal
9091 function_arg_partial_nregs scheme doesn't work
9093 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
9097 r
= gen_rtx_REG (rmode
,
9098 GP_ARG_MIN_REG
+ align_words
);
9099 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
9100 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
9102 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
9106 /* The whole arg fits in gprs. */
9107 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
9108 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
9112 /* It's entirely in memory. */
9113 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
9116 /* Describe where this piece goes in the fprs. */
9117 r
= gen_rtx_REG (fmode
, cum
->fregno
);
9118 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
9120 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
9122 else if (align_words
< GP_ARG_NUM_REG
)
9124 if (TARGET_32BIT
&& TARGET_POWERPC64
)
9125 return rs6000_mixed_function_arg (mode
, type
, align_words
);
9127 if (mode
== BLKmode
)
9130 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
9137 /* For an arg passed partly in registers and partly in memory, this is
9138 the number of bytes passed in registers. For args passed entirely in
9139 registers or entirely in memory, zero. When an arg is described by a
9140 PARALLEL, perhaps using more than one register type, this function
9141 returns the number of bytes used by the first element of the PARALLEL. */
9144 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
9145 tree type
, bool named
)
9150 if (DEFAULT_ABI
== ABI_V4
)
9153 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
9154 && cum
->nargs_prototype
>= 0)
9157 /* In this complicated case we just disable the partial_nregs code. */
9158 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
9161 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
9163 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
9165 /* If we are passing this arg in the fixed parameter save area
9166 (gprs or memory) as well as fprs, then this function should
9167 return the number of partial bytes passed in the parameter
9168 save area rather than partial bytes passed in fprs. */
9170 && (cum
->nargs_prototype
<= 0
9171 || (DEFAULT_ABI
== ABI_AIX
9173 && align_words
>= GP_ARG_NUM_REG
)))
9175 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
9176 > FP_ARG_MAX_REG
+ 1)
9177 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
9178 else if (cum
->nargs_prototype
>= 0)
9182 if (align_words
< GP_ARG_NUM_REG
9183 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
9184 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
9186 if (ret
!= 0 && TARGET_DEBUG_ARG
)
9187 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
9192 /* A C expression that indicates when an argument must be passed by
9193 reference. If nonzero for an argument, a copy of that argument is
9194 made in memory and a pointer to the argument is passed instead of
9195 the argument itself. The pointer is passed in whatever way is
9196 appropriate for passing a pointer to that type.
9198 Under V.4, aggregates and long double are passed by reference.
9200 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9201 reference unless the AltiVec vector extension ABI is in force.
9203 As an extension to all ABIs, variable sized types are passed by
9207 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
9208 enum machine_mode mode
, const_tree type
,
9209 bool named ATTRIBUTE_UNUSED
)
9211 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
9213 if (TARGET_DEBUG_ARG
)
9214 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
9221 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
9223 if (TARGET_DEBUG_ARG
)
9224 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
9228 if (int_size_in_bytes (type
) < 0)
9230 if (TARGET_DEBUG_ARG
)
9231 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
9235 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9236 modes only exist for GCC vector types if -maltivec. */
9237 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
9239 if (TARGET_DEBUG_ARG
)
9240 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
9244 /* Pass synthetic vectors in memory. */
9245 if (TREE_CODE (type
) == VECTOR_TYPE
9246 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
9248 static bool warned_for_pass_big_vectors
= false;
9249 if (TARGET_DEBUG_ARG
)
9250 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
9251 if (!warned_for_pass_big_vectors
)
9253 warning (0, "GCC vector passed by reference: "
9254 "non-standard ABI extension with no compatibility guarantee");
9255 warned_for_pass_big_vectors
= true;
9264 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
9267 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
9272 for (i
= 0; i
< nregs
; i
++)
9274 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
9275 if (reload_completed
)
9277 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
9280 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
9281 i
* GET_MODE_SIZE (reg_mode
));
9284 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
9288 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
9292 /* Perform any needed actions needed for a function that is receiving a
9293 variable number of arguments.
9297 MODE and TYPE are the mode and type of the current parameter.
9299 PRETEND_SIZE is a variable that should be set to the amount of stack
9300 that must be pushed by the prolog to pretend that our caller pushed
9303 Normally, this macro will push all remaining incoming registers on the
9304 stack and set PRETEND_SIZE to the length of the registers pushed. */
9307 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
9308 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
9311 CUMULATIVE_ARGS next_cum
;
9312 int reg_size
= TARGET_32BIT
? 4 : 8;
9313 rtx save_area
= NULL_RTX
, mem
;
9314 int first_reg_offset
;
9317 /* Skip the last named argument. */
9319 rs6000_function_arg_advance_1 (&next_cum
, mode
, type
, true, 0);
9321 if (DEFAULT_ABI
== ABI_V4
)
9323 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
9327 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
9328 HOST_WIDE_INT offset
= 0;
9330 /* Try to optimize the size of the varargs save area.
9331 The ABI requires that ap.reg_save_area is doubleword
9332 aligned, but we don't need to allocate space for all
9333 the bytes, only those to which we actually will save
9335 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
9336 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
9337 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9338 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
9339 && cfun
->va_list_fpr_size
)
9342 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
9343 * UNITS_PER_FP_WORD
;
9344 if (cfun
->va_list_fpr_size
9345 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
9346 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
9348 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
9349 * UNITS_PER_FP_WORD
;
9353 offset
= -((first_reg_offset
* reg_size
) & ~7);
9354 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
9356 gpr_reg_num
= cfun
->va_list_gpr_size
;
9357 if (reg_size
== 4 && (first_reg_offset
& 1))
9360 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
9363 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
9365 - (int) (GP_ARG_NUM_REG
* reg_size
);
9367 if (gpr_size
+ fpr_size
)
9370 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
9371 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
9372 reg_save_area
= XEXP (reg_save_area
, 0);
9373 if (GET_CODE (reg_save_area
) == PLUS
)
9375 gcc_assert (XEXP (reg_save_area
, 0)
9376 == virtual_stack_vars_rtx
);
9377 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
9378 offset
+= INTVAL (XEXP (reg_save_area
, 1));
9381 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
9384 cfun
->machine
->varargs_save_offset
= offset
;
9385 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
9390 first_reg_offset
= next_cum
.words
;
9391 save_area
= virtual_incoming_args_rtx
;
9393 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
9394 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
9397 set
= get_varargs_alias_set ();
9398 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
9399 && cfun
->va_list_gpr_size
)
9401 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
9403 if (va_list_gpr_counter_field
)
9405 /* V4 va_list_gpr_size counts number of registers needed. */
9406 if (nregs
> cfun
->va_list_gpr_size
)
9407 nregs
= cfun
->va_list_gpr_size
;
9411 /* char * va_list instead counts number of bytes needed. */
9412 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
9413 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
9416 mem
= gen_rtx_MEM (BLKmode
,
9417 plus_constant (save_area
,
9418 first_reg_offset
* reg_size
));
9419 MEM_NOTRAP_P (mem
) = 1;
9420 set_mem_alias_set (mem
, set
);
9421 set_mem_align (mem
, BITS_PER_WORD
);
9423 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
9427 /* Save FP registers if needed. */
9428 if (DEFAULT_ABI
== ABI_V4
9429 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9431 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
9432 && cfun
->va_list_fpr_size
)
9434 int fregno
= next_cum
.fregno
, nregs
;
9435 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
9436 rtx lab
= gen_label_rtx ();
9437 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
9438 * UNITS_PER_FP_WORD
);
9441 (gen_rtx_SET (VOIDmode
,
9443 gen_rtx_IF_THEN_ELSE (VOIDmode
,
9444 gen_rtx_NE (VOIDmode
, cr1
,
9446 gen_rtx_LABEL_REF (VOIDmode
, lab
),
9450 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
9451 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
9453 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9455 plus_constant (save_area
, off
));
9456 MEM_NOTRAP_P (mem
) = 1;
9457 set_mem_alias_set (mem
, set
);
9458 set_mem_align (mem
, GET_MODE_ALIGNMENT (
9459 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9460 ? DFmode
: SFmode
));
9461 emit_move_insn (mem
, gen_rtx_REG (
9462 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9463 ? DFmode
: SFmode
, fregno
));
9470 /* Create the va_list data type. */
9473 rs6000_build_builtin_va_list (void)
9475 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
9477 /* For AIX, prefer 'char *' because that's what the system
9478 header files like. */
9479 if (DEFAULT_ABI
!= ABI_V4
)
9480 return build_pointer_type (char_type_node
);
9482 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
9483 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9484 get_identifier ("__va_list_tag"), record
);
9486 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
9487 unsigned_char_type_node
);
9488 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
9489 unsigned_char_type_node
);
9490 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9492 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9493 get_identifier ("reserved"), short_unsigned_type_node
);
9494 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9495 get_identifier ("overflow_arg_area"),
9497 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9498 get_identifier ("reg_save_area"),
9501 va_list_gpr_counter_field
= f_gpr
;
9502 va_list_fpr_counter_field
= f_fpr
;
9504 DECL_FIELD_CONTEXT (f_gpr
) = record
;
9505 DECL_FIELD_CONTEXT (f_fpr
) = record
;
9506 DECL_FIELD_CONTEXT (f_res
) = record
;
9507 DECL_FIELD_CONTEXT (f_ovf
) = record
;
9508 DECL_FIELD_CONTEXT (f_sav
) = record
;
9510 TYPE_STUB_DECL (record
) = type_decl
;
9511 TYPE_NAME (record
) = type_decl
;
9512 TYPE_FIELDS (record
) = f_gpr
;
9513 DECL_CHAIN (f_gpr
) = f_fpr
;
9514 DECL_CHAIN (f_fpr
) = f_res
;
9515 DECL_CHAIN (f_res
) = f_ovf
;
9516 DECL_CHAIN (f_ovf
) = f_sav
;
9518 layout_type (record
);
9520 /* The correct type is an array type of one element. */
9521 return build_array_type (record
, build_index_type (size_zero_node
));
9524 /* Implement va_start. */
9527 rs6000_va_start (tree valist
, rtx nextarg
)
9529 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
9530 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9531 tree gpr
, fpr
, ovf
, sav
, t
;
9533 /* Only SVR4 needs something special. */
9534 if (DEFAULT_ABI
!= ABI_V4
)
9536 std_expand_builtin_va_start (valist
, nextarg
);
9540 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9541 f_fpr
= DECL_CHAIN (f_gpr
);
9542 f_res
= DECL_CHAIN (f_fpr
);
9543 f_ovf
= DECL_CHAIN (f_res
);
9544 f_sav
= DECL_CHAIN (f_ovf
);
9546 valist
= build_simple_mem_ref (valist
);
9547 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9548 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9550 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9552 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9555 /* Count number of gp and fp argument registers used. */
9556 words
= crtl
->args
.info
.words
;
9557 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
9559 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
9562 if (TARGET_DEBUG_ARG
)
9563 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
9564 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
9565 words
, n_gpr
, n_fpr
);
9567 if (cfun
->va_list_gpr_size
)
9569 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
9570 build_int_cst (NULL_TREE
, n_gpr
));
9571 TREE_SIDE_EFFECTS (t
) = 1;
9572 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9575 if (cfun
->va_list_fpr_size
)
9577 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
9578 build_int_cst (NULL_TREE
, n_fpr
));
9579 TREE_SIDE_EFFECTS (t
) = 1;
9580 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9582 #ifdef HAVE_AS_GNU_ATTRIBUTE
9583 if (call_ABI_of_interest (cfun
->decl
))
9584 rs6000_passes_float
= true;
9588 /* Find the overflow area. */
9589 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
9591 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
9592 size_int (words
* UNITS_PER_WORD
));
9593 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
9594 TREE_SIDE_EFFECTS (t
) = 1;
9595 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9597 /* If there were no va_arg invocations, don't set up the register
9599 if (!cfun
->va_list_gpr_size
9600 && !cfun
->va_list_fpr_size
9601 && n_gpr
< GP_ARG_NUM_REG
9602 && n_fpr
< FP_ARG_V4_MAX_REG
)
9605 /* Find the register save area. */
9606 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
9607 if (cfun
->machine
->varargs_save_offset
)
9608 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
9609 size_int (cfun
->machine
->varargs_save_offset
));
9610 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
9611 TREE_SIDE_EFFECTS (t
) = 1;
9612 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9615 /* Implement va_arg. */
9618 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
9621 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9622 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
9623 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
9624 tree lab_false
, lab_over
, addr
;
9626 tree ptrtype
= build_pointer_type_for_mode (type
, ptr_mode
, true);
9630 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
9632 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
9633 return build_va_arg_indirect_ref (t
);
9636 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9637 earlier version of gcc, with the property that it always applied alignment
9638 adjustments to the va-args (even for zero-sized types). The cheapest way
9639 to deal with this is to replicate the effect of the part of
9640 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9642 We don't need to check for pass-by-reference because of the test above.
9643 We can return a simplifed answer, since we know there's no offset to add. */
9646 && rs6000_darwin64_abi
9647 && integer_zerop (TYPE_SIZE (type
)))
9649 unsigned HOST_WIDE_INT align
, boundary
;
9650 tree valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
9651 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
9652 boundary
= rs6000_function_arg_boundary (TYPE_MODE (type
), type
);
9653 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
9654 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
9655 boundary
/= BITS_PER_UNIT
;
9656 if (boundary
> align
)
9659 /* This updates arg ptr by the amount that would be necessary
9660 to align the zero-sized (but not zero-alignment) item. */
9661 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9662 fold_build2 (POINTER_PLUS_EXPR
,
9664 valist_tmp
, size_int (boundary
- 1)));
9665 gimplify_and_add (t
, pre_p
);
9667 t
= fold_convert (sizetype
, valist_tmp
);
9668 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9669 fold_convert (TREE_TYPE (valist
),
9670 fold_build2 (BIT_AND_EXPR
, sizetype
, t
,
9671 size_int (-boundary
))));
9672 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
9673 gimplify_and_add (t
, pre_p
);
9675 /* Since it is zero-sized there's no increment for the item itself. */
9676 valist_tmp
= fold_convert (build_pointer_type (type
), valist_tmp
);
9677 return build_va_arg_indirect_ref (valist_tmp
);
9680 if (DEFAULT_ABI
!= ABI_V4
)
9682 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
9684 tree elem_type
= TREE_TYPE (type
);
9685 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
9686 int elem_size
= GET_MODE_SIZE (elem_mode
);
9688 if (elem_size
< UNITS_PER_WORD
)
9690 tree real_part
, imag_part
;
9691 gimple_seq post
= NULL
;
9693 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9695 /* Copy the value into a temporary, lest the formal temporary
9696 be reused out from under us. */
9697 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
9698 gimple_seq_add_seq (pre_p
, post
);
9700 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9703 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
9707 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
9710 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9711 f_fpr
= DECL_CHAIN (f_gpr
);
9712 f_res
= DECL_CHAIN (f_fpr
);
9713 f_ovf
= DECL_CHAIN (f_res
);
9714 f_sav
= DECL_CHAIN (f_ovf
);
9716 valist
= build_va_arg_indirect_ref (valist
);
9717 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9718 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9720 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9722 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9725 size
= int_size_in_bytes (type
);
9726 rsize
= (size
+ 3) / 4;
9729 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9730 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
9731 || (TARGET_DOUBLE_FLOAT
9732 && (TYPE_MODE (type
) == DFmode
9733 || TYPE_MODE (type
) == TFmode
9734 || TYPE_MODE (type
) == SDmode
9735 || TYPE_MODE (type
) == DDmode
9736 || TYPE_MODE (type
) == TDmode
))))
9738 /* FP args go in FP registers, if present. */
9740 n_reg
= (size
+ 7) / 8;
9741 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
9742 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
9743 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
9748 /* Otherwise into GP registers. */
9757 /* Pull the value out of the saved registers.... */
9760 addr
= create_tmp_var (ptr_type_node
, "addr");
9762 /* AltiVec vectors never go in registers when -mabi=altivec. */
9763 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
9767 lab_false
= create_artificial_label (input_location
);
9768 lab_over
= create_artificial_label (input_location
);
9770 /* Long long and SPE vectors are aligned in the registers.
9771 As are any other 2 gpr item such as complex int due to a
9772 historical mistake. */
9774 if (n_reg
== 2 && reg
== gpr
)
9777 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9778 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
9779 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
9780 unshare_expr (reg
), u
);
9782 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9783 reg number is 0 for f1, so we want to make it odd. */
9784 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
9786 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9787 build_int_cst (TREE_TYPE (reg
), 1));
9788 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
9791 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
9792 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
9793 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
9794 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
9795 gimplify_and_add (t
, pre_p
);
9799 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
9801 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9802 build_int_cst (TREE_TYPE (reg
), n_reg
));
9803 u
= fold_convert (sizetype
, u
);
9804 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
9805 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
9807 /* _Decimal32 varargs are located in the second word of the 64-bit
9808 FP register for 32-bit binaries. */
9809 if (!TARGET_POWERPC64
9810 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9811 && TYPE_MODE (type
) == SDmode
)
9812 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9814 gimplify_assign (addr
, t
, pre_p
);
9816 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
9818 stmt
= gimple_build_label (lab_false
);
9819 gimple_seq_add_stmt (pre_p
, stmt
);
9821 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
9823 /* Ensure that we don't find any more args in regs.
9824 Alignment has taken care of for special cases. */
9825 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
9829 /* ... otherwise out of the overflow area. */
9831 /* Care for on-stack alignment if needed. */
9835 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
9836 t
= fold_convert (sizetype
, t
);
9837 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
9839 t
= fold_convert (TREE_TYPE (ovf
), t
);
9841 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9843 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
9845 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9846 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
9850 stmt
= gimple_build_label (lab_over
);
9851 gimple_seq_add_stmt (pre_p
, stmt
);
9854 if (STRICT_ALIGNMENT
9855 && (TYPE_ALIGN (type
)
9856 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
9858 /* The value (of type complex double, for example) may not be
9859 aligned in memory in the saved registers, so copy via a
9860 temporary. (This is the same code as used for SPARC.) */
9861 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
9862 tree dest_addr
= build_fold_addr_expr (tmp
);
9864 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
9865 3, dest_addr
, addr
, size_int (rsize
* 4));
9867 gimplify_and_add (copy
, pre_p
);
9871 addr
= fold_convert (ptrtype
, addr
);
9872 return build_va_arg_indirect_ref (addr
);
9878 def_builtin (int mask
, const char *name
, tree type
, int code
)
9880 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
9883 if (rs6000_builtin_decls
[code
])
9884 fatal_error ("internal error: builtin function to %s already processed",
9887 rs6000_builtin_decls
[code
] = t
=
9888 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
9891 gcc_assert (code
>= 0 && code
< (int)RS6000_BUILTIN_COUNT
);
9892 switch (builtin_classify
[code
])
9897 /* assume builtin can do anything. */
9898 case RS6000_BTC_MISC
:
9901 /* const function, function only depends on the inputs. */
9902 case RS6000_BTC_CONST
:
9903 TREE_READONLY (t
) = 1;
9904 TREE_NOTHROW (t
) = 1;
9907 /* pure function, function can read global memory. */
9908 case RS6000_BTC_PURE
:
9909 DECL_PURE_P (t
) = 1;
9910 TREE_NOTHROW (t
) = 1;
9913 /* Function is a math function. If rounding mode is on, then treat
9914 the function as not reading global memory, but it can have
9915 arbitrary side effects. If it is off, then assume the function is
9916 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9917 attribute in builtin-attribute.def that is used for the math
9919 case RS6000_BTC_FP_PURE
:
9920 TREE_NOTHROW (t
) = 1;
9921 if (flag_rounding_math
)
9923 DECL_PURE_P (t
) = 1;
9924 DECL_IS_NOVOPS (t
) = 1;
9927 TREE_READONLY (t
) = 1;
9933 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9935 static const struct builtin_description bdesc_3arg
[] =
9937 { MASK_ALTIVEC
, CODE_FOR_fmav4sf4
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
9938 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
9939 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
9940 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
9941 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
9942 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
9943 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
9944 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
9945 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
9946 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
9947 { MASK_ALTIVEC
, CODE_FOR_nfmsv4sf4
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
9948 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2df
, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF
},
9949 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di
, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI
},
9950 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
9951 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
9952 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
9953 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
9954 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS
},
9955 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS
},
9956 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS
},
9957 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS
},
9958 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
9959 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
9960 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
9961 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
9962 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2df
, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF
},
9963 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di
, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI
},
9964 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si_uns
, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS
},
9965 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS
},
9966 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS
},
9967 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di_uns
, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS
},
9968 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
9969 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
9970 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
9971 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
9973 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
9974 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
9975 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
9976 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
9977 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
9978 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
9979 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
9980 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
9981 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
9982 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
9983 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
9984 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
9985 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
9986 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
9987 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
9989 { MASK_VSX
, CODE_FOR_fmav2df4
, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP
},
9990 { MASK_VSX
, CODE_FOR_fmsv2df4
, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP
},
9991 { MASK_VSX
, CODE_FOR_nfmav2df4
, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP
},
9992 { MASK_VSX
, CODE_FOR_nfmsv2df4
, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP
},
9994 { MASK_VSX
, CODE_FOR_fmav4sf4
, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP
},
9995 { MASK_VSX
, CODE_FOR_fmsv4sf4
, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP
},
9996 { MASK_VSX
, CODE_FOR_nfmav4sf4
, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP
},
9997 { MASK_VSX
, CODE_FOR_nfmsv4sf4
, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP
},
9999 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB
},
10000 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD
},
10002 { MASK_VSX
, CODE_FOR_vector_select_v2di
, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI
},
10003 { MASK_VSX
, CODE_FOR_vector_select_v2df
, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF
},
10004 { MASK_VSX
, CODE_FOR_vector_select_v4sf
, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF
},
10005 { MASK_VSX
, CODE_FOR_vector_select_v4si
, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI
},
10006 { MASK_VSX
, CODE_FOR_vector_select_v8hi
, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI
},
10007 { MASK_VSX
, CODE_FOR_vector_select_v16qi
, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI
},
10008 { MASK_VSX
, CODE_FOR_vector_select_v2di_uns
, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS
},
10009 { MASK_VSX
, CODE_FOR_vector_select_v4si_uns
, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS
},
10010 { MASK_VSX
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS
},
10011 { MASK_VSX
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS
},
10013 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di
, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI
},
10014 { MASK_VSX
, CODE_FOR_altivec_vperm_v2df
, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF
},
10015 { MASK_VSX
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF
},
10016 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si
, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI
},
10017 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI
},
10018 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI
},
10019 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS
},
10020 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS
},
10021 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS
},
10022 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS
},
10024 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2df
, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF
},
10025 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2di
, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI
},
10026 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4sf
, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF
},
10027 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4si
, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI
},
10028 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v8hi
, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI
},
10029 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v16qi
, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI
},
10030 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI
},
10031 { MASK_VSX
, CODE_FOR_vsx_set_v2df
, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF
},
10032 { MASK_VSX
, CODE_FOR_vsx_set_v2di
, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI
},
10034 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2di
, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI
},
10035 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2df
, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF
},
10036 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4sf
, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF
},
10037 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4si
, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI
},
10038 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v8hi
, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI
},
10039 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v16qi
, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI
},
10040 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI
},
10042 { 0, CODE_FOR_fmsv2sf4
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
10043 { 0, CODE_FOR_fmav2sf4
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
10044 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
10045 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
10046 { 0, CODE_FOR_nfmsv2sf4
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
10047 { 0, CODE_FOR_nfmav2sf4
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
10048 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
10049 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
10050 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
10053 /* DST operations: void foo (void *, const int, const char). */
10055 static const struct builtin_description bdesc_dst
[] =
10057 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
10058 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
10059 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
10060 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
10062 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
10063 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
10064 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
10065 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
10068 /* Simple binary operations: VECc = foo (VECa, VECb). */
10070 static struct builtin_description bdesc_2arg
[] =
10072 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
10073 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
10074 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
10075 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
10076 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
10077 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
10078 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
10079 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
10080 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
10081 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
10082 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
10083 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
10084 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
10085 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
10086 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
10087 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
10088 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
10089 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
10090 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
10091 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
10092 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
10093 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
10094 { MASK_ALTIVEC
, CODE_FOR_vector_eqv16qi
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
10095 { MASK_ALTIVEC
, CODE_FOR_vector_eqv8hi
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
10096 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4si
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
10097 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4sf
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
10098 { MASK_ALTIVEC
, CODE_FOR_vector_gev4sf
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
10099 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv16qi
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
10100 { MASK_ALTIVEC
, CODE_FOR_vector_gtv16qi
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
10101 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv8hi
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
10102 { MASK_ALTIVEC
, CODE_FOR_vector_gtv8hi
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
10103 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv4si
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
10104 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4si
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
10105 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4sf
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
10106 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
10107 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
10108 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
10109 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
10110 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
10111 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
10112 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
10113 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
10114 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
10115 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
10116 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
10117 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
10118 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
10119 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
10120 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
10121 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
10122 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
10123 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
10124 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
10125 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
10126 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
10127 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
10128 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
10129 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS
},
10130 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
10131 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
10132 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS
},
10133 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
10134 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
10135 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS
},
10136 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
10137 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
10138 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS
},
10139 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
10140 { MASK_ALTIVEC
, CODE_FOR_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
10141 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
10142 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
10143 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
10144 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
10145 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
10146 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
10147 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
10148 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
10149 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
10150 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
10151 { MASK_ALTIVEC
, CODE_FOR_recipv4sf3
, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP
},
10152 { MASK_ALTIVEC
, CODE_FOR_vrotlv16qi3
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
10153 { MASK_ALTIVEC
, CODE_FOR_vrotlv8hi3
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
10154 { MASK_ALTIVEC
, CODE_FOR_vrotlv4si3
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
10155 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
10156 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
10157 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
10158 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
10159 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
10160 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
10161 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
10162 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
10163 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
10164 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
10165 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
10166 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
10167 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
10168 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
10169 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
10170 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
10171 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
10172 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
10173 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
10174 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
10175 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
10176 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
10177 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
10178 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
10179 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
10180 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
10181 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
10182 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
10183 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
10184 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
10185 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
10186 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
10187 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
10188 { MASK_ALTIVEC
, CODE_FOR_vector_copysignv4sf3
, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF
},
10190 { MASK_VSX
, CODE_FOR_addv2df3
, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP
},
10191 { MASK_VSX
, CODE_FOR_subv2df3
, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP
},
10192 { MASK_VSX
, CODE_FOR_mulv2df3
, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP
},
10193 { MASK_VSX
, CODE_FOR_divv2df3
, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP
},
10194 { MASK_VSX
, CODE_FOR_recipv2df3
, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF
},
10195 { MASK_VSX
, CODE_FOR_sminv2df3
, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP
},
10196 { MASK_VSX
, CODE_FOR_smaxv2df3
, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP
},
10197 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fe
, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE
},
10198 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fg
, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG
},
10199 { MASK_VSX
, CODE_FOR_vector_eqv2df
, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP
},
10200 { MASK_VSX
, CODE_FOR_vector_gtv2df
, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP
},
10201 { MASK_VSX
, CODE_FOR_vector_gev2df
, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP
},
10203 { MASK_VSX
, CODE_FOR_addv4sf3
, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP
},
10204 { MASK_VSX
, CODE_FOR_subv4sf3
, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP
},
10205 { MASK_VSX
, CODE_FOR_mulv4sf3
, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP
},
10206 { MASK_VSX
, CODE_FOR_divv4sf3
, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP
},
10207 { MASK_VSX
, CODE_FOR_recipv4sf3
, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF
},
10208 { MASK_VSX
, CODE_FOR_sminv4sf3
, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP
},
10209 { MASK_VSX
, CODE_FOR_smaxv4sf3
, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP
},
10210 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fe
, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE
},
10211 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fg
, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG
},
10212 { MASK_VSX
, CODE_FOR_vector_eqv4sf
, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP
},
10213 { MASK_VSX
, CODE_FOR_vector_gtv4sf
, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP
},
10214 { MASK_VSX
, CODE_FOR_vector_gev4sf
, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP
},
10216 { MASK_VSX
, CODE_FOR_smindf3
, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP
},
10217 { MASK_VSX
, CODE_FOR_smaxdf3
, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP
},
10218 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fe
, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE
},
10219 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fg
, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG
},
10220 { MASK_VSX
, CODE_FOR_vector_copysignv2df3
, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP
},
10221 { MASK_VSX
, CODE_FOR_vector_copysignv4sf3
, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP
},
10223 { MASK_VSX
, CODE_FOR_vsx_concat_v2df
, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF
},
10224 { MASK_VSX
, CODE_FOR_vsx_concat_v2di
, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI
},
10225 { MASK_VSX
, CODE_FOR_vsx_splat_v2df
, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF
},
10226 { MASK_VSX
, CODE_FOR_vsx_splat_v2di
, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI
},
10227 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4sf
, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF
},
10228 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4si
, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI
},
10229 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4sf
, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF
},
10230 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4si
, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI
},
10231 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2df
, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF
},
10232 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2di
, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI
},
10233 { MASK_VSX
, CODE_FOR_vec_interleave_highv2df
, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF
},
10234 { MASK_VSX
, CODE_FOR_vec_interleave_highv2di
, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI
},
10236 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
10237 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
10238 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
10239 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
10240 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
10241 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
10242 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
10243 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
10244 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
10245 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
10246 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
10247 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
10248 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
10249 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
10250 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
10251 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
10252 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
10253 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
10254 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
10255 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
10256 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
10257 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
10258 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
10259 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
10260 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
10261 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
10262 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
10263 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
10264 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
10265 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
10266 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
10267 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
10268 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
10269 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
10270 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
10271 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
10272 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
10273 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
10274 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
10275 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN
},
10276 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
10277 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
10278 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
10279 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
10280 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
10281 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
10282 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
10283 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
10284 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
10285 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
10286 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
10287 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
10288 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
10289 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
10290 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
10291 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
10292 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
10293 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
10294 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
10295 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
10296 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
10297 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
10298 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
10299 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
10300 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
10301 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
10302 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
10303 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
10304 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
10305 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
10306 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
10307 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
10308 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
10309 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
10310 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
10311 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
10312 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
10313 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
10314 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
10315 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
10316 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
10317 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
10318 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
10319 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
10320 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
10321 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
10322 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
10323 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
10324 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP
},
10325 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
10326 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
10327 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
10328 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
10329 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
10330 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
10331 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
10332 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
10333 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
10334 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
10335 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
10336 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
10337 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
10338 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
10339 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
10340 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
10341 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
10342 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
10343 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
10344 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
10345 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
10346 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
10347 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
10348 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
10349 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
10350 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
10351 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
10352 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
10353 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
10354 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
10355 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
10356 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
10357 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
10358 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
10359 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
10360 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
10361 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
10362 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
10363 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
10364 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
10366 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL
},
10367 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV
},
10369 { 0, CODE_FOR_paired_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
10370 { 0, CODE_FOR_paired_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
10371 { 0, CODE_FOR_paired_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
10372 { 0, CODE_FOR_paired_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
10373 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
10374 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
10375 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
10376 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
10377 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
10378 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
10380 /* Place holder, leave as first spe builtin. */
10381 { 0, CODE_FOR_addv2si3
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
10382 { 0, CODE_FOR_andv2si3
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
10383 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
10384 { 0, CODE_FOR_divv2si3
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
10385 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
10386 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
10387 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
10388 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
10389 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
10390 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
10391 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
10392 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
10393 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
10394 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
10395 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
10396 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
10397 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
10398 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
10399 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
10400 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
10401 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
10402 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
10403 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
10404 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
10405 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
10406 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
10407 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
10408 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
10409 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
10410 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
10411 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
10412 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
10413 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
10414 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
10415 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
10416 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
10417 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
10418 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
10419 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
10420 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
10421 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
10422 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
10423 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
10424 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
10425 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
10426 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
10427 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
10428 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
10429 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
10430 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
10431 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
10432 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
10433 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
10434 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
10435 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
10436 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
10437 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
10438 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
10439 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
10440 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
10441 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
10442 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
10443 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
10444 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
10445 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
10446 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
10447 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
10448 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
10449 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
10450 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
10451 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
10452 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
10453 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
10454 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
10455 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
10456 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
10457 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
10458 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
10459 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
10460 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
10461 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
10462 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
10463 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
10464 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
10465 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
10466 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
10467 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
10468 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
10469 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
10470 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
10471 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
10472 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
10473 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
10474 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
10475 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
10476 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
10477 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
10478 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
10479 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
10480 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
10481 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
10482 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
10483 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
10484 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
10485 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
10486 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
10487 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
10488 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
10489 { 0, CODE_FOR_subv2si3
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
10491 /* SPE binary operations expecting a 5-bit unsigned literal. */
10492 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
10494 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
10495 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
10496 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
10497 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
10498 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
10499 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
10500 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
10501 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
10502 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
10503 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
10504 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
10505 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
10506 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
10507 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
10508 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
10509 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
10510 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
10511 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
10512 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
10513 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
10514 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
10515 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
10516 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
10517 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
10518 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
10519 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
10521 /* Place-holder. Leave as last binary SPE builtin. */
10522 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
10525 /* AltiVec predicates. */
10527 struct builtin_description_predicates
10529 const unsigned int mask
;
10530 const enum insn_code icode
;
10531 const char *const name
;
10532 const enum rs6000_builtins code
;
10535 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
10537 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp_p
, "__builtin_altivec_vcmpbfp_p",
10538 ALTIVEC_BUILTIN_VCMPBFP_P
},
10539 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
,
10540 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
10541 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
,
10542 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
10543 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
,
10544 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
10545 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v4si_p
, "__builtin_altivec_vcmpequw_p",
10546 ALTIVEC_BUILTIN_VCMPEQUW_P
},
10547 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v4si_p
, "__builtin_altivec_vcmpgtsw_p",
10548 ALTIVEC_BUILTIN_VCMPGTSW_P
},
10549 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v4si_p
, "__builtin_altivec_vcmpgtuw_p",
10550 ALTIVEC_BUILTIN_VCMPGTUW_P
},
10551 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v8hi_p
, "__builtin_altivec_vcmpequh_p",
10552 ALTIVEC_BUILTIN_VCMPEQUH_P
},
10553 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v8hi_p
, "__builtin_altivec_vcmpgtsh_p",
10554 ALTIVEC_BUILTIN_VCMPGTSH_P
},
10555 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v8hi_p
, "__builtin_altivec_vcmpgtuh_p",
10556 ALTIVEC_BUILTIN_VCMPGTUH_P
},
10557 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v16qi_p
, "__builtin_altivec_vcmpequb_p",
10558 ALTIVEC_BUILTIN_VCMPEQUB_P
},
10559 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v16qi_p
, "__builtin_altivec_vcmpgtsb_p",
10560 ALTIVEC_BUILTIN_VCMPGTSB_P
},
10561 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v16qi_p
, "__builtin_altivec_vcmpgtub_p",
10562 ALTIVEC_BUILTIN_VCMPGTUB_P
},
10564 { MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
, "__builtin_vsx_xvcmpeqsp_p",
10565 VSX_BUILTIN_XVCMPEQSP_P
},
10566 { MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
, "__builtin_vsx_xvcmpgesp_p",
10567 VSX_BUILTIN_XVCMPGESP_P
},
10568 { MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
, "__builtin_vsx_xvcmpgtsp_p",
10569 VSX_BUILTIN_XVCMPGTSP_P
},
10570 { MASK_VSX
, CODE_FOR_vector_eq_v2df_p
, "__builtin_vsx_xvcmpeqdp_p",
10571 VSX_BUILTIN_XVCMPEQDP_P
},
10572 { MASK_VSX
, CODE_FOR_vector_ge_v2df_p
, "__builtin_vsx_xvcmpgedp_p",
10573 VSX_BUILTIN_XVCMPGEDP_P
},
10574 { MASK_VSX
, CODE_FOR_vector_gt_v2df_p
, "__builtin_vsx_xvcmpgtdp_p",
10575 VSX_BUILTIN_XVCMPGTDP_P
},
10577 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpeq_p",
10578 ALTIVEC_BUILTIN_VCMPEQ_P
},
10579 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpgt_p",
10580 ALTIVEC_BUILTIN_VCMPGT_P
},
10581 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpge_p",
10582 ALTIVEC_BUILTIN_VCMPGE_P
}
10585 /* SPE predicates. */
10586 static struct builtin_description bdesc_spe_predicates
[] =
10588 /* Place-holder. Leave as first. */
10589 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
10590 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
10591 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
10592 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
10593 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
10594 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
10595 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
10596 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
10597 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
10598 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
10599 /* Place-holder. Leave as last. */
10600 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
10603 /* SPE evsel predicates. */
10604 static struct builtin_description bdesc_spe_evsel
[] =
10606 /* Place-holder. Leave as first. */
10607 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
10608 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
10609 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
10610 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
10611 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
10612 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
10613 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
10614 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
10615 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
10616 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
10617 /* Place-holder. Leave as last. */
10618 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
10621 /* PAIRED predicates. */
10622 static const struct builtin_description bdesc_paired_preds
[] =
10624 /* Place-holder. Leave as first. */
10625 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
10626 /* Place-holder. Leave as last. */
10627 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
10630 /* ABS* operations. */
10632 static const struct builtin_description bdesc_abs
[] =
10634 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
10635 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
10636 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
10637 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
10638 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
10639 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
10640 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
},
10641 { MASK_VSX
, CODE_FOR_absv2df2
, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP
},
10642 { MASK_VSX
, CODE_FOR_vsx_nabsv2df2
, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP
},
10643 { MASK_VSX
, CODE_FOR_absv4sf2
, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP
},
10644 { MASK_VSX
, CODE_FOR_vsx_nabsv4sf2
, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP
},
10647 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10650 static struct builtin_description bdesc_1arg
[] =
10652 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
10653 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
10654 { MASK_ALTIVEC
, CODE_FOR_rev4sf2
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
10655 { MASK_ALTIVEC
, CODE_FOR_vector_floorv4sf2
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
10656 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
10657 { MASK_ALTIVEC
, CODE_FOR_vector_ceilv4sf2
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
10658 { MASK_ALTIVEC
, CODE_FOR_vector_btruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
10659 { MASK_ALTIVEC
, CODE_FOR_rsqrtv4sf2
, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP
},
10660 { MASK_ALTIVEC
, CODE_FOR_rsqrtev4sf2
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
10661 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
10662 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
10663 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
10664 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
10665 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
10666 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
10667 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
10668 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
10669 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
10671 { MASK_VSX
, CODE_FOR_negv2df2
, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP
},
10672 { MASK_VSX
, CODE_FOR_sqrtv2df2
, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP
},
10673 { MASK_VSX
, CODE_FOR_rsqrtv2df2
, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF
},
10674 { MASK_VSX
, CODE_FOR_rsqrtev2df2
, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP
},
10675 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fe
, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE
},
10676 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fg
, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG
},
10677 { MASK_VSX
, CODE_FOR_vsx_frev2df2
, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP
},
10679 { MASK_VSX
, CODE_FOR_negv4sf2
, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP
},
10680 { MASK_VSX
, CODE_FOR_sqrtv4sf2
, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP
},
10681 { MASK_VSX
, CODE_FOR_rsqrtv4sf2
, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF
},
10682 { MASK_VSX
, CODE_FOR_rsqrtev4sf2
, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP
},
10683 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fe
, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE
},
10684 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fg
, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG
},
10685 { MASK_VSX
, CODE_FOR_vsx_frev4sf2
, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP
},
10687 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP
},
10688 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP
},
10689 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsp
, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP
},
10690 { MASK_VSX
, CODE_FOR_vsx_xvcvspdp
, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP
},
10691 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fe
, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE
},
10692 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fg
, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG
},
10694 { MASK_VSX
, CODE_FOR_vsx_fix_truncv2dfv2di2
, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS
},
10695 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS
},
10696 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS
},
10697 { MASK_VSX
, CODE_FOR_vsx_floatv2div2df2
, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP
},
10698 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP
},
10699 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS
},
10701 { MASK_VSX
, CODE_FOR_vsx_fix_truncv4sfv4si2
, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS
},
10702 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv4sfv4si2
, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS
},
10703 { MASK_VSX
, CODE_FOR_vsx_floatv4siv4sf2
, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP
},
10704 { MASK_VSX
, CODE_FOR_vsx_floatunsv4siv4sf2
, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP
},
10706 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsxws
, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS
},
10707 { MASK_VSX
, CODE_FOR_vsx_xvcvdpuxws
, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS
},
10708 { MASK_VSX
, CODE_FOR_vsx_xvcvsxwdp
, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP
},
10709 { MASK_VSX
, CODE_FOR_vsx_xvcvuxwdp
, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP
},
10710 { MASK_VSX
, CODE_FOR_vsx_xvrdpi
, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI
},
10711 { MASK_VSX
, CODE_FOR_vsx_xvrdpic
, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC
},
10712 { MASK_VSX
, CODE_FOR_vsx_floorv2df2
, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM
},
10713 { MASK_VSX
, CODE_FOR_vsx_ceilv2df2
, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP
},
10714 { MASK_VSX
, CODE_FOR_vsx_btruncv2df2
, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ
},
10716 { MASK_VSX
, CODE_FOR_vsx_xvcvspsxds
, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS
},
10717 { MASK_VSX
, CODE_FOR_vsx_xvcvspuxds
, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS
},
10718 { MASK_VSX
, CODE_FOR_vsx_xvcvsxdsp
, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP
},
10719 { MASK_VSX
, CODE_FOR_vsx_xvcvuxdsp
, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP
},
10720 { MASK_VSX
, CODE_FOR_vsx_xvrspi
, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI
},
10721 { MASK_VSX
, CODE_FOR_vsx_xvrspic
, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC
},
10722 { MASK_VSX
, CODE_FOR_vsx_floorv4sf2
, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM
},
10723 { MASK_VSX
, CODE_FOR_vsx_ceilv4sf2
, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP
},
10724 { MASK_VSX
, CODE_FOR_vsx_btruncv4sf2
, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ
},
10726 { MASK_VSX
, CODE_FOR_vsx_xsrdpi
, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI
},
10727 { MASK_VSX
, CODE_FOR_vsx_xsrdpic
, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC
},
10728 { MASK_VSX
, CODE_FOR_vsx_floordf2
, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM
},
10729 { MASK_VSX
, CODE_FOR_vsx_ceildf2
, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP
},
10730 { MASK_VSX
, CODE_FOR_vsx_btruncdf2
, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ
},
10732 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
10733 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
10734 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
10735 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
10736 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
10737 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
10738 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
10739 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
10740 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
10741 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT
},
10742 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
10743 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
10744 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
10745 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
10746 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
10747 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
10748 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
10749 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
10750 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
10751 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
10753 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT
},
10754 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT
},
10755 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT
},
10757 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_floatv4siv4sf2
, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF
},
10758 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_unsigned_floatv4siv4sf2
, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
},
10759 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fix_truncv4sfv4si2
, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI
},
10760 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fixuns_truncv4sfv4si2
, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
},
10762 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10763 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10764 { 0, CODE_FOR_absv2si2
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
10765 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
10766 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
10767 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
10768 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
10769 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
10770 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
10771 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
10772 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
10773 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
10774 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
10775 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
10776 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
10777 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
10778 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
10779 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
10780 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
10781 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
10782 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
10783 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
10784 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
10785 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
10786 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
10787 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
10788 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
10789 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
10790 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
10791 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
10793 /* Place-holder. Leave as last unary SPE builtin. */
10794 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
10796 { 0, CODE_FOR_paired_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
10797 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
10798 { 0, CODE_FOR_paired_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
10799 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
10800 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
10804 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10807 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10808 rtx op0
= expand_normal (arg0
);
10809 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10810 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10812 if (icode
== CODE_FOR_nothing
)
10813 /* Builtin not supported on this processor. */
10816 /* If we got invalid arguments bail out before generating bad rtl. */
10817 if (arg0
== error_mark_node
)
10820 if (icode
== CODE_FOR_altivec_vspltisb
10821 || icode
== CODE_FOR_altivec_vspltish
10822 || icode
== CODE_FOR_altivec_vspltisw
10823 || icode
== CODE_FOR_spe_evsplatfi
10824 || icode
== CODE_FOR_spe_evsplati
)
10826 /* Only allow 5-bit *signed* literals. */
10827 if (GET_CODE (op0
) != CONST_INT
10828 || INTVAL (op0
) > 15
10829 || INTVAL (op0
) < -16)
10831 error ("argument 1 must be a 5-bit signed literal");
10837 || GET_MODE (target
) != tmode
10838 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10839 target
= gen_reg_rtx (tmode
);
10841 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10842 op0
= copy_to_mode_reg (mode0
, op0
);
10844 pat
= GEN_FCN (icode
) (target
, op0
);
10853 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
10855 rtx pat
, scratch1
, scratch2
;
10856 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10857 rtx op0
= expand_normal (arg0
);
10858 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10859 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10861 /* If we have invalid arguments, bail out before generating bad rtl. */
10862 if (arg0
== error_mark_node
)
10866 || GET_MODE (target
) != tmode
10867 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10868 target
= gen_reg_rtx (tmode
);
10870 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10871 op0
= copy_to_mode_reg (mode0
, op0
);
10873 scratch1
= gen_reg_rtx (mode0
);
10874 scratch2
= gen_reg_rtx (mode0
);
10876 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
10885 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10888 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10889 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10890 rtx op0
= expand_normal (arg0
);
10891 rtx op1
= expand_normal (arg1
);
10892 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10893 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10894 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10896 if (icode
== CODE_FOR_nothing
)
10897 /* Builtin not supported on this processor. */
10900 /* If we got invalid arguments bail out before generating bad rtl. */
10901 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10904 if (icode
== CODE_FOR_altivec_vcfux
10905 || icode
== CODE_FOR_altivec_vcfsx
10906 || icode
== CODE_FOR_altivec_vctsxs
10907 || icode
== CODE_FOR_altivec_vctuxs
10908 || icode
== CODE_FOR_altivec_vspltb
10909 || icode
== CODE_FOR_altivec_vsplth
10910 || icode
== CODE_FOR_altivec_vspltw
10911 || icode
== CODE_FOR_spe_evaddiw
10912 || icode
== CODE_FOR_spe_evldd
10913 || icode
== CODE_FOR_spe_evldh
10914 || icode
== CODE_FOR_spe_evldw
10915 || icode
== CODE_FOR_spe_evlhhesplat
10916 || icode
== CODE_FOR_spe_evlhhossplat
10917 || icode
== CODE_FOR_spe_evlhhousplat
10918 || icode
== CODE_FOR_spe_evlwhe
10919 || icode
== CODE_FOR_spe_evlwhos
10920 || icode
== CODE_FOR_spe_evlwhou
10921 || icode
== CODE_FOR_spe_evlwhsplat
10922 || icode
== CODE_FOR_spe_evlwwsplat
10923 || icode
== CODE_FOR_spe_evrlwi
10924 || icode
== CODE_FOR_spe_evslwi
10925 || icode
== CODE_FOR_spe_evsrwis
10926 || icode
== CODE_FOR_spe_evsubifw
10927 || icode
== CODE_FOR_spe_evsrwiu
)
10929 /* Only allow 5-bit unsigned literals. */
10931 if (TREE_CODE (arg1
) != INTEGER_CST
10932 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
10934 error ("argument 2 must be a 5-bit unsigned literal");
10940 || GET_MODE (target
) != tmode
10941 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10942 target
= gen_reg_rtx (tmode
);
10944 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10945 op0
= copy_to_mode_reg (mode0
, op0
);
10946 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10947 op1
= copy_to_mode_reg (mode1
, op1
);
10949 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
10958 altivec_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
10961 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
10962 tree arg0
= CALL_EXPR_ARG (exp
, 1);
10963 tree arg1
= CALL_EXPR_ARG (exp
, 2);
10964 rtx op0
= expand_normal (arg0
);
10965 rtx op1
= expand_normal (arg1
);
10966 enum machine_mode tmode
= SImode
;
10967 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10968 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10971 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
10973 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10977 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
10979 gcc_assert (mode0
== mode1
);
10981 /* If we have invalid arguments, bail out before generating bad rtl. */
10982 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10986 || GET_MODE (target
) != tmode
10987 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10988 target
= gen_reg_rtx (tmode
);
10990 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10991 op0
= copy_to_mode_reg (mode0
, op0
);
10992 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10993 op1
= copy_to_mode_reg (mode1
, op1
);
10995 scratch
= gen_reg_rtx (mode0
);
10997 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11002 /* The vec_any* and vec_all* predicates use the same opcodes for two
11003 different operations, but the bits in CR6 will be different
11004 depending on what information we want. So we have to play tricks
11005 with CR6 to get the right bits out.
11007 If you think this is disgusting, look at the specs for the
11008 AltiVec predicates. */
11010 switch (cr6_form_int
)
11013 emit_insn (gen_cr6_test_for_zero (target
));
11016 emit_insn (gen_cr6_test_for_zero_reverse (target
));
11019 emit_insn (gen_cr6_test_for_lt (target
));
11022 emit_insn (gen_cr6_test_for_lt_reverse (target
));
11025 error ("argument 1 of __builtin_altivec_predicate is out of range");
11033 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
11036 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11037 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11038 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11039 enum machine_mode mode0
= Pmode
;
11040 enum machine_mode mode1
= Pmode
;
11041 rtx op0
= expand_normal (arg0
);
11042 rtx op1
= expand_normal (arg1
);
11044 if (icode
== CODE_FOR_nothing
)
11045 /* Builtin not supported on this processor. */
11048 /* If we got invalid arguments bail out before generating bad rtl. */
11049 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11053 || GET_MODE (target
) != tmode
11054 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11055 target
= gen_reg_rtx (tmode
);
11057 op1
= copy_to_mode_reg (mode1
, op1
);
11059 if (op0
== const0_rtx
)
11061 addr
= gen_rtx_MEM (tmode
, op1
);
11065 op0
= copy_to_mode_reg (mode0
, op0
);
11066 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
11069 pat
= GEN_FCN (icode
) (target
, addr
);
11079 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
11082 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11083 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11084 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11085 enum machine_mode mode0
= Pmode
;
11086 enum machine_mode mode1
= Pmode
;
11087 rtx op0
= expand_normal (arg0
);
11088 rtx op1
= expand_normal (arg1
);
11090 if (icode
== CODE_FOR_nothing
)
11091 /* Builtin not supported on this processor. */
11094 /* If we got invalid arguments bail out before generating bad rtl. */
11095 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11099 || GET_MODE (target
) != tmode
11100 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11101 target
= gen_reg_rtx (tmode
);
11103 op1
= copy_to_mode_reg (mode1
, op1
);
11105 if (op0
== const0_rtx
)
11107 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
11111 op0
= copy_to_mode_reg (mode0
, op0
);
11112 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
11115 pat
= GEN_FCN (icode
) (target
, addr
);
11125 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
11127 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11128 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11129 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11130 rtx op0
= expand_normal (arg0
);
11131 rtx op1
= expand_normal (arg1
);
11132 rtx op2
= expand_normal (arg2
);
11134 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
11135 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
11136 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
11138 /* Invalid arguments. Bail before doing anything stoopid! */
11139 if (arg0
== error_mark_node
11140 || arg1
== error_mark_node
11141 || arg2
== error_mark_node
)
11144 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
11145 op0
= copy_to_mode_reg (mode2
, op0
);
11146 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
11147 op1
= copy_to_mode_reg (mode0
, op1
);
11148 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
11149 op2
= copy_to_mode_reg (mode1
, op2
);
11151 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
11158 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
11160 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11161 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11162 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11163 rtx op0
= expand_normal (arg0
);
11164 rtx op1
= expand_normal (arg1
);
11165 rtx op2
= expand_normal (arg2
);
11167 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11168 enum machine_mode mode1
= Pmode
;
11169 enum machine_mode mode2
= Pmode
;
11171 /* Invalid arguments. Bail before doing anything stoopid! */
11172 if (arg0
== error_mark_node
11173 || arg1
== error_mark_node
11174 || arg2
== error_mark_node
)
11177 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
11178 op0
= copy_to_mode_reg (tmode
, op0
);
11180 op2
= copy_to_mode_reg (mode2
, op2
);
11182 if (op1
== const0_rtx
)
11184 addr
= gen_rtx_MEM (tmode
, op2
);
11188 op1
= copy_to_mode_reg (mode1
, op1
);
11189 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
11192 pat
= GEN_FCN (icode
) (addr
, op0
);
11199 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
11201 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11202 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11203 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11204 rtx op0
= expand_normal (arg0
);
11205 rtx op1
= expand_normal (arg1
);
11206 rtx op2
= expand_normal (arg2
);
11208 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11209 enum machine_mode smode
= insn_data
[icode
].operand
[1].mode
;
11210 enum machine_mode mode1
= Pmode
;
11211 enum machine_mode mode2
= Pmode
;
11213 /* Invalid arguments. Bail before doing anything stoopid! */
11214 if (arg0
== error_mark_node
11215 || arg1
== error_mark_node
11216 || arg2
== error_mark_node
)
11219 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, smode
))
11220 op0
= copy_to_mode_reg (smode
, op0
);
11222 op2
= copy_to_mode_reg (mode2
, op2
);
11224 if (op1
== const0_rtx
)
11226 addr
= gen_rtx_MEM (tmode
, op2
);
11230 op1
= copy_to_mode_reg (mode1
, op1
);
11231 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
11234 pat
= GEN_FCN (icode
) (addr
, op0
);
11241 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
11244 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11245 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11246 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11247 rtx op0
= expand_normal (arg0
);
11248 rtx op1
= expand_normal (arg1
);
11249 rtx op2
= expand_normal (arg2
);
11250 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11251 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11252 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11253 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
11255 if (icode
== CODE_FOR_nothing
)
11256 /* Builtin not supported on this processor. */
11259 /* If we got invalid arguments bail out before generating bad rtl. */
11260 if (arg0
== error_mark_node
11261 || arg1
== error_mark_node
11262 || arg2
== error_mark_node
)
11265 /* Check and prepare argument depending on the instruction code.
11267 Note that a switch statement instead of the sequence of tests
11268 would be incorrect as many of the CODE_FOR values could be
11269 CODE_FOR_nothing and that would yield multiple alternatives
11270 with identical values. We'd never reach here at runtime in
11272 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
11273 || icode
== CODE_FOR_altivec_vsldoi_v4si
11274 || icode
== CODE_FOR_altivec_vsldoi_v8hi
11275 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
11277 /* Only allow 4-bit unsigned literals. */
11279 if (TREE_CODE (arg2
) != INTEGER_CST
11280 || TREE_INT_CST_LOW (arg2
) & ~0xf)
11282 error ("argument 3 must be a 4-bit unsigned literal");
11286 else if (icode
== CODE_FOR_vsx_xxpermdi_v2df
11287 || icode
== CODE_FOR_vsx_xxpermdi_v2di
11288 || icode
== CODE_FOR_vsx_xxsldwi_v16qi
11289 || icode
== CODE_FOR_vsx_xxsldwi_v8hi
11290 || icode
== CODE_FOR_vsx_xxsldwi_v4si
11291 || icode
== CODE_FOR_vsx_xxsldwi_v4sf
11292 || icode
== CODE_FOR_vsx_xxsldwi_v2di
11293 || icode
== CODE_FOR_vsx_xxsldwi_v2df
)
11295 /* Only allow 2-bit unsigned literals. */
11297 if (TREE_CODE (arg2
) != INTEGER_CST
11298 || TREE_INT_CST_LOW (arg2
) & ~0x3)
11300 error ("argument 3 must be a 2-bit unsigned literal");
11304 else if (icode
== CODE_FOR_vsx_set_v2df
11305 || icode
== CODE_FOR_vsx_set_v2di
)
11307 /* Only allow 1-bit unsigned literals. */
11309 if (TREE_CODE (arg2
) != INTEGER_CST
11310 || TREE_INT_CST_LOW (arg2
) & ~0x1)
11312 error ("argument 3 must be a 1-bit unsigned literal");
11318 || GET_MODE (target
) != tmode
11319 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11320 target
= gen_reg_rtx (tmode
);
11322 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11323 op0
= copy_to_mode_reg (mode0
, op0
);
11324 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11325 op1
= copy_to_mode_reg (mode1
, op1
);
11326 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
11327 op2
= copy_to_mode_reg (mode2
, op2
);
11329 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
11330 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
11332 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
11340 /* Expand the lvx builtins. */
11342 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
11344 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11345 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11347 enum machine_mode tmode
, mode0
;
11349 enum insn_code icode
;
11353 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
11354 icode
= CODE_FOR_vector_altivec_load_v16qi
;
11356 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
11357 icode
= CODE_FOR_vector_altivec_load_v8hi
;
11359 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
11360 icode
= CODE_FOR_vector_altivec_load_v4si
;
11362 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
11363 icode
= CODE_FOR_vector_altivec_load_v4sf
;
11365 case ALTIVEC_BUILTIN_LD_INTERNAL_2df
:
11366 icode
= CODE_FOR_vector_altivec_load_v2df
;
11368 case ALTIVEC_BUILTIN_LD_INTERNAL_2di
:
11369 icode
= CODE_FOR_vector_altivec_load_v2di
;
11372 *expandedp
= false;
11378 arg0
= CALL_EXPR_ARG (exp
, 0);
11379 op0
= expand_normal (arg0
);
11380 tmode
= insn_data
[icode
].operand
[0].mode
;
11381 mode0
= insn_data
[icode
].operand
[1].mode
;
11384 || GET_MODE (target
) != tmode
11385 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11386 target
= gen_reg_rtx (tmode
);
11388 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11389 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
11391 pat
= GEN_FCN (icode
) (target
, op0
);
11398 /* Expand the stvx builtins. */
11400 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
11403 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11404 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11406 enum machine_mode mode0
, mode1
;
11408 enum insn_code icode
;
11412 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
11413 icode
= CODE_FOR_vector_altivec_store_v16qi
;
11415 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
11416 icode
= CODE_FOR_vector_altivec_store_v8hi
;
11418 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
11419 icode
= CODE_FOR_vector_altivec_store_v4si
;
11421 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
11422 icode
= CODE_FOR_vector_altivec_store_v4sf
;
11424 case ALTIVEC_BUILTIN_ST_INTERNAL_2df
:
11425 icode
= CODE_FOR_vector_altivec_store_v2df
;
11427 case ALTIVEC_BUILTIN_ST_INTERNAL_2di
:
11428 icode
= CODE_FOR_vector_altivec_store_v2di
;
11431 *expandedp
= false;
11435 arg0
= CALL_EXPR_ARG (exp
, 0);
11436 arg1
= CALL_EXPR_ARG (exp
, 1);
11437 op0
= expand_normal (arg0
);
11438 op1
= expand_normal (arg1
);
11439 mode0
= insn_data
[icode
].operand
[0].mode
;
11440 mode1
= insn_data
[icode
].operand
[1].mode
;
11442 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11443 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
11444 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
11445 op1
= copy_to_mode_reg (mode1
, op1
);
11447 pat
= GEN_FCN (icode
) (op0
, op1
);
11455 /* Expand the dst builtins. */
11457 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
11460 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11461 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11462 tree arg0
, arg1
, arg2
;
11463 enum machine_mode mode0
, mode1
;
11464 rtx pat
, op0
, op1
, op2
;
11465 const struct builtin_description
*d
;
11468 *expandedp
= false;
11470 /* Handle DST variants. */
11472 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
11473 if (d
->code
== fcode
)
11475 arg0
= CALL_EXPR_ARG (exp
, 0);
11476 arg1
= CALL_EXPR_ARG (exp
, 1);
11477 arg2
= CALL_EXPR_ARG (exp
, 2);
11478 op0
= expand_normal (arg0
);
11479 op1
= expand_normal (arg1
);
11480 op2
= expand_normal (arg2
);
11481 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
11482 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
11484 /* Invalid arguments, bail out before generating bad rtl. */
11485 if (arg0
== error_mark_node
11486 || arg1
== error_mark_node
11487 || arg2
== error_mark_node
)
11492 if (TREE_CODE (arg2
) != INTEGER_CST
11493 || TREE_INT_CST_LOW (arg2
) & ~0x3)
11495 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
11499 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
11500 op0
= copy_to_mode_reg (Pmode
, op0
);
11501 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
11502 op1
= copy_to_mode_reg (mode1
, op1
);
11504 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
11514 /* Expand vec_init builtin. */
11516 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
11518 enum machine_mode tmode
= TYPE_MODE (type
);
11519 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
11520 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
11521 rtvec v
= rtvec_alloc (n_elt
);
11523 gcc_assert (VECTOR_MODE_P (tmode
));
11524 gcc_assert (n_elt
== call_expr_nargs (exp
));
11526 for (i
= 0; i
< n_elt
; ++i
)
11528 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
11529 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
11532 if (!target
|| !register_operand (target
, tmode
))
11533 target
= gen_reg_rtx (tmode
);
11535 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
11539 /* Return the integer constant in ARG. Constrain it to be in the range
11540 of the subparts of VEC_TYPE; issue an error if not. */
11543 get_element_number (tree vec_type
, tree arg
)
11545 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
11547 if (!host_integerp (arg
, 1)
11548 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
11550 error ("selector must be an integer constant in the range 0..%wi", max
);
11557 /* Expand vec_set builtin. */
11559 altivec_expand_vec_set_builtin (tree exp
)
11561 enum machine_mode tmode
, mode1
;
11562 tree arg0
, arg1
, arg2
;
11566 arg0
= CALL_EXPR_ARG (exp
, 0);
11567 arg1
= CALL_EXPR_ARG (exp
, 1);
11568 arg2
= CALL_EXPR_ARG (exp
, 2);
11570 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
11571 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11572 gcc_assert (VECTOR_MODE_P (tmode
));
11574 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
11575 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
11576 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
11578 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
11579 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
11581 op0
= force_reg (tmode
, op0
);
11582 op1
= force_reg (mode1
, op1
);
11584 rs6000_expand_vector_set (op0
, op1
, elt
);
11589 /* Expand vec_ext builtin. */
11591 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
11593 enum machine_mode tmode
, mode0
;
11598 arg0
= CALL_EXPR_ARG (exp
, 0);
11599 arg1
= CALL_EXPR_ARG (exp
, 1);
11601 op0
= expand_normal (arg0
);
11602 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
11604 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11605 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
11606 gcc_assert (VECTOR_MODE_P (mode0
));
11608 op0
= force_reg (mode0
, op0
);
11610 if (optimize
|| !target
|| !register_operand (target
, tmode
))
11611 target
= gen_reg_rtx (tmode
);
11613 rs6000_expand_vector_extract (target
, op0
, elt
);
11618 /* Expand the builtin in EXP and store the result in TARGET. Store
11619 true in *EXPANDEDP if we found a builtin to expand. */
11621 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11623 const struct builtin_description
*d
;
11624 const struct builtin_description_predicates
*dp
;
11626 enum insn_code icode
;
11627 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11630 enum machine_mode tmode
, mode0
;
11631 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11633 if ((fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11634 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
11635 || (fcode
>= VSX_BUILTIN_OVERLOADED_FIRST
11636 && fcode
<= VSX_BUILTIN_OVERLOADED_LAST
))
11639 error ("unresolved overload for Altivec builtin %qF", fndecl
);
11643 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
11647 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
11651 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
11659 case ALTIVEC_BUILTIN_STVX
:
11660 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si
, exp
);
11661 case ALTIVEC_BUILTIN_STVEBX
:
11662 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
11663 case ALTIVEC_BUILTIN_STVEHX
:
11664 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
11665 case ALTIVEC_BUILTIN_STVEWX
:
11666 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
11667 case ALTIVEC_BUILTIN_STVXL
:
11668 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
11670 case ALTIVEC_BUILTIN_STVLX
:
11671 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
11672 case ALTIVEC_BUILTIN_STVLXL
:
11673 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
11674 case ALTIVEC_BUILTIN_STVRX
:
11675 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
11676 case ALTIVEC_BUILTIN_STVRXL
:
11677 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
11679 case VSX_BUILTIN_STXVD2X_V2DF
:
11680 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df
, exp
);
11681 case VSX_BUILTIN_STXVD2X_V2DI
:
11682 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di
, exp
);
11683 case VSX_BUILTIN_STXVW4X_V4SF
:
11684 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf
, exp
);
11685 case VSX_BUILTIN_STXVW4X_V4SI
:
11686 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si
, exp
);
11687 case VSX_BUILTIN_STXVW4X_V8HI
:
11688 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi
, exp
);
11689 case VSX_BUILTIN_STXVW4X_V16QI
:
11690 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi
, exp
);
11692 case ALTIVEC_BUILTIN_MFVSCR
:
11693 icode
= CODE_FOR_altivec_mfvscr
;
11694 tmode
= insn_data
[icode
].operand
[0].mode
;
11697 || GET_MODE (target
) != tmode
11698 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11699 target
= gen_reg_rtx (tmode
);
11701 pat
= GEN_FCN (icode
) (target
);
11707 case ALTIVEC_BUILTIN_MTVSCR
:
11708 icode
= CODE_FOR_altivec_mtvscr
;
11709 arg0
= CALL_EXPR_ARG (exp
, 0);
11710 op0
= expand_normal (arg0
);
11711 mode0
= insn_data
[icode
].operand
[0].mode
;
11713 /* If we got invalid arguments bail out before generating bad rtl. */
11714 if (arg0
== error_mark_node
)
11717 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11718 op0
= copy_to_mode_reg (mode0
, op0
);
11720 pat
= GEN_FCN (icode
) (op0
);
11725 case ALTIVEC_BUILTIN_DSSALL
:
11726 emit_insn (gen_altivec_dssall ());
11729 case ALTIVEC_BUILTIN_DSS
:
11730 icode
= CODE_FOR_altivec_dss
;
11731 arg0
= CALL_EXPR_ARG (exp
, 0);
11733 op0
= expand_normal (arg0
);
11734 mode0
= insn_data
[icode
].operand
[0].mode
;
11736 /* If we got invalid arguments bail out before generating bad rtl. */
11737 if (arg0
== error_mark_node
)
11740 if (TREE_CODE (arg0
) != INTEGER_CST
11741 || TREE_INT_CST_LOW (arg0
) & ~0x3)
11743 error ("argument to dss must be a 2-bit unsigned literal");
11747 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11748 op0
= copy_to_mode_reg (mode0
, op0
);
11750 emit_insn (gen_altivec_dss (op0
));
11753 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
11754 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
11755 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
11756 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
11757 case VSX_BUILTIN_VEC_INIT_V2DF
:
11758 case VSX_BUILTIN_VEC_INIT_V2DI
:
11759 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
11761 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
11762 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
11763 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
11764 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
11765 case VSX_BUILTIN_VEC_SET_V2DF
:
11766 case VSX_BUILTIN_VEC_SET_V2DI
:
11767 return altivec_expand_vec_set_builtin (exp
);
11769 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
11770 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
11771 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
11772 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
11773 case VSX_BUILTIN_VEC_EXT_V2DF
:
11774 case VSX_BUILTIN_VEC_EXT_V2DI
:
11775 return altivec_expand_vec_ext_builtin (exp
, target
);
11779 /* Fall through. */
11782 /* Expand abs* operations. */
11784 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
11785 if (d
->code
== fcode
)
11786 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
11788 /* Expand the AltiVec predicates. */
11789 dp
= bdesc_altivec_preds
;
11790 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
11791 if (dp
->code
== fcode
)
11792 return altivec_expand_predicate_builtin (dp
->icode
, exp
, target
);
11794 /* LV* are funky. We initialized them differently. */
11797 case ALTIVEC_BUILTIN_LVSL
:
11798 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
11799 exp
, target
, false);
11800 case ALTIVEC_BUILTIN_LVSR
:
11801 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
11802 exp
, target
, false);
11803 case ALTIVEC_BUILTIN_LVEBX
:
11804 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
11805 exp
, target
, false);
11806 case ALTIVEC_BUILTIN_LVEHX
:
11807 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
11808 exp
, target
, false);
11809 case ALTIVEC_BUILTIN_LVEWX
:
11810 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
11811 exp
, target
, false);
11812 case ALTIVEC_BUILTIN_LVXL
:
11813 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
11814 exp
, target
, false);
11815 case ALTIVEC_BUILTIN_LVX
:
11816 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si
,
11817 exp
, target
, false);
11818 case ALTIVEC_BUILTIN_LVLX
:
11819 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
11820 exp
, target
, true);
11821 case ALTIVEC_BUILTIN_LVLXL
:
11822 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
11823 exp
, target
, true);
11824 case ALTIVEC_BUILTIN_LVRX
:
11825 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
11826 exp
, target
, true);
11827 case ALTIVEC_BUILTIN_LVRXL
:
11828 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
11829 exp
, target
, true);
11830 case VSX_BUILTIN_LXVD2X_V2DF
:
11831 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df
,
11832 exp
, target
, false);
11833 case VSX_BUILTIN_LXVD2X_V2DI
:
11834 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di
,
11835 exp
, target
, false);
11836 case VSX_BUILTIN_LXVW4X_V4SF
:
11837 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf
,
11838 exp
, target
, false);
11839 case VSX_BUILTIN_LXVW4X_V4SI
:
11840 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si
,
11841 exp
, target
, false);
11842 case VSX_BUILTIN_LXVW4X_V8HI
:
11843 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi
,
11844 exp
, target
, false);
11845 case VSX_BUILTIN_LXVW4X_V16QI
:
11846 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi
,
11847 exp
, target
, false);
11851 /* Fall through. */
11854 *expandedp
= false;
11858 /* Expand the builtin in EXP and store the result in TARGET. Store
11859 true in *EXPANDEDP if we found a builtin to expand. */
11861 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
11863 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11864 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11865 const struct builtin_description
*d
;
11872 case PAIRED_BUILTIN_STX
:
11873 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
11874 case PAIRED_BUILTIN_LX
:
11875 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
11878 /* Fall through. */
11881 /* Expand the paired predicates. */
11882 d
= bdesc_paired_preds
;
11883 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
11884 if (d
->code
== fcode
)
11885 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
11887 *expandedp
= false;
11891 /* Binops that need to be initialized manually, but can be expanded
11892 automagically by rs6000_expand_binop_builtin. */
11893 static struct builtin_description bdesc_2arg_spe
[] =
11895 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
11896 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
11897 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
11898 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
11899 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
11900 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
11901 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
11902 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
11903 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
11904 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
11905 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
11906 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
11907 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
11908 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
11909 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
11910 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
11911 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
11912 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
11913 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
11914 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
11915 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
11916 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
11919 /* Expand the builtin in EXP and store the result in TARGET. Store
11920 true in *EXPANDEDP if we found a builtin to expand.
11922 This expands the SPE builtins that are not simple unary and binary
11925 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11927 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11929 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11930 enum insn_code icode
;
11931 enum machine_mode tmode
, mode0
;
11933 struct builtin_description
*d
;
11938 /* Syntax check for a 5-bit unsigned immediate. */
11941 case SPE_BUILTIN_EVSTDD
:
11942 case SPE_BUILTIN_EVSTDH
:
11943 case SPE_BUILTIN_EVSTDW
:
11944 case SPE_BUILTIN_EVSTWHE
:
11945 case SPE_BUILTIN_EVSTWHO
:
11946 case SPE_BUILTIN_EVSTWWE
:
11947 case SPE_BUILTIN_EVSTWWO
:
11948 arg1
= CALL_EXPR_ARG (exp
, 2);
11949 if (TREE_CODE (arg1
) != INTEGER_CST
11950 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
11952 error ("argument 2 must be a 5-bit unsigned literal");
11960 /* The evsplat*i instructions are not quite generic. */
11963 case SPE_BUILTIN_EVSPLATFI
:
11964 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
11966 case SPE_BUILTIN_EVSPLATI
:
11967 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
11973 d
= (struct builtin_description
*) bdesc_2arg_spe
;
11974 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
11975 if (d
->code
== fcode
)
11976 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
11978 d
= (struct builtin_description
*) bdesc_spe_predicates
;
11979 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
11980 if (d
->code
== fcode
)
11981 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
11983 d
= (struct builtin_description
*) bdesc_spe_evsel
;
11984 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
11985 if (d
->code
== fcode
)
11986 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
11990 case SPE_BUILTIN_EVSTDDX
:
11991 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
11992 case SPE_BUILTIN_EVSTDHX
:
11993 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
11994 case SPE_BUILTIN_EVSTDWX
:
11995 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
11996 case SPE_BUILTIN_EVSTWHEX
:
11997 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
11998 case SPE_BUILTIN_EVSTWHOX
:
11999 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
12000 case SPE_BUILTIN_EVSTWWEX
:
12001 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
12002 case SPE_BUILTIN_EVSTWWOX
:
12003 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
12004 case SPE_BUILTIN_EVSTDD
:
12005 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
12006 case SPE_BUILTIN_EVSTDH
:
12007 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
12008 case SPE_BUILTIN_EVSTDW
:
12009 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
12010 case SPE_BUILTIN_EVSTWHE
:
12011 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
12012 case SPE_BUILTIN_EVSTWHO
:
12013 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
12014 case SPE_BUILTIN_EVSTWWE
:
12015 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
12016 case SPE_BUILTIN_EVSTWWO
:
12017 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
12018 case SPE_BUILTIN_MFSPEFSCR
:
12019 icode
= CODE_FOR_spe_mfspefscr
;
12020 tmode
= insn_data
[icode
].operand
[0].mode
;
12023 || GET_MODE (target
) != tmode
12024 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
12025 target
= gen_reg_rtx (tmode
);
12027 pat
= GEN_FCN (icode
) (target
);
12032 case SPE_BUILTIN_MTSPEFSCR
:
12033 icode
= CODE_FOR_spe_mtspefscr
;
12034 arg0
= CALL_EXPR_ARG (exp
, 0);
12035 op0
= expand_normal (arg0
);
12036 mode0
= insn_data
[icode
].operand
[0].mode
;
12038 if (arg0
== error_mark_node
)
12041 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
12042 op0
= copy_to_mode_reg (mode0
, op0
);
12044 pat
= GEN_FCN (icode
) (op0
);
12052 *expandedp
= false;
12057 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
12059 rtx pat
, scratch
, tmp
;
12060 tree form
= CALL_EXPR_ARG (exp
, 0);
12061 tree arg0
= CALL_EXPR_ARG (exp
, 1);
12062 tree arg1
= CALL_EXPR_ARG (exp
, 2);
12063 rtx op0
= expand_normal (arg0
);
12064 rtx op1
= expand_normal (arg1
);
12065 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
12066 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
12068 enum rtx_code code
;
12070 if (TREE_CODE (form
) != INTEGER_CST
)
12072 error ("argument 1 of __builtin_paired_predicate must be a constant");
12076 form_int
= TREE_INT_CST_LOW (form
);
12078 gcc_assert (mode0
== mode1
);
12080 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
12084 || GET_MODE (target
) != SImode
12085 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
12086 target
= gen_reg_rtx (SImode
);
12087 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
12088 op0
= copy_to_mode_reg (mode0
, op0
);
12089 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
12090 op1
= copy_to_mode_reg (mode1
, op1
);
12092 scratch
= gen_reg_rtx (CCFPmode
);
12094 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
12116 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
12119 error ("argument 1 of __builtin_paired_predicate is out of range");
12123 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
12124 emit_move_insn (target
, tmp
);
12129 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
12131 rtx pat
, scratch
, tmp
;
12132 tree form
= CALL_EXPR_ARG (exp
, 0);
12133 tree arg0
= CALL_EXPR_ARG (exp
, 1);
12134 tree arg1
= CALL_EXPR_ARG (exp
, 2);
12135 rtx op0
= expand_normal (arg0
);
12136 rtx op1
= expand_normal (arg1
);
12137 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
12138 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
12140 enum rtx_code code
;
12142 if (TREE_CODE (form
) != INTEGER_CST
)
12144 error ("argument 1 of __builtin_spe_predicate must be a constant");
12148 form_int
= TREE_INT_CST_LOW (form
);
12150 gcc_assert (mode0
== mode1
);
12152 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
12156 || GET_MODE (target
) != SImode
12157 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
12158 target
= gen_reg_rtx (SImode
);
12160 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
12161 op0
= copy_to_mode_reg (mode0
, op0
);
12162 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
12163 op1
= copy_to_mode_reg (mode1
, op1
);
12165 scratch
= gen_reg_rtx (CCmode
);
12167 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
12172 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12173 _lower_. We use one compare, but look in different bits of the
12174 CR for each variant.
12176 There are 2 elements in each SPE simd type (upper/lower). The CR
12177 bits are set as follows:
12179 BIT0 | BIT 1 | BIT 2 | BIT 3
12180 U | L | (U | L) | (U & L)
12182 So, for an "all" relationship, BIT 3 would be set.
12183 For an "any" relationship, BIT 2 would be set. Etc.
12185 Following traditional nomenclature, these bits map to:
12187 BIT0 | BIT 1 | BIT 2 | BIT 3
12190 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12195 /* All variant. OV bit. */
12197 /* We need to get to the OV bit, which is the ORDERED bit. We
12198 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12199 that's ugly and will make validate_condition_mode die.
12200 So let's just use another pattern. */
12201 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
12203 /* Any variant. EQ bit. */
12207 /* Upper variant. LT bit. */
12211 /* Lower variant. GT bit. */
12216 error ("argument 1 of __builtin_spe_predicate is out of range");
12220 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
12221 emit_move_insn (target
, tmp
);
12226 /* The evsel builtins look like this:
12228 e = __builtin_spe_evsel_OP (a, b, c, d);
12230 and work like this:
12232 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12233 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12237 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
12240 tree arg0
= CALL_EXPR_ARG (exp
, 0);
12241 tree arg1
= CALL_EXPR_ARG (exp
, 1);
12242 tree arg2
= CALL_EXPR_ARG (exp
, 2);
12243 tree arg3
= CALL_EXPR_ARG (exp
, 3);
12244 rtx op0
= expand_normal (arg0
);
12245 rtx op1
= expand_normal (arg1
);
12246 rtx op2
= expand_normal (arg2
);
12247 rtx op3
= expand_normal (arg3
);
12248 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
12249 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
12251 gcc_assert (mode0
== mode1
);
12253 if (arg0
== error_mark_node
|| arg1
== error_mark_node
12254 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
12258 || GET_MODE (target
) != mode0
12259 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
12260 target
= gen_reg_rtx (mode0
);
12262 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
12263 op0
= copy_to_mode_reg (mode0
, op0
);
12264 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
12265 op1
= copy_to_mode_reg (mode0
, op1
);
12266 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
12267 op2
= copy_to_mode_reg (mode0
, op2
);
12268 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
12269 op3
= copy_to_mode_reg (mode0
, op3
);
12271 /* Generate the compare. */
12272 scratch
= gen_reg_rtx (CCmode
);
12273 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
12278 if (mode0
== V2SImode
)
12279 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
12281 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
12286 /* Expand an expression EXP that calls a built-in function,
12287 with result going to TARGET if that's convenient
12288 (and in mode MODE if that's convenient).
12289 SUBTARGET may be used as the target for computing one of EXP's operands.
12290 IGNORE is nonzero if the value is to be ignored. */
12293 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
12294 enum machine_mode mode ATTRIBUTE_UNUSED
,
12295 int ignore ATTRIBUTE_UNUSED
)
12297 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
12298 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
12299 const struct builtin_description
*d
;
12306 case RS6000_BUILTIN_RECIP
:
12307 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
12309 case RS6000_BUILTIN_RECIPF
:
12310 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
12312 case RS6000_BUILTIN_RSQRTF
:
12313 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
12315 case RS6000_BUILTIN_RSQRT
:
12316 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2
, exp
, target
);
12318 case RS6000_BUILTIN_BSWAP_HI
:
12319 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2
, exp
, target
);
12321 case POWER7_BUILTIN_BPERMD
:
12322 return rs6000_expand_binop_builtin (((TARGET_64BIT
)
12323 ? CODE_FOR_bpermd_di
12324 : CODE_FOR_bpermd_si
), exp
, target
);
12326 case ALTIVEC_BUILTIN_MASK_FOR_LOAD
:
12327 case ALTIVEC_BUILTIN_MASK_FOR_STORE
:
12329 int icode
= (int) CODE_FOR_altivec_lvsr
;
12330 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
12331 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
12335 gcc_assert (TARGET_ALTIVEC
);
12337 arg
= CALL_EXPR_ARG (exp
, 0);
12338 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg
)));
12339 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
12340 addr
= memory_address (mode
, op
);
12341 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
12345 /* For the load case need to negate the address. */
12346 op
= gen_reg_rtx (GET_MODE (addr
));
12347 emit_insn (gen_rtx_SET (VOIDmode
, op
,
12348 gen_rtx_NEG (GET_MODE (addr
), addr
)));
12350 op
= gen_rtx_MEM (mode
, op
);
12353 || GET_MODE (target
) != tmode
12354 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
12355 target
= gen_reg_rtx (tmode
);
12357 /*pat = gen_altivec_lvsr (target, op);*/
12358 pat
= GEN_FCN (icode
) (target
, op
);
12366 case ALTIVEC_BUILTIN_VCFUX
:
12367 case ALTIVEC_BUILTIN_VCFSX
:
12368 case ALTIVEC_BUILTIN_VCTUXS
:
12369 case ALTIVEC_BUILTIN_VCTSXS
:
12370 /* FIXME: There's got to be a nicer way to handle this case than
12371 constructing a new CALL_EXPR. */
12372 if (call_expr_nargs (exp
) == 1)
12374 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
12375 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
12383 if (TARGET_ALTIVEC
)
12385 ret
= altivec_expand_builtin (exp
, target
, &success
);
12392 ret
= spe_expand_builtin (exp
, target
, &success
);
12397 if (TARGET_PAIRED_FLOAT
)
12399 ret
= paired_expand_builtin (exp
, target
, &success
);
12405 gcc_assert (TARGET_ALTIVEC
|| TARGET_VSX
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
12407 /* Handle simple unary operations. */
12408 d
= (struct builtin_description
*) bdesc_1arg
;
12409 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
12410 if (d
->code
== fcode
)
12411 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
12413 /* Handle simple binary operations. */
12414 d
= (struct builtin_description
*) bdesc_2arg
;
12415 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
12416 if (d
->code
== fcode
)
12417 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
12419 /* Handle simple ternary operations. */
12421 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
12422 if (d
->code
== fcode
)
12423 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
12425 gcc_unreachable ();
12429 rs6000_init_builtins (void)
12434 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
12435 V2SF_type_node
= build_vector_type (float_type_node
, 2);
12436 V2DI_type_node
= build_vector_type (intDI_type_node
, 2);
12437 V2DF_type_node
= build_vector_type (double_type_node
, 2);
12438 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
12439 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
12440 V4SF_type_node
= build_vector_type (float_type_node
, 4);
12441 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
12442 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
12444 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
12445 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
12446 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
12447 unsigned_V2DI_type_node
= build_vector_type (unsigned_intDI_type_node
, 2);
12449 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
12450 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
12451 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
12452 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
12454 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12455 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12456 'vector unsigned short'. */
12458 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
12459 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
12460 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
12461 bool_long_type_node
= build_distinct_type_copy (unsigned_intDI_type_node
);
12462 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
12464 long_integer_type_internal_node
= long_integer_type_node
;
12465 long_unsigned_type_internal_node
= long_unsigned_type_node
;
12466 long_long_integer_type_internal_node
= long_long_integer_type_node
;
12467 long_long_unsigned_type_internal_node
= long_long_unsigned_type_node
;
12468 intQI_type_internal_node
= intQI_type_node
;
12469 uintQI_type_internal_node
= unsigned_intQI_type_node
;
12470 intHI_type_internal_node
= intHI_type_node
;
12471 uintHI_type_internal_node
= unsigned_intHI_type_node
;
12472 intSI_type_internal_node
= intSI_type_node
;
12473 uintSI_type_internal_node
= unsigned_intSI_type_node
;
12474 intDI_type_internal_node
= intDI_type_node
;
12475 uintDI_type_internal_node
= unsigned_intDI_type_node
;
12476 float_type_internal_node
= float_type_node
;
12477 double_type_internal_node
= double_type_node
;
12478 void_type_internal_node
= void_type_node
;
12480 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12482 builtin_mode_to_type
[QImode
][0] = integer_type_node
;
12483 builtin_mode_to_type
[HImode
][0] = integer_type_node
;
12484 builtin_mode_to_type
[SImode
][0] = intSI_type_node
;
12485 builtin_mode_to_type
[SImode
][1] = unsigned_intSI_type_node
;
12486 builtin_mode_to_type
[DImode
][0] = intDI_type_node
;
12487 builtin_mode_to_type
[DImode
][1] = unsigned_intDI_type_node
;
12488 builtin_mode_to_type
[SFmode
][0] = float_type_node
;
12489 builtin_mode_to_type
[DFmode
][0] = double_type_node
;
12490 builtin_mode_to_type
[V2SImode
][0] = V2SI_type_node
;
12491 builtin_mode_to_type
[V2SFmode
][0] = V2SF_type_node
;
12492 builtin_mode_to_type
[V2DImode
][0] = V2DI_type_node
;
12493 builtin_mode_to_type
[V2DImode
][1] = unsigned_V2DI_type_node
;
12494 builtin_mode_to_type
[V2DFmode
][0] = V2DF_type_node
;
12495 builtin_mode_to_type
[V4HImode
][0] = V4HI_type_node
;
12496 builtin_mode_to_type
[V4SImode
][0] = V4SI_type_node
;
12497 builtin_mode_to_type
[V4SImode
][1] = unsigned_V4SI_type_node
;
12498 builtin_mode_to_type
[V4SFmode
][0] = V4SF_type_node
;
12499 builtin_mode_to_type
[V8HImode
][0] = V8HI_type_node
;
12500 builtin_mode_to_type
[V8HImode
][1] = unsigned_V8HI_type_node
;
12501 builtin_mode_to_type
[V16QImode
][0] = V16QI_type_node
;
12502 builtin_mode_to_type
[V16QImode
][1] = unsigned_V16QI_type_node
;
12504 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12505 get_identifier ("__bool char"),
12506 bool_char_type_node
);
12507 TYPE_NAME (bool_char_type_node
) = tdecl
;
12508 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12509 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12510 get_identifier ("__bool short"),
12511 bool_short_type_node
);
12512 TYPE_NAME (bool_short_type_node
) = tdecl
;
12513 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12514 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12515 get_identifier ("__bool int"),
12516 bool_int_type_node
);
12517 TYPE_NAME (bool_int_type_node
) = tdecl
;
12518 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12519 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
, get_identifier ("__pixel"),
12521 TYPE_NAME (pixel_type_node
) = tdecl
;
12522 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12524 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
12525 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
12526 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
12527 bool_V2DI_type_node
= build_vector_type (bool_long_type_node
, 2);
12528 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
12530 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12531 get_identifier ("__vector unsigned char"),
12532 unsigned_V16QI_type_node
);
12533 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
12534 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12535 tdecl
= build_decl (BUILTINS_LOCATION
,
12536 TYPE_DECL
, get_identifier ("__vector signed char"),
12538 TYPE_NAME (V16QI_type_node
) = tdecl
;
12539 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12540 tdecl
= build_decl (BUILTINS_LOCATION
,
12541 TYPE_DECL
, get_identifier ("__vector __bool char"),
12542 bool_V16QI_type_node
);
12543 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
12544 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12546 tdecl
= build_decl (BUILTINS_LOCATION
,
12547 TYPE_DECL
, get_identifier ("__vector unsigned short"),
12548 unsigned_V8HI_type_node
);
12549 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
12550 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12551 tdecl
= build_decl (BUILTINS_LOCATION
,
12552 TYPE_DECL
, get_identifier ("__vector signed short"),
12554 TYPE_NAME (V8HI_type_node
) = tdecl
;
12555 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12556 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12557 get_identifier ("__vector __bool short"),
12558 bool_V8HI_type_node
);
12559 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
12560 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12562 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12563 get_identifier ("__vector unsigned int"),
12564 unsigned_V4SI_type_node
);
12565 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
12566 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12567 tdecl
= build_decl (BUILTINS_LOCATION
,
12568 TYPE_DECL
, get_identifier ("__vector signed int"),
12570 TYPE_NAME (V4SI_type_node
) = tdecl
;
12571 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12572 tdecl
= build_decl (BUILTINS_LOCATION
,
12573 TYPE_DECL
, get_identifier ("__vector __bool int"),
12574 bool_V4SI_type_node
);
12575 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
12576 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12578 tdecl
= build_decl (BUILTINS_LOCATION
,
12579 TYPE_DECL
, get_identifier ("__vector float"),
12581 TYPE_NAME (V4SF_type_node
) = tdecl
;
12582 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12583 tdecl
= build_decl (BUILTINS_LOCATION
,
12584 TYPE_DECL
, get_identifier ("__vector __pixel"),
12585 pixel_V8HI_type_node
);
12586 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
12587 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12591 tdecl
= build_decl (BUILTINS_LOCATION
,
12592 TYPE_DECL
, get_identifier ("__vector double"),
12594 TYPE_NAME (V2DF_type_node
) = tdecl
;
12595 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12597 tdecl
= build_decl (BUILTINS_LOCATION
,
12598 TYPE_DECL
, get_identifier ("__vector long"),
12600 TYPE_NAME (V2DI_type_node
) = tdecl
;
12601 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12603 tdecl
= build_decl (BUILTINS_LOCATION
,
12604 TYPE_DECL
, get_identifier ("__vector unsigned long"),
12605 unsigned_V2DI_type_node
);
12606 TYPE_NAME (unsigned_V2DI_type_node
) = tdecl
;
12607 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12609 tdecl
= build_decl (BUILTINS_LOCATION
,
12610 TYPE_DECL
, get_identifier ("__vector __bool long"),
12611 bool_V2DI_type_node
);
12612 TYPE_NAME (bool_V2DI_type_node
) = tdecl
;
12613 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12616 if (TARGET_PAIRED_FLOAT
)
12617 paired_init_builtins ();
12619 spe_init_builtins ();
12620 if (TARGET_ALTIVEC
)
12621 altivec_init_builtins ();
12622 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
|| TARGET_VSX
)
12623 rs6000_common_init_builtins ();
12626 ftype
= builtin_function_type (DFmode
, DFmode
, DFmode
, VOIDmode
,
12627 RS6000_BUILTIN_RECIP
,
12628 "__builtin_recipdiv");
12629 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
12630 RS6000_BUILTIN_RECIP
);
12634 ftype
= builtin_function_type (SFmode
, SFmode
, SFmode
, VOIDmode
,
12635 RS6000_BUILTIN_RECIPF
,
12636 "__builtin_recipdivf");
12637 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
12638 RS6000_BUILTIN_RECIPF
);
12640 if (TARGET_FRSQRTE
)
12642 ftype
= builtin_function_type (DFmode
, DFmode
, VOIDmode
, VOIDmode
,
12643 RS6000_BUILTIN_RSQRT
,
12644 "__builtin_rsqrt");
12645 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrt", ftype
,
12646 RS6000_BUILTIN_RSQRT
);
12648 if (TARGET_FRSQRTES
)
12650 ftype
= builtin_function_type (SFmode
, SFmode
, VOIDmode
, VOIDmode
,
12651 RS6000_BUILTIN_RSQRTF
,
12652 "__builtin_rsqrtf");
12653 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
12654 RS6000_BUILTIN_RSQRTF
);
12656 if (TARGET_POPCNTD
)
12658 enum machine_mode mode
= (TARGET_64BIT
) ? DImode
: SImode
;
12659 tree ftype
= builtin_function_type (mode
, mode
, mode
, VOIDmode
,
12660 POWER7_BUILTIN_BPERMD
,
12661 "__builtin_bpermd");
12662 def_builtin (MASK_POPCNTD
, "__builtin_bpermd", ftype
,
12663 POWER7_BUILTIN_BPERMD
);
12665 if (TARGET_POWERPC
)
12667 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12668 tree ftype
= build_function_type_list (unsigned_intHI_type_node
,
12669 unsigned_intHI_type_node
,
12671 def_builtin (MASK_POWERPC
, "__builtin_bswap16", ftype
,
12672 RS6000_BUILTIN_BSWAP_HI
);
12676 /* AIX libm provides clog as __clog. */
12677 if (built_in_decls
[BUILT_IN_CLOG
])
12678 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
12681 #ifdef SUBTARGET_INIT_BUILTINS
12682 SUBTARGET_INIT_BUILTINS
;
12686 /* Returns the rs6000 builtin decl for CODE. */
12689 rs6000_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
12691 if (code
>= RS6000_BUILTIN_COUNT
)
12692 return error_mark_node
;
12694 return rs6000_builtin_decls
[code
];
12697 /* Search through a set of builtins and enable the mask bits.
12698 DESC is an array of builtins.
12699 SIZE is the total number of builtins.
12700 START is the builtin enum at which to start.
12701 END is the builtin enum at which to end. */
12703 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
12704 enum rs6000_builtins start
,
12705 enum rs6000_builtins end
)
12709 for (i
= 0; i
< size
; ++i
)
12710 if (desc
[i
].code
== start
)
12716 for (; i
< size
; ++i
)
12718 /* Flip all the bits on. */
12719 desc
[i
].mask
= target_flags
;
12720 if (desc
[i
].code
== end
)
12726 spe_init_builtins (void)
12728 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
12729 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
12730 struct builtin_description
*d
;
12733 tree v2si_ftype_4_v2si
12734 = build_function_type_list (opaque_V2SI_type_node
,
12735 opaque_V2SI_type_node
,
12736 opaque_V2SI_type_node
,
12737 opaque_V2SI_type_node
,
12738 opaque_V2SI_type_node
,
12741 tree v2sf_ftype_4_v2sf
12742 = build_function_type_list (opaque_V2SF_type_node
,
12743 opaque_V2SF_type_node
,
12744 opaque_V2SF_type_node
,
12745 opaque_V2SF_type_node
,
12746 opaque_V2SF_type_node
,
12749 tree int_ftype_int_v2si_v2si
12750 = build_function_type_list (integer_type_node
,
12752 opaque_V2SI_type_node
,
12753 opaque_V2SI_type_node
,
12756 tree int_ftype_int_v2sf_v2sf
12757 = build_function_type_list (integer_type_node
,
12759 opaque_V2SF_type_node
,
12760 opaque_V2SF_type_node
,
12763 tree void_ftype_v2si_puint_int
12764 = build_function_type_list (void_type_node
,
12765 opaque_V2SI_type_node
,
12770 tree void_ftype_v2si_puint_char
12771 = build_function_type_list (void_type_node
,
12772 opaque_V2SI_type_node
,
12777 tree void_ftype_v2si_pv2si_int
12778 = build_function_type_list (void_type_node
,
12779 opaque_V2SI_type_node
,
12780 opaque_p_V2SI_type_node
,
12784 tree void_ftype_v2si_pv2si_char
12785 = build_function_type_list (void_type_node
,
12786 opaque_V2SI_type_node
,
12787 opaque_p_V2SI_type_node
,
12791 tree void_ftype_int
12792 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
12794 tree int_ftype_void
12795 = build_function_type_list (integer_type_node
, NULL_TREE
);
12797 tree v2si_ftype_pv2si_int
12798 = build_function_type_list (opaque_V2SI_type_node
,
12799 opaque_p_V2SI_type_node
,
12803 tree v2si_ftype_puint_int
12804 = build_function_type_list (opaque_V2SI_type_node
,
12809 tree v2si_ftype_pushort_int
12810 = build_function_type_list (opaque_V2SI_type_node
,
12815 tree v2si_ftype_signed_char
12816 = build_function_type_list (opaque_V2SI_type_node
,
12817 signed_char_type_node
,
12820 /* The initialization of the simple binary and unary builtins is
12821 done in rs6000_common_init_builtins, but we have to enable the
12822 mask bits here manually because we have run out of `target_flags'
12823 bits. We really need to redesign this mask business. */
12825 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
12826 ARRAY_SIZE (bdesc_2arg
),
12827 SPE_BUILTIN_EVADDW
,
12828 SPE_BUILTIN_EVXOR
);
12829 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
12830 ARRAY_SIZE (bdesc_1arg
),
12832 SPE_BUILTIN_EVSUBFUSIAAW
);
12833 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
12834 ARRAY_SIZE (bdesc_spe_predicates
),
12835 SPE_BUILTIN_EVCMPEQ
,
12836 SPE_BUILTIN_EVFSTSTLT
);
12837 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
12838 ARRAY_SIZE (bdesc_spe_evsel
),
12839 SPE_BUILTIN_EVSEL_CMPGTS
,
12840 SPE_BUILTIN_EVSEL_FSTSTEQ
);
12842 (*lang_hooks
.decls
.pushdecl
)
12843 (build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12844 get_identifier ("__ev64_opaque__"),
12845 opaque_V2SI_type_node
));
12847 /* Initialize irregular SPE builtins. */
12849 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
12850 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
12851 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
12852 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
12853 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
12854 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
12855 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
12856 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
12857 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
12858 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
12859 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
12860 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
12861 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
12862 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
12863 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
12864 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
12865 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
12866 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
12869 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
12870 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
12871 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
12872 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
12873 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
12874 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
12875 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
12876 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
12877 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
12878 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
12879 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
12880 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
12881 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
12882 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
12883 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
12884 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
12885 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
12886 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
12887 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
12888 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
12889 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
12890 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
12893 d
= (struct builtin_description
*) bdesc_spe_predicates
;
12894 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
12898 switch (insn_data
[d
->icode
].operand
[1].mode
)
12901 type
= int_ftype_int_v2si_v2si
;
12904 type
= int_ftype_int_v2sf_v2sf
;
12907 gcc_unreachable ();
12910 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12913 /* Evsel predicates. */
12914 d
= (struct builtin_description
*) bdesc_spe_evsel
;
12915 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
12919 switch (insn_data
[d
->icode
].operand
[1].mode
)
12922 type
= v2si_ftype_4_v2si
;
12925 type
= v2sf_ftype_4_v2sf
;
12928 gcc_unreachable ();
12931 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12936 paired_init_builtins (void)
12938 const struct builtin_description
*d
;
12941 tree int_ftype_int_v2sf_v2sf
12942 = build_function_type_list (integer_type_node
,
12947 tree pcfloat_type_node
=
12948 build_pointer_type (build_qualified_type
12949 (float_type_node
, TYPE_QUAL_CONST
));
12951 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
12952 long_integer_type_node
,
12955 tree void_ftype_v2sf_long_pcfloat
=
12956 build_function_type_list (void_type_node
,
12958 long_integer_type_node
,
12963 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
12964 PAIRED_BUILTIN_LX
);
12967 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
12968 PAIRED_BUILTIN_STX
);
12971 d
= bdesc_paired_preds
;
12972 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
12976 switch (insn_data
[d
->icode
].operand
[1].mode
)
12979 type
= int_ftype_int_v2sf_v2sf
;
12982 gcc_unreachable ();
12985 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12990 altivec_init_builtins (void)
12992 const struct builtin_description
*d
;
12993 const struct builtin_description_predicates
*dp
;
12997 tree pvoid_type_node
= build_pointer_type (void_type_node
);
12999 tree pcvoid_type_node
13000 = build_pointer_type (build_qualified_type (void_type_node
,
13003 tree int_ftype_opaque
13004 = build_function_type_list (integer_type_node
,
13005 opaque_V4SI_type_node
, NULL_TREE
);
13006 tree opaque_ftype_opaque
13007 = build_function_type_list (integer_type_node
, NULL_TREE
);
13008 tree opaque_ftype_opaque_int
13009 = build_function_type_list (opaque_V4SI_type_node
,
13010 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
13011 tree opaque_ftype_opaque_opaque_int
13012 = build_function_type_list (opaque_V4SI_type_node
,
13013 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
13014 integer_type_node
, NULL_TREE
);
13015 tree int_ftype_int_opaque_opaque
13016 = build_function_type_list (integer_type_node
,
13017 integer_type_node
, opaque_V4SI_type_node
,
13018 opaque_V4SI_type_node
, NULL_TREE
);
13019 tree int_ftype_int_v4si_v4si
13020 = build_function_type_list (integer_type_node
,
13021 integer_type_node
, V4SI_type_node
,
13022 V4SI_type_node
, NULL_TREE
);
13023 tree void_ftype_v4si
13024 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
13025 tree v8hi_ftype_void
13026 = build_function_type_list (V8HI_type_node
, NULL_TREE
);
13027 tree void_ftype_void
13028 = build_function_type_list (void_type_node
, NULL_TREE
);
13029 tree void_ftype_int
13030 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
13032 tree opaque_ftype_long_pcvoid
13033 = build_function_type_list (opaque_V4SI_type_node
,
13034 long_integer_type_node
, pcvoid_type_node
,
13036 tree v16qi_ftype_long_pcvoid
13037 = build_function_type_list (V16QI_type_node
,
13038 long_integer_type_node
, pcvoid_type_node
,
13040 tree v8hi_ftype_long_pcvoid
13041 = build_function_type_list (V8HI_type_node
,
13042 long_integer_type_node
, pcvoid_type_node
,
13044 tree v4si_ftype_long_pcvoid
13045 = build_function_type_list (V4SI_type_node
,
13046 long_integer_type_node
, pcvoid_type_node
,
13048 tree v4sf_ftype_long_pcvoid
13049 = build_function_type_list (V4SF_type_node
,
13050 long_integer_type_node
, pcvoid_type_node
,
13052 tree v2df_ftype_long_pcvoid
13053 = build_function_type_list (V2DF_type_node
,
13054 long_integer_type_node
, pcvoid_type_node
,
13056 tree v2di_ftype_long_pcvoid
13057 = build_function_type_list (V2DI_type_node
,
13058 long_integer_type_node
, pcvoid_type_node
,
13061 tree void_ftype_opaque_long_pvoid
13062 = build_function_type_list (void_type_node
,
13063 opaque_V4SI_type_node
, long_integer_type_node
,
13064 pvoid_type_node
, NULL_TREE
);
13065 tree void_ftype_v4si_long_pvoid
13066 = build_function_type_list (void_type_node
,
13067 V4SI_type_node
, long_integer_type_node
,
13068 pvoid_type_node
, NULL_TREE
);
13069 tree void_ftype_v16qi_long_pvoid
13070 = build_function_type_list (void_type_node
,
13071 V16QI_type_node
, long_integer_type_node
,
13072 pvoid_type_node
, NULL_TREE
);
13073 tree void_ftype_v8hi_long_pvoid
13074 = build_function_type_list (void_type_node
,
13075 V8HI_type_node
, long_integer_type_node
,
13076 pvoid_type_node
, NULL_TREE
);
13077 tree void_ftype_v4sf_long_pvoid
13078 = build_function_type_list (void_type_node
,
13079 V4SF_type_node
, long_integer_type_node
,
13080 pvoid_type_node
, NULL_TREE
);
13081 tree void_ftype_v2df_long_pvoid
13082 = build_function_type_list (void_type_node
,
13083 V2DF_type_node
, long_integer_type_node
,
13084 pvoid_type_node
, NULL_TREE
);
13085 tree void_ftype_v2di_long_pvoid
13086 = build_function_type_list (void_type_node
,
13087 V2DI_type_node
, long_integer_type_node
,
13088 pvoid_type_node
, NULL_TREE
);
13089 tree int_ftype_int_v8hi_v8hi
13090 = build_function_type_list (integer_type_node
,
13091 integer_type_node
, V8HI_type_node
,
13092 V8HI_type_node
, NULL_TREE
);
13093 tree int_ftype_int_v16qi_v16qi
13094 = build_function_type_list (integer_type_node
,
13095 integer_type_node
, V16QI_type_node
,
13096 V16QI_type_node
, NULL_TREE
);
13097 tree int_ftype_int_v4sf_v4sf
13098 = build_function_type_list (integer_type_node
,
13099 integer_type_node
, V4SF_type_node
,
13100 V4SF_type_node
, NULL_TREE
);
13101 tree int_ftype_int_v2df_v2df
13102 = build_function_type_list (integer_type_node
,
13103 integer_type_node
, V2DF_type_node
,
13104 V2DF_type_node
, NULL_TREE
);
13105 tree v4si_ftype_v4si
13106 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
13107 tree v8hi_ftype_v8hi
13108 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
13109 tree v16qi_ftype_v16qi
13110 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
13111 tree v4sf_ftype_v4sf
13112 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
13113 tree v2df_ftype_v2df
13114 = build_function_type_list (V2DF_type_node
, V2DF_type_node
, NULL_TREE
);
13115 tree void_ftype_pcvoid_int_int
13116 = build_function_type_list (void_type_node
,
13117 pcvoid_type_node
, integer_type_node
,
13118 integer_type_node
, NULL_TREE
);
13120 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
13121 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
13122 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
13123 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
13124 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
13125 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
13126 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
13127 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
13128 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
13129 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
13130 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
13131 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
13132 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
13133 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
13134 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
13135 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
13136 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
13137 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
13138 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
13139 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
13140 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
13141 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
13142 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
13143 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
13144 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
13145 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
13146 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
13147 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
13148 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
13149 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
13151 def_builtin (MASK_VSX
, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid
,
13152 VSX_BUILTIN_LXVD2X_V2DF
);
13153 def_builtin (MASK_VSX
, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid
,
13154 VSX_BUILTIN_LXVD2X_V2DI
);
13155 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid
,
13156 VSX_BUILTIN_LXVW4X_V4SF
);
13157 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid
,
13158 VSX_BUILTIN_LXVW4X_V4SI
);
13159 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v8hi",
13160 v8hi_ftype_long_pcvoid
, VSX_BUILTIN_LXVW4X_V8HI
);
13161 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v16qi",
13162 v16qi_ftype_long_pcvoid
, VSX_BUILTIN_LXVW4X_V16QI
);
13163 def_builtin (MASK_VSX
, "__builtin_vsx_stxvd2x_v2df",
13164 void_ftype_v2df_long_pvoid
, VSX_BUILTIN_STXVD2X_V2DF
);
13165 def_builtin (MASK_VSX
, "__builtin_vsx_stxvd2x_v2di",
13166 void_ftype_v2di_long_pvoid
, VSX_BUILTIN_STXVD2X_V2DI
);
13167 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v4sf",
13168 void_ftype_v4sf_long_pvoid
, VSX_BUILTIN_STXVW4X_V4SF
);
13169 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v4si",
13170 void_ftype_v4si_long_pvoid
, VSX_BUILTIN_STXVW4X_V4SI
);
13171 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v8hi",
13172 void_ftype_v8hi_long_pvoid
, VSX_BUILTIN_STXVW4X_V8HI
);
13173 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v16qi",
13174 void_ftype_v16qi_long_pvoid
, VSX_BUILTIN_STXVW4X_V16QI
);
13175 def_builtin (MASK_VSX
, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid
,
13176 VSX_BUILTIN_VEC_LD
);
13177 def_builtin (MASK_VSX
, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid
,
13178 VSX_BUILTIN_VEC_ST
);
13180 if (rs6000_cpu
== PROCESSOR_CELL
)
13182 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
13183 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
13184 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
13185 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
13187 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
13188 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
13189 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
13190 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
13192 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
13193 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
13194 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
13195 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
13197 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
13198 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
13199 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
13200 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
13202 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
13203 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
13204 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
13206 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
13207 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
13208 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
13209 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
13210 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
13211 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
13212 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
13213 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
13214 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
13215 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
13216 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
13217 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
13219 /* Add the DST variants. */
13221 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
13222 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
13224 /* Initialize the predicates. */
13225 dp
= bdesc_altivec_preds
;
13226 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
13228 enum machine_mode mode1
;
13230 bool is_overloaded
= ((dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13231 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13232 || (dp
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13233 && dp
->code
<= VSX_BUILTIN_OVERLOADED_LAST
));
13238 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
13243 type
= int_ftype_int_opaque_opaque
;
13246 type
= int_ftype_int_v4si_v4si
;
13249 type
= int_ftype_int_v8hi_v8hi
;
13252 type
= int_ftype_int_v16qi_v16qi
;
13255 type
= int_ftype_int_v4sf_v4sf
;
13258 type
= int_ftype_int_v2df_v2df
;
13261 gcc_unreachable ();
13264 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
13267 /* Initialize the abs* operators. */
13269 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
13271 enum machine_mode mode0
;
13274 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
13279 type
= v4si_ftype_v4si
;
13282 type
= v8hi_ftype_v8hi
;
13285 type
= v16qi_ftype_v16qi
;
13288 type
= v4sf_ftype_v4sf
;
13291 type
= v2df_ftype_v2df
;
13294 gcc_unreachable ();
13297 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13300 if (TARGET_ALTIVEC
)
13304 /* Initialize target builtin that implements
13305 targetm.vectorize.builtin_mask_for_load. */
13307 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
13308 v16qi_ftype_long_pcvoid
,
13309 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
13310 BUILT_IN_MD
, NULL
, NULL_TREE
);
13311 TREE_READONLY (decl
) = 1;
13312 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13313 altivec_builtin_mask_for_load
= decl
;
13316 /* Access to the vec_init patterns. */
13317 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
13318 integer_type_node
, integer_type_node
,
13319 integer_type_node
, NULL_TREE
);
13320 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
13321 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
13323 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
13324 short_integer_type_node
,
13325 short_integer_type_node
,
13326 short_integer_type_node
,
13327 short_integer_type_node
,
13328 short_integer_type_node
,
13329 short_integer_type_node
,
13330 short_integer_type_node
, NULL_TREE
);
13331 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
13332 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
13334 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
13335 char_type_node
, char_type_node
,
13336 char_type_node
, char_type_node
,
13337 char_type_node
, char_type_node
,
13338 char_type_node
, char_type_node
,
13339 char_type_node
, char_type_node
,
13340 char_type_node
, char_type_node
,
13341 char_type_node
, char_type_node
,
13342 char_type_node
, NULL_TREE
);
13343 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
13344 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
13346 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
13347 float_type_node
, float_type_node
,
13348 float_type_node
, NULL_TREE
);
13349 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
13350 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
13354 ftype
= build_function_type_list (V2DF_type_node
, double_type_node
,
13355 double_type_node
, NULL_TREE
);
13356 def_builtin (MASK_VSX
, "__builtin_vec_init_v2df", ftype
,
13357 VSX_BUILTIN_VEC_INIT_V2DF
);
13359 ftype
= build_function_type_list (V2DI_type_node
, intDI_type_node
,
13360 intDI_type_node
, NULL_TREE
);
13361 def_builtin (MASK_VSX
, "__builtin_vec_init_v2di", ftype
,
13362 VSX_BUILTIN_VEC_INIT_V2DI
);
13365 /* Access to the vec_set patterns. */
13366 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
13368 integer_type_node
, NULL_TREE
);
13369 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
13370 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
13372 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
13374 integer_type_node
, NULL_TREE
);
13375 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
13376 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
13378 ftype
= build_function_type_list (V16QI_type_node
, V16QI_type_node
,
13380 integer_type_node
, NULL_TREE
);
13381 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
13382 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
13384 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
13386 integer_type_node
, NULL_TREE
);
13387 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_set_v4sf", ftype
,
13388 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
13392 ftype
= build_function_type_list (V2DF_type_node
, V2DF_type_node
,
13394 integer_type_node
, NULL_TREE
);
13395 def_builtin (MASK_VSX
, "__builtin_vec_set_v2df", ftype
,
13396 VSX_BUILTIN_VEC_SET_V2DF
);
13398 ftype
= build_function_type_list (V2DI_type_node
, V2DI_type_node
,
13400 integer_type_node
, NULL_TREE
);
13401 def_builtin (MASK_VSX
, "__builtin_vec_set_v2di", ftype
,
13402 VSX_BUILTIN_VEC_SET_V2DI
);
13405 /* Access to the vec_extract patterns. */
13406 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
13407 integer_type_node
, NULL_TREE
);
13408 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
13409 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
13411 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
13412 integer_type_node
, NULL_TREE
);
13413 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
13414 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
13416 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
13417 integer_type_node
, NULL_TREE
);
13418 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
13419 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
13421 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
13422 integer_type_node
, NULL_TREE
);
13423 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_ext_v4sf", ftype
,
13424 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
13428 ftype
= build_function_type_list (double_type_node
, V2DF_type_node
,
13429 integer_type_node
, NULL_TREE
);
13430 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2df", ftype
,
13431 VSX_BUILTIN_VEC_EXT_V2DF
);
13433 ftype
= build_function_type_list (intDI_type_node
, V2DI_type_node
,
13434 integer_type_node
, NULL_TREE
);
13435 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2di", ftype
,
13436 VSX_BUILTIN_VEC_EXT_V2DI
);
13440 /* Hash function for builtin functions with up to 3 arguments and a return
13443 builtin_hash_function (const void *hash_entry
)
13447 const struct builtin_hash_struct
*bh
=
13448 (const struct builtin_hash_struct
*) hash_entry
;
13450 for (i
= 0; i
< 4; i
++)
13452 ret
= (ret
* (unsigned)MAX_MACHINE_MODE
) + ((unsigned)bh
->mode
[i
]);
13453 ret
= (ret
* 2) + bh
->uns_p
[i
];
13459 /* Compare builtin hash entries H1 and H2 for equivalence. */
13461 builtin_hash_eq (const void *h1
, const void *h2
)
13463 const struct builtin_hash_struct
*p1
= (const struct builtin_hash_struct
*) h1
;
13464 const struct builtin_hash_struct
*p2
= (const struct builtin_hash_struct
*) h2
;
13466 return ((p1
->mode
[0] == p2
->mode
[0])
13467 && (p1
->mode
[1] == p2
->mode
[1])
13468 && (p1
->mode
[2] == p2
->mode
[2])
13469 && (p1
->mode
[3] == p2
->mode
[3])
13470 && (p1
->uns_p
[0] == p2
->uns_p
[0])
13471 && (p1
->uns_p
[1] == p2
->uns_p
[1])
13472 && (p1
->uns_p
[2] == p2
->uns_p
[2])
13473 && (p1
->uns_p
[3] == p2
->uns_p
[3]));
13476 /* Map types for builtin functions with an explicit return type and up to 3
13477 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13478 of the argument. */
13480 builtin_function_type (enum machine_mode mode_ret
, enum machine_mode mode_arg0
,
13481 enum machine_mode mode_arg1
, enum machine_mode mode_arg2
,
13482 enum rs6000_builtins builtin
, const char *name
)
13484 struct builtin_hash_struct h
;
13485 struct builtin_hash_struct
*h2
;
13489 tree ret_type
= NULL_TREE
;
13490 tree arg_type
[3] = { NULL_TREE
, NULL_TREE
, NULL_TREE
};
13492 /* Create builtin_hash_table. */
13493 if (builtin_hash_table
== NULL
)
13494 builtin_hash_table
= htab_create_ggc (1500, builtin_hash_function
,
13495 builtin_hash_eq
, NULL
);
13497 h
.type
= NULL_TREE
;
13498 h
.mode
[0] = mode_ret
;
13499 h
.mode
[1] = mode_arg0
;
13500 h
.mode
[2] = mode_arg1
;
13501 h
.mode
[3] = mode_arg2
;
13507 /* If the builtin is a type that produces unsigned results or takes unsigned
13508 arguments, and it is returned as a decl for the vectorizer (such as
13509 widening multiplies, permute), make sure the arguments and return value
13510 are type correct. */
13513 /* unsigned 2 argument functions. */
13514 case ALTIVEC_BUILTIN_VMULEUB_UNS
:
13515 case ALTIVEC_BUILTIN_VMULEUH_UNS
:
13516 case ALTIVEC_BUILTIN_VMULOUB_UNS
:
13517 case ALTIVEC_BUILTIN_VMULOUH_UNS
:
13523 /* unsigned 3 argument functions. */
13524 case ALTIVEC_BUILTIN_VPERM_16QI_UNS
:
13525 case ALTIVEC_BUILTIN_VPERM_8HI_UNS
:
13526 case ALTIVEC_BUILTIN_VPERM_4SI_UNS
:
13527 case ALTIVEC_BUILTIN_VPERM_2DI_UNS
:
13528 case ALTIVEC_BUILTIN_VSEL_16QI_UNS
:
13529 case ALTIVEC_BUILTIN_VSEL_8HI_UNS
:
13530 case ALTIVEC_BUILTIN_VSEL_4SI_UNS
:
13531 case ALTIVEC_BUILTIN_VSEL_2DI_UNS
:
13532 case VSX_BUILTIN_VPERM_16QI_UNS
:
13533 case VSX_BUILTIN_VPERM_8HI_UNS
:
13534 case VSX_BUILTIN_VPERM_4SI_UNS
:
13535 case VSX_BUILTIN_VPERM_2DI_UNS
:
13536 case VSX_BUILTIN_XXSEL_16QI_UNS
:
13537 case VSX_BUILTIN_XXSEL_8HI_UNS
:
13538 case VSX_BUILTIN_XXSEL_4SI_UNS
:
13539 case VSX_BUILTIN_XXSEL_2DI_UNS
:
13546 /* signed permute functions with unsigned char mask. */
13547 case ALTIVEC_BUILTIN_VPERM_16QI
:
13548 case ALTIVEC_BUILTIN_VPERM_8HI
:
13549 case ALTIVEC_BUILTIN_VPERM_4SI
:
13550 case ALTIVEC_BUILTIN_VPERM_4SF
:
13551 case ALTIVEC_BUILTIN_VPERM_2DI
:
13552 case ALTIVEC_BUILTIN_VPERM_2DF
:
13553 case VSX_BUILTIN_VPERM_16QI
:
13554 case VSX_BUILTIN_VPERM_8HI
:
13555 case VSX_BUILTIN_VPERM_4SI
:
13556 case VSX_BUILTIN_VPERM_4SF
:
13557 case VSX_BUILTIN_VPERM_2DI
:
13558 case VSX_BUILTIN_VPERM_2DF
:
13562 /* unsigned args, signed return. */
13563 case VSX_BUILTIN_XVCVUXDDP_UNS
:
13564 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
:
13568 /* signed args, unsigned return. */
13569 case VSX_BUILTIN_XVCVDPUXDS_UNS
:
13570 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
:
13578 /* Figure out how many args are present. */
13579 while (num_args
> 0 && h
.mode
[num_args
] == VOIDmode
)
13583 fatal_error ("internal error: builtin function %s had no type", name
);
13585 ret_type
= builtin_mode_to_type
[h
.mode
[0]][h
.uns_p
[0]];
13586 if (!ret_type
&& h
.uns_p
[0])
13587 ret_type
= builtin_mode_to_type
[h
.mode
[0]][0];
13590 fatal_error ("internal error: builtin function %s had an unexpected "
13591 "return type %s", name
, GET_MODE_NAME (h
.mode
[0]));
13593 for (i
= 0; i
< (int) ARRAY_SIZE (arg_type
); i
++)
13594 arg_type
[i
] = NULL_TREE
;
13596 for (i
= 0; i
< num_args
; i
++)
13598 int m
= (int) h
.mode
[i
+1];
13599 int uns_p
= h
.uns_p
[i
+1];
13601 arg_type
[i
] = builtin_mode_to_type
[m
][uns_p
];
13602 if (!arg_type
[i
] && uns_p
)
13603 arg_type
[i
] = builtin_mode_to_type
[m
][0];
13606 fatal_error ("internal error: builtin function %s, argument %d "
13607 "had unexpected argument type %s", name
, i
,
13608 GET_MODE_NAME (m
));
13611 found
= htab_find_slot (builtin_hash_table
, &h
, INSERT
);
13612 if (*found
== NULL
)
13614 h2
= ggc_alloc_builtin_hash_struct ();
13616 *found
= (void *)h2
;
13618 h2
->type
= build_function_type_list (ret_type
, arg_type
[0], arg_type
[1],
13619 arg_type
[2], NULL_TREE
);
13622 return ((struct builtin_hash_struct
*)(*found
))->type
;
13626 rs6000_common_init_builtins (void)
13628 const struct builtin_description
*d
;
13631 tree opaque_ftype_opaque
= NULL_TREE
;
13632 tree opaque_ftype_opaque_opaque
= NULL_TREE
;
13633 tree opaque_ftype_opaque_opaque_opaque
= NULL_TREE
;
13634 tree v2si_ftype_qi
= NULL_TREE
;
13635 tree v2si_ftype_v2si_qi
= NULL_TREE
;
13636 tree v2si_ftype_int_qi
= NULL_TREE
;
13638 if (!TARGET_PAIRED_FLOAT
)
13640 builtin_mode_to_type
[V2SImode
][0] = opaque_V2SI_type_node
;
13641 builtin_mode_to_type
[V2SFmode
][0] = opaque_V2SF_type_node
;
13644 /* Add the ternary operators. */
13646 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
13649 int mask
= d
->mask
;
13651 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13652 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13655 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13656 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13657 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13658 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13660 if (! (type
= opaque_ftype_opaque_opaque_opaque
))
13661 type
= opaque_ftype_opaque_opaque_opaque
13662 = build_function_type_list (opaque_V4SI_type_node
,
13663 opaque_V4SI_type_node
,
13664 opaque_V4SI_type_node
,
13665 opaque_V4SI_type_node
,
13670 enum insn_code icode
= d
->icode
;
13671 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13674 type
= builtin_function_type (insn_data
[icode
].operand
[0].mode
,
13675 insn_data
[icode
].operand
[1].mode
,
13676 insn_data
[icode
].operand
[2].mode
,
13677 insn_data
[icode
].operand
[3].mode
,
13681 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13684 /* Add the binary operators. */
13686 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
13688 enum machine_mode mode0
, mode1
, mode2
;
13690 int mask
= d
->mask
;
13692 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13693 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13696 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13697 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13698 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13699 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13701 if (! (type
= opaque_ftype_opaque_opaque
))
13702 type
= opaque_ftype_opaque_opaque
13703 = build_function_type_list (opaque_V4SI_type_node
,
13704 opaque_V4SI_type_node
,
13705 opaque_V4SI_type_node
,
13710 enum insn_code icode
= d
->icode
;
13711 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13714 mode0
= insn_data
[icode
].operand
[0].mode
;
13715 mode1
= insn_data
[icode
].operand
[1].mode
;
13716 mode2
= insn_data
[icode
].operand
[2].mode
;
13718 if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
13720 if (! (type
= v2si_ftype_v2si_qi
))
13721 type
= v2si_ftype_v2si_qi
13722 = build_function_type_list (opaque_V2SI_type_node
,
13723 opaque_V2SI_type_node
,
13728 else if (mode0
== V2SImode
&& GET_MODE_CLASS (mode1
) == MODE_INT
13729 && mode2
== QImode
)
13731 if (! (type
= v2si_ftype_int_qi
))
13732 type
= v2si_ftype_int_qi
13733 = build_function_type_list (opaque_V2SI_type_node
,
13740 type
= builtin_function_type (mode0
, mode1
, mode2
, VOIDmode
,
13744 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13747 /* Add the simple unary operators. */
13748 d
= (struct builtin_description
*) bdesc_1arg
;
13749 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
13751 enum machine_mode mode0
, mode1
;
13753 int mask
= d
->mask
;
13755 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13756 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13759 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13760 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13761 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13762 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13764 if (! (type
= opaque_ftype_opaque
))
13765 type
= opaque_ftype_opaque
13766 = build_function_type_list (opaque_V4SI_type_node
,
13767 opaque_V4SI_type_node
,
13772 enum insn_code icode
= d
->icode
;
13773 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13776 mode0
= insn_data
[icode
].operand
[0].mode
;
13777 mode1
= insn_data
[icode
].operand
[1].mode
;
13779 if (mode0
== V2SImode
&& mode1
== QImode
)
13781 if (! (type
= v2si_ftype_qi
))
13782 type
= v2si_ftype_qi
13783 = build_function_type_list (opaque_V2SI_type_node
,
13789 type
= builtin_function_type (mode0
, mode1
, VOIDmode
, VOIDmode
,
13793 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13798 rs6000_init_libfuncs (void)
13800 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
13801 && !TARGET_POWER2
&& !TARGET_POWERPC
)
13803 /* AIX library routines for float->int conversion. */
13804 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
13805 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
13806 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
13807 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
13810 if (!TARGET_IEEEQUAD
)
13811 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13812 if (!TARGET_XL_COMPAT
)
13814 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
13815 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
13816 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
13817 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
13819 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
13821 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
13822 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
13823 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
13824 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
13825 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
13826 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
13827 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
13829 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
13830 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
13831 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
13832 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
13833 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
13834 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
13835 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
13836 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
13839 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
13840 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
13844 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
13845 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
13846 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
13847 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
13851 /* 32-bit SVR4 quad floating point routines. */
13853 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
13854 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
13855 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
13856 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
13857 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
13858 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
13859 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
13861 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
13862 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
13863 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
13864 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
13865 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
13866 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
13868 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
13869 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
13870 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
13871 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
13872 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
13873 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
13874 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
13875 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
13880 /* Expand a block clear operation, and return 1 if successful. Return 0
13881 if we should let the compiler generate normal code.
13883 operands[0] is the destination
13884 operands[1] is the length
13885 operands[3] is the alignment */
13888 expand_block_clear (rtx operands
[])
13890 rtx orig_dest
= operands
[0];
13891 rtx bytes_rtx
= operands
[1];
13892 rtx align_rtx
= operands
[3];
13893 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
13894 HOST_WIDE_INT align
;
13895 HOST_WIDE_INT bytes
;
13900 /* If this is not a fixed size move, just call memcpy */
13904 /* This must be a fixed size alignment */
13905 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
13906 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
13908 /* Anything to clear? */
13909 bytes
= INTVAL (bytes_rtx
);
13913 /* Use the builtin memset after a point, to avoid huge code bloat.
13914 When optimize_size, avoid any significant code bloat; calling
13915 memset is about 4 instructions, so allow for one instruction to
13916 load zero and three to do clearing. */
13917 if (TARGET_ALTIVEC
&& align
>= 128)
13919 else if (TARGET_POWERPC64
&& align
>= 32)
13921 else if (TARGET_SPE
&& align
>= 64)
13926 if (optimize_size
&& bytes
> 3 * clear_step
)
13928 if (! optimize_size
&& bytes
> 8 * clear_step
)
13931 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
13933 enum machine_mode mode
= BLKmode
;
13936 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
13941 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
13946 else if (bytes
>= 8 && TARGET_POWERPC64
13947 /* 64-bit loads and stores require word-aligned
13949 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
13954 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
13955 { /* move 4 bytes */
13959 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
13960 { /* move 2 bytes */
13964 else /* move 1 byte at a time */
13970 dest
= adjust_address (orig_dest
, mode
, offset
);
13972 emit_move_insn (dest
, CONST0_RTX (mode
));
13979 /* Expand a block move operation, and return 1 if successful. Return 0
13980 if we should let the compiler generate normal code.
13982 operands[0] is the destination
13983 operands[1] is the source
13984 operands[2] is the length
13985 operands[3] is the alignment */
13987 #define MAX_MOVE_REG 4
13990 expand_block_move (rtx operands
[])
13992 rtx orig_dest
= operands
[0];
13993 rtx orig_src
= operands
[1];
13994 rtx bytes_rtx
= operands
[2];
13995 rtx align_rtx
= operands
[3];
13996 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
14001 rtx stores
[MAX_MOVE_REG
];
14004 /* If this is not a fixed size move, just call memcpy */
14008 /* This must be a fixed size alignment */
14009 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
14010 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
14012 /* Anything to move? */
14013 bytes
= INTVAL (bytes_rtx
);
14017 if (bytes
> rs6000_block_move_inline_limit
)
14020 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
14023 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
14024 rtx (*mov
) (rtx
, rtx
);
14026 enum machine_mode mode
= BLKmode
;
14029 /* Altivec first, since it will be faster than a string move
14030 when it applies, and usually not significantly larger. */
14031 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
14035 gen_func
.mov
= gen_movv4si
;
14037 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
14041 gen_func
.mov
= gen_movv2si
;
14043 else if (TARGET_STRING
14044 && bytes
> 24 /* move up to 32 bytes at a time */
14050 && ! fixed_regs
[10]
14051 && ! fixed_regs
[11]
14052 && ! fixed_regs
[12])
14054 move_bytes
= (bytes
> 32) ? 32 : bytes
;
14055 gen_func
.movmemsi
= gen_movmemsi_8reg
;
14057 else if (TARGET_STRING
14058 && bytes
> 16 /* move up to 24 bytes at a time */
14064 && ! fixed_regs
[10])
14066 move_bytes
= (bytes
> 24) ? 24 : bytes
;
14067 gen_func
.movmemsi
= gen_movmemsi_6reg
;
14069 else if (TARGET_STRING
14070 && bytes
> 8 /* move up to 16 bytes at a time */
14074 && ! fixed_regs
[8])
14076 move_bytes
= (bytes
> 16) ? 16 : bytes
;
14077 gen_func
.movmemsi
= gen_movmemsi_4reg
;
14079 else if (bytes
>= 8 && TARGET_POWERPC64
14080 /* 64-bit loads and stores require word-aligned
14082 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
14086 gen_func
.mov
= gen_movdi
;
14088 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
14089 { /* move up to 8 bytes at a time */
14090 move_bytes
= (bytes
> 8) ? 8 : bytes
;
14091 gen_func
.movmemsi
= gen_movmemsi_2reg
;
14093 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
14094 { /* move 4 bytes */
14097 gen_func
.mov
= gen_movsi
;
14099 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
14100 { /* move 2 bytes */
14103 gen_func
.mov
= gen_movhi
;
14105 else if (TARGET_STRING
&& bytes
> 1)
14106 { /* move up to 4 bytes at a time */
14107 move_bytes
= (bytes
> 4) ? 4 : bytes
;
14108 gen_func
.movmemsi
= gen_movmemsi_1reg
;
14110 else /* move 1 byte at a time */
14114 gen_func
.mov
= gen_movqi
;
14117 src
= adjust_address (orig_src
, mode
, offset
);
14118 dest
= adjust_address (orig_dest
, mode
, offset
);
14120 if (mode
!= BLKmode
)
14122 rtx tmp_reg
= gen_reg_rtx (mode
);
14124 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
14125 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
14128 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
14131 for (i
= 0; i
< num_reg
; i
++)
14132 emit_insn (stores
[i
]);
14136 if (mode
== BLKmode
)
14138 /* Move the address into scratch registers. The movmemsi
14139 patterns require zero offset. */
14140 if (!REG_P (XEXP (src
, 0)))
14142 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
14143 src
= replace_equiv_address (src
, src_reg
);
14145 set_mem_size (src
, GEN_INT (move_bytes
));
14147 if (!REG_P (XEXP (dest
, 0)))
14149 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
14150 dest
= replace_equiv_address (dest
, dest_reg
);
14152 set_mem_size (dest
, GEN_INT (move_bytes
));
14154 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
14155 GEN_INT (move_bytes
& 31),
14164 /* Return a string to perform a load_multiple operation.
14165 operands[0] is the vector.
14166 operands[1] is the source address.
14167 operands[2] is the first destination register. */
14170 rs6000_output_load_multiple (rtx operands
[3])
14172 /* We have to handle the case where the pseudo used to contain the address
14173 is assigned to one of the output registers. */
14175 int words
= XVECLEN (operands
[0], 0);
14178 if (XVECLEN (operands
[0], 0) == 1)
14179 return "{l|lwz} %2,0(%1)";
14181 for (i
= 0; i
< words
; i
++)
14182 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
14183 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
14187 xop
[0] = GEN_INT (4 * (words
-1));
14188 xop
[1] = operands
[1];
14189 xop
[2] = operands
[2];
14190 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
14195 xop
[0] = GEN_INT (4 * (words
-1));
14196 xop
[1] = operands
[1];
14197 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
14198 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
);
14203 for (j
= 0; j
< words
; j
++)
14206 xop
[0] = GEN_INT (j
* 4);
14207 xop
[1] = operands
[1];
14208 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
14209 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
14211 xop
[0] = GEN_INT (i
* 4);
14212 xop
[1] = operands
[1];
14213 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
14218 return "{lsi|lswi} %2,%1,%N0";
14222 /* A validation routine: say whether CODE, a condition code, and MODE
14223 match. The other alternatives either don't make sense or should
14224 never be generated. */
14227 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
14229 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
14230 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
14231 && GET_MODE_CLASS (mode
) == MODE_CC
);
14233 /* These don't make sense. */
14234 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
14235 || mode
!= CCUNSmode
);
14237 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
14238 || mode
== CCUNSmode
);
14240 gcc_assert (mode
== CCFPmode
14241 || (code
!= ORDERED
&& code
!= UNORDERED
14242 && code
!= UNEQ
&& code
!= LTGT
14243 && code
!= UNGT
&& code
!= UNLT
14244 && code
!= UNGE
&& code
!= UNLE
));
14246 /* These should never be generated except for
14247 flag_finite_math_only. */
14248 gcc_assert (mode
!= CCFPmode
14249 || flag_finite_math_only
14250 || (code
!= LE
&& code
!= GE
14251 && code
!= UNEQ
&& code
!= LTGT
14252 && code
!= UNGT
&& code
!= UNLT
));
14254 /* These are invalid; the information is not there. */
14255 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
14259 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14260 mask required to convert the result of a rotate insn into a shift
14261 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14264 includes_lshift_p (rtx shiftop
, rtx andop
)
14266 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
14268 shift_mask
<<= INTVAL (shiftop
);
14270 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
14273 /* Similar, but for right shift. */
14276 includes_rshift_p (rtx shiftop
, rtx andop
)
14278 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
14280 shift_mask
>>= INTVAL (shiftop
);
14282 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
14285 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14286 to perform a left shift. It must have exactly SHIFTOP least
14287 significant 0's, then one or more 1's, then zero or more 0's. */
14290 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
14292 if (GET_CODE (andop
) == CONST_INT
)
14294 HOST_WIDE_INT c
, lsb
, shift_mask
;
14296 c
= INTVAL (andop
);
14297 if (c
== 0 || c
== ~0)
14301 shift_mask
<<= INTVAL (shiftop
);
14303 /* Find the least significant one bit. */
14306 /* It must coincide with the LSB of the shift mask. */
14307 if (-lsb
!= shift_mask
)
14310 /* Invert to look for the next transition (if any). */
14313 /* Remove the low group of ones (originally low group of zeros). */
14316 /* Again find the lsb, and check we have all 1's above. */
14320 else if (GET_CODE (andop
) == CONST_DOUBLE
14321 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
14323 HOST_WIDE_INT low
, high
, lsb
;
14324 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
14326 low
= CONST_DOUBLE_LOW (andop
);
14327 if (HOST_BITS_PER_WIDE_INT
< 64)
14328 high
= CONST_DOUBLE_HIGH (andop
);
14330 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
14331 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
14334 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
14336 shift_mask_high
= ~0;
14337 if (INTVAL (shiftop
) > 32)
14338 shift_mask_high
<<= INTVAL (shiftop
) - 32;
14340 lsb
= high
& -high
;
14342 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
14348 lsb
= high
& -high
;
14349 return high
== -lsb
;
14352 shift_mask_low
= ~0;
14353 shift_mask_low
<<= INTVAL (shiftop
);
14357 if (-lsb
!= shift_mask_low
)
14360 if (HOST_BITS_PER_WIDE_INT
< 64)
14365 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
14367 lsb
= high
& -high
;
14368 return high
== -lsb
;
14372 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
14378 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14379 to perform a left shift. It must have SHIFTOP or more least
14380 significant 0's, with the remainder of the word 1's. */
14383 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
14385 if (GET_CODE (andop
) == CONST_INT
)
14387 HOST_WIDE_INT c
, lsb
, shift_mask
;
14390 shift_mask
<<= INTVAL (shiftop
);
14391 c
= INTVAL (andop
);
14393 /* Find the least significant one bit. */
14396 /* It must be covered by the shift mask.
14397 This test also rejects c == 0. */
14398 if ((lsb
& shift_mask
) == 0)
14401 /* Check we have all 1's above the transition, and reject all 1's. */
14402 return c
== -lsb
&& lsb
!= 1;
14404 else if (GET_CODE (andop
) == CONST_DOUBLE
14405 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
14407 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
14409 low
= CONST_DOUBLE_LOW (andop
);
14411 if (HOST_BITS_PER_WIDE_INT
< 64)
14413 HOST_WIDE_INT high
, shift_mask_high
;
14415 high
= CONST_DOUBLE_HIGH (andop
);
14419 shift_mask_high
= ~0;
14420 if (INTVAL (shiftop
) > 32)
14421 shift_mask_high
<<= INTVAL (shiftop
) - 32;
14423 lsb
= high
& -high
;
14425 if ((lsb
& shift_mask_high
) == 0)
14428 return high
== -lsb
;
14434 shift_mask_low
= ~0;
14435 shift_mask_low
<<= INTVAL (shiftop
);
14439 if ((lsb
& shift_mask_low
) == 0)
14442 return low
== -lsb
&& lsb
!= 1;
14448 /* Return 1 if operands will generate a valid arguments to rlwimi
14449 instruction for insert with right shift in 64-bit mode. The mask may
14450 not start on the first bit or stop on the last bit because wrap-around
14451 effects of instruction do not correspond to semantics of RTL insn. */
14454 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
14456 if (INTVAL (startop
) > 32
14457 && INTVAL (startop
) < 64
14458 && INTVAL (sizeop
) > 1
14459 && INTVAL (sizeop
) + INTVAL (startop
) < 64
14460 && INTVAL (shiftop
) > 0
14461 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
14462 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
14468 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14469 for lfq and stfq insns iff the registers are hard registers. */
14472 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
14474 /* We might have been passed a SUBREG. */
14475 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
14478 /* We might have been passed non floating point registers. */
14479 if (!FP_REGNO_P (REGNO (reg1
))
14480 || !FP_REGNO_P (REGNO (reg2
)))
14483 return (REGNO (reg1
) == REGNO (reg2
) - 1);
14486 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14487 addr1 and addr2 must be in consecutive memory locations
14488 (addr2 == addr1 + 8). */
14491 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
14494 unsigned int reg1
, reg2
;
14495 int offset1
, offset2
;
14497 /* The mems cannot be volatile. */
14498 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
14501 addr1
= XEXP (mem1
, 0);
14502 addr2
= XEXP (mem2
, 0);
14504 /* Extract an offset (if used) from the first addr. */
14505 if (GET_CODE (addr1
) == PLUS
)
14507 /* If not a REG, return zero. */
14508 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
14512 reg1
= REGNO (XEXP (addr1
, 0));
14513 /* The offset must be constant! */
14514 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
14516 offset1
= INTVAL (XEXP (addr1
, 1));
14519 else if (GET_CODE (addr1
) != REG
)
14523 reg1
= REGNO (addr1
);
14524 /* This was a simple (mem (reg)) expression. Offset is 0. */
14528 /* And now for the second addr. */
14529 if (GET_CODE (addr2
) == PLUS
)
14531 /* If not a REG, return zero. */
14532 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
14536 reg2
= REGNO (XEXP (addr2
, 0));
14537 /* The offset must be constant. */
14538 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
14540 offset2
= INTVAL (XEXP (addr2
, 1));
14543 else if (GET_CODE (addr2
) != REG
)
14547 reg2
= REGNO (addr2
);
14548 /* This was a simple (mem (reg)) expression. Offset is 0. */
14552 /* Both of these must have the same base register. */
14556 /* The offset for the second addr must be 8 more than the first addr. */
14557 if (offset2
!= offset1
+ 8)
14560 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14567 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
14569 static bool eliminated
= false;
14572 if (mode
!= SDmode
)
14573 ret
= assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
14576 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
14577 gcc_assert (mem
!= NULL_RTX
);
14581 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
14582 cfun
->machine
->sdmode_stack_slot
= mem
;
14588 if (TARGET_DEBUG_ADDR
)
14590 fprintf (stderr
, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14591 GET_MODE_NAME (mode
));
14593 fprintf (stderr
, "\tNULL_RTX\n");
14602 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
14604 /* Don't walk into types. */
14605 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
14607 *walk_subtrees
= 0;
14611 switch (TREE_CODE (*tp
))
14620 case VIEW_CONVERT_EXPR
:
14621 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
14631 enum reload_reg_type
{
14633 VECTOR_REGISTER_TYPE
,
14634 OTHER_REGISTER_TYPE
14637 static enum reload_reg_type
14638 rs6000_reload_register_type (enum reg_class rclass
)
14644 return GPR_REGISTER_TYPE
;
14649 return VECTOR_REGISTER_TYPE
;
14652 return OTHER_REGISTER_TYPE
;
14656 /* Inform reload about cases where moving X with a mode MODE to a register in
14657 RCLASS requires an extra scratch or immediate register. Return the class
14658 needed for the immediate register.
14660 For VSX and Altivec, we may need a register to convert sp+offset into
14663 For misaligned 64-bit gpr loads and stores we need a register to
14664 convert an offset address to indirect. */
14667 rs6000_secondary_reload (bool in_p
,
14669 reg_class_t rclass_i
,
14670 enum machine_mode mode
,
14671 secondary_reload_info
*sri
)
14673 enum reg_class rclass
= (enum reg_class
) rclass_i
;
14674 reg_class_t ret
= ALL_REGS
;
14675 enum insn_code icode
;
14676 bool default_p
= false;
14678 sri
->icode
= CODE_FOR_nothing
;
14680 /* Convert vector loads and stores into gprs to use an additional base
14682 icode
= rs6000_vector_reload
[mode
][in_p
!= false];
14683 if (icode
!= CODE_FOR_nothing
)
14686 sri
->icode
= CODE_FOR_nothing
;
14687 sri
->extra_cost
= 0;
14689 if (GET_CODE (x
) == MEM
)
14691 rtx addr
= XEXP (x
, 0);
14693 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14694 an extra register in that case, but it would need an extra
14695 register if the addressing is reg+reg or (reg+reg)&(-16). */
14696 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
)
14698 if (!legitimate_indirect_address_p (addr
, false)
14699 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14701 sri
->icode
= icode
;
14702 /* account for splitting the loads, and converting the
14703 address from reg+reg to reg. */
14704 sri
->extra_cost
= (((TARGET_64BIT
) ? 3 : 5)
14705 + ((GET_CODE (addr
) == AND
) ? 1 : 0));
14708 /* Loads to and stores from vector registers can only do reg+reg
14709 addressing. Altivec registers can also do (reg+reg)&(-16). */
14710 else if (rclass
== VSX_REGS
|| rclass
== ALTIVEC_REGS
14711 || rclass
== FLOAT_REGS
|| rclass
== NO_REGS
)
14713 if (!VECTOR_MEM_ALTIVEC_P (mode
)
14714 && GET_CODE (addr
) == AND
14715 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14716 && INTVAL (XEXP (addr
, 1)) == -16
14717 && (legitimate_indirect_address_p (XEXP (addr
, 0), false)
14718 || legitimate_indexed_address_p (XEXP (addr
, 0), false)))
14720 sri
->icode
= icode
;
14721 sri
->extra_cost
= ((GET_CODE (XEXP (addr
, 0)) == PLUS
)
14724 else if (!legitimate_indirect_address_p (addr
, false)
14725 && (rclass
== NO_REGS
14726 || !legitimate_indexed_address_p (addr
, false)))
14728 sri
->icode
= icode
;
14729 sri
->extra_cost
= 1;
14732 icode
= CODE_FOR_nothing
;
14734 /* Any other loads, including to pseudo registers which haven't been
14735 assigned to a register yet, default to require a scratch
14739 sri
->icode
= icode
;
14740 sri
->extra_cost
= 2;
14743 else if (REG_P (x
))
14745 int regno
= true_regnum (x
);
14747 icode
= CODE_FOR_nothing
;
14748 if (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
)
14752 enum reg_class xclass
= REGNO_REG_CLASS (regno
);
14753 enum reload_reg_type rtype1
= rs6000_reload_register_type (rclass
);
14754 enum reload_reg_type rtype2
= rs6000_reload_register_type (xclass
);
14756 /* If memory is needed, use default_secondary_reload to create the
14758 if (rtype1
!= rtype2
|| rtype1
== OTHER_REGISTER_TYPE
)
14767 else if (TARGET_POWERPC64
14768 && rs6000_reload_register_type (rclass
) == GPR_REGISTER_TYPE
14770 && GET_MODE_SIZE (GET_MODE (x
)) >= UNITS_PER_WORD
)
14772 rtx addr
= XEXP (x
, 0);
14774 if (GET_CODE (addr
) == PRE_MODIFY
)
14775 addr
= XEXP (addr
, 1);
14776 else if (GET_CODE (addr
) == LO_SUM
14777 && GET_CODE (XEXP (addr
, 0)) == REG
14778 && GET_CODE (XEXP (addr
, 1)) == CONST
)
14779 addr
= XEXP (XEXP (addr
, 1), 0);
14781 if (GET_CODE (addr
) == PLUS
14782 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14783 && (INTVAL (XEXP (addr
, 1)) & 3) != 0)
14786 sri
->icode
= CODE_FOR_reload_di_load
;
14788 sri
->icode
= CODE_FOR_reload_di_store
;
14789 sri
->extra_cost
= 2;
14799 ret
= default_secondary_reload (in_p
, x
, rclass
, mode
, sri
);
14801 gcc_assert (ret
!= ALL_REGS
);
14803 if (TARGET_DEBUG_ADDR
)
14806 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14808 reg_class_names
[ret
],
14809 in_p
? "true" : "false",
14810 reg_class_names
[rclass
],
14811 GET_MODE_NAME (mode
));
14814 fprintf (stderr
, ", default secondary reload");
14816 if (sri
->icode
!= CODE_FOR_nothing
)
14817 fprintf (stderr
, ", reload func = %s, extra cost = %d\n",
14818 insn_data
[sri
->icode
].name
, sri
->extra_cost
);
14820 fprintf (stderr
, "\n");
14828 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14829 to SP+reg addressing. */
14832 rs6000_secondary_reload_inner (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
14834 int regno
= true_regnum (reg
);
14835 enum machine_mode mode
= GET_MODE (reg
);
14836 enum reg_class rclass
;
14838 rtx and_op2
= NULL_RTX
;
14841 rtx scratch_or_premodify
= scratch
;
14845 if (TARGET_DEBUG_ADDR
)
14847 fprintf (stderr
, "\nrs6000_secondary_reload_inner, type = %s\n",
14848 store_p
? "store" : "load");
14849 fprintf (stderr
, "reg:\n");
14851 fprintf (stderr
, "mem:\n");
14853 fprintf (stderr
, "scratch:\n");
14854 debug_rtx (scratch
);
14857 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
14858 gcc_assert (GET_CODE (mem
) == MEM
);
14859 rclass
= REGNO_REG_CLASS (regno
);
14860 addr
= XEXP (mem
, 0);
14864 /* GPRs can handle reg + small constant, all other addresses need to use
14865 the scratch register. */
14868 if (GET_CODE (addr
) == AND
)
14870 and_op2
= XEXP (addr
, 1);
14871 addr
= XEXP (addr
, 0);
14874 if (GET_CODE (addr
) == PRE_MODIFY
)
14876 scratch_or_premodify
= XEXP (addr
, 0);
14877 gcc_assert (REG_P (scratch_or_premodify
));
14878 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14879 addr
= XEXP (addr
, 1);
14882 if (GET_CODE (addr
) == PLUS
14883 && (!rs6000_legitimate_offset_address_p (TImode
, addr
, false)
14884 || and_op2
!= NULL_RTX
))
14886 addr_op1
= XEXP (addr
, 0);
14887 addr_op2
= XEXP (addr
, 1);
14888 gcc_assert (legitimate_indirect_address_p (addr_op1
, false));
14890 if (!REG_P (addr_op2
)
14891 && (GET_CODE (addr_op2
) != CONST_INT
14892 || !satisfies_constraint_I (addr_op2
)))
14894 if (TARGET_DEBUG_ADDR
)
14897 "\nMove plus addr to register %s, mode = %s: ",
14898 rs6000_reg_names
[REGNO (scratch
)],
14899 GET_MODE_NAME (mode
));
14900 debug_rtx (addr_op2
);
14902 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14903 addr_op2
= scratch
;
14906 emit_insn (gen_rtx_SET (VOIDmode
,
14907 scratch_or_premodify
,
14908 gen_rtx_PLUS (Pmode
,
14912 addr
= scratch_or_premodify
;
14913 scratch_or_premodify
= scratch
;
14915 else if (!legitimate_indirect_address_p (addr
, false)
14916 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14918 if (TARGET_DEBUG_ADDR
)
14920 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
14921 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
14922 GET_MODE_NAME (mode
));
14925 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14926 addr
= scratch_or_premodify
;
14927 scratch_or_premodify
= scratch
;
14931 /* Float/Altivec registers can only handle reg+reg addressing. Move
14932 other addresses into a scratch register. */
14937 /* With float regs, we need to handle the AND ourselves, since we can't
14938 use the Altivec instruction with an implicit AND -16. Allow scalar
14939 loads to float registers to use reg+offset even if VSX. */
14940 if (GET_CODE (addr
) == AND
14941 && (rclass
!= ALTIVEC_REGS
|| GET_MODE_SIZE (mode
) != 16
14942 || GET_CODE (XEXP (addr
, 1)) != CONST_INT
14943 || INTVAL (XEXP (addr
, 1)) != -16
14944 || !VECTOR_MEM_ALTIVEC_P (mode
)))
14946 and_op2
= XEXP (addr
, 1);
14947 addr
= XEXP (addr
, 0);
14950 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14951 as the address later. */
14952 if (GET_CODE (addr
) == PRE_MODIFY
14953 && (!VECTOR_MEM_VSX_P (mode
)
14954 || and_op2
!= NULL_RTX
14955 || !legitimate_indexed_address_p (XEXP (addr
, 1), false)))
14957 scratch_or_premodify
= XEXP (addr
, 0);
14958 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify
,
14960 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14961 addr
= XEXP (addr
, 1);
14964 if (legitimate_indirect_address_p (addr
, false) /* reg */
14965 || legitimate_indexed_address_p (addr
, false) /* reg+reg */
14966 || GET_CODE (addr
) == PRE_MODIFY
/* VSX pre-modify */
14967 || (GET_CODE (addr
) == AND
/* Altivec memory */
14968 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14969 && INTVAL (XEXP (addr
, 1)) == -16
14970 && VECTOR_MEM_ALTIVEC_P (mode
))
14971 || (rclass
== FLOAT_REGS
/* legacy float mem */
14972 && GET_MODE_SIZE (mode
) == 8
14973 && and_op2
== NULL_RTX
14974 && scratch_or_premodify
== scratch
14975 && rs6000_legitimate_offset_address_p (mode
, addr
, false)))
14978 else if (GET_CODE (addr
) == PLUS
)
14980 addr_op1
= XEXP (addr
, 0);
14981 addr_op2
= XEXP (addr
, 1);
14982 gcc_assert (REG_P (addr_op1
));
14984 if (TARGET_DEBUG_ADDR
)
14986 fprintf (stderr
, "\nMove plus addr to register %s, mode = %s: ",
14987 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
14988 debug_rtx (addr_op2
);
14990 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14991 emit_insn (gen_rtx_SET (VOIDmode
,
14992 scratch_or_premodify
,
14993 gen_rtx_PLUS (Pmode
,
14996 addr
= scratch_or_premodify
;
14997 scratch_or_premodify
= scratch
;
15000 else if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == CONST
15001 || GET_CODE (addr
) == CONST_INT
|| REG_P (addr
))
15003 if (TARGET_DEBUG_ADDR
)
15005 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
15006 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
15007 GET_MODE_NAME (mode
));
15011 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
15012 addr
= scratch_or_premodify
;
15013 scratch_or_premodify
= scratch
;
15017 gcc_unreachable ();
15022 gcc_unreachable ();
15025 /* If the original address involved a pre-modify that we couldn't use the VSX
15026 memory instruction with update, and we haven't taken care of already,
15027 store the address in the pre-modify register and use that as the
15029 if (scratch_or_premodify
!= scratch
&& scratch_or_premodify
!= addr
)
15031 emit_insn (gen_rtx_SET (VOIDmode
, scratch_or_premodify
, addr
));
15032 addr
= scratch_or_premodify
;
15035 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15036 memory instruction, recreate the AND now, including the clobber which is
15037 generated by the general ANDSI3/ANDDI3 patterns for the
15038 andi. instruction. */
15039 if (and_op2
!= NULL_RTX
)
15041 if (! legitimate_indirect_address_p (addr
, false))
15043 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, addr
));
15047 if (TARGET_DEBUG_ADDR
)
15049 fprintf (stderr
, "\nAnd addr to register %s, mode = %s: ",
15050 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
15051 debug_rtx (and_op2
);
15054 and_rtx
= gen_rtx_SET (VOIDmode
,
15056 gen_rtx_AND (Pmode
,
15060 cc_clobber
= gen_rtx_CLOBBER (CCmode
, gen_rtx_SCRATCH (CCmode
));
15061 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
15062 gen_rtvec (2, and_rtx
, cc_clobber
)));
15066 /* Adjust the address if it changed. */
15067 if (addr
!= XEXP (mem
, 0))
15069 mem
= change_address (mem
, mode
, addr
);
15070 if (TARGET_DEBUG_ADDR
)
15071 fprintf (stderr
, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15074 /* Now create the move. */
15076 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
15078 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
15083 /* Convert reloads involving 64-bit gprs and misaligned offset
15084 addressing to use indirect addressing. */
15087 rs6000_secondary_reload_ppc64 (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
15089 int regno
= true_regnum (reg
);
15090 enum reg_class rclass
;
15092 rtx scratch_or_premodify
= scratch
;
15094 if (TARGET_DEBUG_ADDR
)
15096 fprintf (stderr
, "\nrs6000_secondary_reload_ppc64, type = %s\n",
15097 store_p
? "store" : "load");
15098 fprintf (stderr
, "reg:\n");
15100 fprintf (stderr
, "mem:\n");
15102 fprintf (stderr
, "scratch:\n");
15103 debug_rtx (scratch
);
15106 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
15107 gcc_assert (GET_CODE (mem
) == MEM
);
15108 rclass
= REGNO_REG_CLASS (regno
);
15109 gcc_assert (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
);
15110 addr
= XEXP (mem
, 0);
15112 if (GET_CODE (addr
) == PRE_MODIFY
)
15114 scratch_or_premodify
= XEXP (addr
, 0);
15115 gcc_assert (REG_P (scratch_or_premodify
));
15116 addr
= XEXP (addr
, 1);
15118 gcc_assert (GET_CODE (addr
) == PLUS
|| GET_CODE (addr
) == LO_SUM
);
15120 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
15122 mem
= replace_equiv_address_nv (mem
, scratch_or_premodify
);
15124 /* Now create the move. */
15126 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
15128 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
15133 /* Allocate a 64-bit stack slot to be used for copying SDmode
15134 values through if this function has any SDmode references. */
15137 rs6000_alloc_sdmode_stack_slot (void)
15141 gimple_stmt_iterator gsi
;
15143 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
15146 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
15148 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
15151 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
15152 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
15158 /* Check for any SDmode parameters of the function. */
15159 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= DECL_CHAIN (t
))
15161 if (TREE_TYPE (t
) == error_mark_node
)
15164 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
15165 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
15167 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
15168 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
15176 rs6000_instantiate_decls (void)
15178 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
15179 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
15182 /* Given an rtx X being reloaded into a reg required to be
15183 in class CLASS, return the class of reg to actually use.
15184 In general this is just CLASS; but on some machines
15185 in some cases it is preferable to use a more restrictive class.
15187 On the RS/6000, we have to return NO_REGS when we want to reload a
15188 floating-point CONST_DOUBLE to force it to be copied to memory.
15190 We also don't want to reload integer values into floating-point
15191 registers if we can at all help it. In fact, this can
15192 cause reload to die, if it tries to generate a reload of CTR
15193 into a FP register and discovers it doesn't have the memory location
15196 ??? Would it be a good idea to have reload do the converse, that is
15197 try to reload floating modes into FP registers if possible?
15200 static enum reg_class
15201 rs6000_preferred_reload_class (rtx x
, enum reg_class rclass
)
15203 enum machine_mode mode
= GET_MODE (x
);
15205 if (VECTOR_UNIT_VSX_P (mode
)
15206 && x
== CONST0_RTX (mode
) && VSX_REG_CLASS_P (rclass
))
15209 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
15210 && (rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
15211 && easy_vector_constant (x
, mode
))
15212 return ALTIVEC_REGS
;
15214 if (CONSTANT_P (x
) && reg_classes_intersect_p (rclass
, FLOAT_REGS
))
15217 if (GET_MODE_CLASS (mode
) == MODE_INT
&& rclass
== NON_SPECIAL_REGS
)
15218 return GENERAL_REGS
;
15220 /* For VSX, prefer the traditional registers for 64-bit values because we can
15221 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15222 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15223 prefer Altivec loads.. */
15224 if (rclass
== VSX_REGS
)
15226 if (GET_MODE_SIZE (mode
) <= 8)
15229 if (VECTOR_UNIT_ALTIVEC_P (mode
) || VECTOR_MEM_ALTIVEC_P (mode
))
15230 return ALTIVEC_REGS
;
15238 /* Debug version of rs6000_preferred_reload_class. */
15239 static enum reg_class
15240 rs6000_debug_preferred_reload_class (rtx x
, enum reg_class rclass
)
15242 enum reg_class ret
= rs6000_preferred_reload_class (x
, rclass
);
15245 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15247 reg_class_names
[ret
], reg_class_names
[rclass
],
15248 GET_MODE_NAME (GET_MODE (x
)));
15254 /* If we are copying between FP or AltiVec registers and anything else, we need
15255 a memory location. The exception is when we are targeting ppc64 and the
15256 move to/from fpr to gpr instructions are available. Also, under VSX, you
15257 can copy vector registers from the FP register set to the Altivec register
15258 set and vice versa. */
15261 rs6000_secondary_memory_needed (enum reg_class class1
,
15262 enum reg_class class2
,
15263 enum machine_mode mode
)
15265 if (class1
== class2
)
15268 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15269 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15270 between these classes. But we need memory for other things that can go in
15271 FLOAT_REGS like SFmode. */
15273 && (VECTOR_MEM_VSX_P (mode
) || VECTOR_UNIT_VSX_P (mode
))
15274 && (class1
== VSX_REGS
|| class1
== ALTIVEC_REGS
15275 || class1
== FLOAT_REGS
))
15276 return (class2
!= VSX_REGS
&& class2
!= ALTIVEC_REGS
15277 && class2
!= FLOAT_REGS
);
15279 if (class1
== VSX_REGS
|| class2
== VSX_REGS
)
15282 if (class1
== FLOAT_REGS
15283 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
15284 || ((mode
!= DFmode
)
15285 && (mode
!= DDmode
)
15286 && (mode
!= DImode
))))
15289 if (class2
== FLOAT_REGS
15290 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
15291 || ((mode
!= DFmode
)
15292 && (mode
!= DDmode
)
15293 && (mode
!= DImode
))))
15296 if (class1
== ALTIVEC_REGS
|| class2
== ALTIVEC_REGS
)
15302 /* Debug version of rs6000_secondary_memory_needed. */
15304 rs6000_debug_secondary_memory_needed (enum reg_class class1
,
15305 enum reg_class class2
,
15306 enum machine_mode mode
)
15308 bool ret
= rs6000_secondary_memory_needed (class1
, class2
, mode
);
15311 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15312 "class2 = %s, mode = %s\n",
15313 ret
? "true" : "false", reg_class_names
[class1
],
15314 reg_class_names
[class2
], GET_MODE_NAME (mode
));
15319 /* Return the register class of a scratch register needed to copy IN into
15320 or out of a register in RCLASS in MODE. If it can be done directly,
15321 NO_REGS is returned. */
15323 static enum reg_class
15324 rs6000_secondary_reload_class (enum reg_class rclass
, enum machine_mode mode
,
15329 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
15331 && MACHOPIC_INDIRECT
15335 /* We cannot copy a symbolic operand directly into anything
15336 other than BASE_REGS for TARGET_ELF. So indicate that a
15337 register from BASE_REGS is needed as an intermediate
15340 On Darwin, pic addresses require a load from memory, which
15341 needs a base register. */
15342 if (rclass
!= BASE_REGS
15343 && (GET_CODE (in
) == SYMBOL_REF
15344 || GET_CODE (in
) == HIGH
15345 || GET_CODE (in
) == LABEL_REF
15346 || GET_CODE (in
) == CONST
))
15350 if (GET_CODE (in
) == REG
)
15352 regno
= REGNO (in
);
15353 if (regno
>= FIRST_PSEUDO_REGISTER
)
15355 regno
= true_regnum (in
);
15356 if (regno
>= FIRST_PSEUDO_REGISTER
)
15360 else if (GET_CODE (in
) == SUBREG
)
15362 regno
= true_regnum (in
);
15363 if (regno
>= FIRST_PSEUDO_REGISTER
)
15369 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15371 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
15372 || (regno
>= 0 && INT_REGNO_P (regno
)))
15375 /* Constants, memory, and FP registers can go into FP registers. */
15376 if ((regno
== -1 || FP_REGNO_P (regno
))
15377 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
15378 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
15380 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15383 && (regno
== -1 || VSX_REGNO_P (regno
))
15384 && VSX_REG_CLASS_P (rclass
))
15387 /* Memory, and AltiVec registers can go into AltiVec registers. */
15388 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
15389 && rclass
== ALTIVEC_REGS
)
15392 /* We can copy among the CR registers. */
15393 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
15394 && regno
>= 0 && CR_REGNO_P (regno
))
15397 /* Otherwise, we need GENERAL_REGS. */
15398 return GENERAL_REGS
;
15401 /* Debug version of rs6000_secondary_reload_class. */
15402 static enum reg_class
15403 rs6000_debug_secondary_reload_class (enum reg_class rclass
,
15404 enum machine_mode mode
, rtx in
)
15406 enum reg_class ret
= rs6000_secondary_reload_class (rclass
, mode
, in
);
15408 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15409 "mode = %s, input rtx:\n",
15410 reg_class_names
[ret
], reg_class_names
[rclass
],
15411 GET_MODE_NAME (mode
));
15417 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15420 rs6000_cannot_change_mode_class (enum machine_mode from
,
15421 enum machine_mode to
,
15422 enum reg_class rclass
)
15424 unsigned from_size
= GET_MODE_SIZE (from
);
15425 unsigned to_size
= GET_MODE_SIZE (to
);
15427 if (from_size
!= to_size
)
15429 enum reg_class xclass
= (TARGET_VSX
) ? VSX_REGS
: FLOAT_REGS
;
15430 return ((from_size
< 8 || to_size
< 8 || TARGET_IEEEQUAD
)
15431 && reg_classes_intersect_p (xclass
, rclass
));
15434 if (TARGET_E500_DOUBLE
15435 && ((((to
) == DFmode
) + ((from
) == DFmode
)) == 1
15436 || (((to
) == TFmode
) + ((from
) == TFmode
)) == 1
15437 || (((to
) == DDmode
) + ((from
) == DDmode
)) == 1
15438 || (((to
) == TDmode
) + ((from
) == TDmode
)) == 1
15439 || (((to
) == DImode
) + ((from
) == DImode
)) == 1))
15442 /* Since the VSX register set includes traditional floating point registers
15443 and altivec registers, just check for the size being different instead of
15444 trying to check whether the modes are vector modes. Otherwise it won't
15445 allow say DF and DI to change classes. */
15446 if (TARGET_VSX
&& VSX_REG_CLASS_P (rclass
))
15447 return (from_size
!= 8 && from_size
!= 16);
15449 if (TARGET_ALTIVEC
&& rclass
== ALTIVEC_REGS
15450 && (ALTIVEC_VECTOR_MODE (from
) + ALTIVEC_VECTOR_MODE (to
)) == 1)
15453 if (TARGET_SPE
&& (SPE_VECTOR_MODE (from
) + SPE_VECTOR_MODE (to
)) == 1
15454 && reg_classes_intersect_p (GENERAL_REGS
, rclass
))
15460 /* Debug version of rs6000_cannot_change_mode_class. */
15462 rs6000_debug_cannot_change_mode_class (enum machine_mode from
,
15463 enum machine_mode to
,
15464 enum reg_class rclass
)
15466 bool ret
= rs6000_cannot_change_mode_class (from
, to
, rclass
);
15469 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15470 "to = %s, rclass = %s\n",
15471 ret
? "true" : "false",
15472 GET_MODE_NAME (from
), GET_MODE_NAME (to
),
15473 reg_class_names
[rclass
]);
15478 /* Given a comparison operation, return the bit number in CCR to test. We
15479 know this is a valid comparison.
15481 SCC_P is 1 if this is for an scc. That means that %D will have been
15482 used instead of %C, so the bits will be in different places.
15484 Return -1 if OP isn't a valid comparison for some reason. */
15487 ccr_bit (rtx op
, int scc_p
)
15489 enum rtx_code code
= GET_CODE (op
);
15490 enum machine_mode cc_mode
;
15495 if (!COMPARISON_P (op
))
15498 reg
= XEXP (op
, 0);
15500 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
15502 cc_mode
= GET_MODE (reg
);
15503 cc_regnum
= REGNO (reg
);
15504 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
15506 validate_condition_mode (code
, cc_mode
);
15508 /* When generating a sCOND operation, only positive conditions are
15511 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
15512 || code
== GTU
|| code
== LTU
);
15517 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
15519 return base_bit
+ 2;
15520 case GT
: case GTU
: case UNLE
:
15521 return base_bit
+ 1;
15522 case LT
: case LTU
: case UNGE
:
15524 case ORDERED
: case UNORDERED
:
15525 return base_bit
+ 3;
15528 /* If scc, we will have done a cror to put the bit in the
15529 unordered position. So test that bit. For integer, this is ! LT
15530 unless this is an scc insn. */
15531 return scc_p
? base_bit
+ 3 : base_bit
;
15534 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
15537 gcc_unreachable ();
15541 /* Return the GOT register. */
15544 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
15546 /* The second flow pass currently (June 1999) can't update
15547 regs_ever_live without disturbing other parts of the compiler, so
15548 update it here to make the prolog/epilogue code happy. */
15549 if (!can_create_pseudo_p ()
15550 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
15551 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
15553 crtl
->uses_pic_offset_table
= 1;
15555 return pic_offset_table_rtx
;
15558 static rs6000_stack_t stack_info
;
15560 /* Function to init struct machine_function.
15561 This will be called, via a pointer variable,
15562 from push_function_context. */
15564 static struct machine_function
*
15565 rs6000_init_machine_status (void)
15567 stack_info
.reload_completed
= 0;
15568 return ggc_alloc_cleared_machine_function ();
15571 /* These macros test for integers and extract the low-order bits. */
15573 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15574 && GET_MODE (X) == VOIDmode)
15576 #define INT_LOWPART(X) \
15577 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15580 extract_MB (rtx op
)
15583 unsigned long val
= INT_LOWPART (op
);
15585 /* If the high bit is zero, the value is the first 1 bit we find
15587 if ((val
& 0x80000000) == 0)
15589 gcc_assert (val
& 0xffffffff);
15592 while (((val
<<= 1) & 0x80000000) == 0)
15597 /* If the high bit is set and the low bit is not, or the mask is all
15598 1's, the value is zero. */
15599 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
15602 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15605 while (((val
>>= 1) & 1) != 0)
15612 extract_ME (rtx op
)
15615 unsigned long val
= INT_LOWPART (op
);
15617 /* If the low bit is zero, the value is the first 1 bit we find from
15619 if ((val
& 1) == 0)
15621 gcc_assert (val
& 0xffffffff);
15624 while (((val
>>= 1) & 1) == 0)
15630 /* If the low bit is set and the high bit is not, or the mask is all
15631 1's, the value is 31. */
15632 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
15635 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15638 while (((val
<<= 1) & 0x80000000) != 0)
15644 /* Locate some local-dynamic symbol still in use by this function
15645 so that we can print its name in some tls_ld pattern. */
15647 static const char *
15648 rs6000_get_some_local_dynamic_name (void)
15652 if (cfun
->machine
->some_ld_name
)
15653 return cfun
->machine
->some_ld_name
;
15655 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15657 && for_each_rtx (&PATTERN (insn
),
15658 rs6000_get_some_local_dynamic_name_1
, 0))
15659 return cfun
->machine
->some_ld_name
;
15661 gcc_unreachable ();
15664 /* Helper function for rs6000_get_some_local_dynamic_name. */
15667 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
15671 if (GET_CODE (x
) == SYMBOL_REF
)
15673 const char *str
= XSTR (x
, 0);
15674 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
15676 cfun
->machine
->some_ld_name
= str
;
15684 /* Write out a function code label. */
15687 rs6000_output_function_entry (FILE *file
, const char *fname
)
15689 if (fname
[0] != '.')
15691 switch (DEFAULT_ABI
)
15694 gcc_unreachable ();
15700 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
15709 RS6000_OUTPUT_BASENAME (file
, fname
);
15712 /* Print an operand. Recognize special options, documented below. */
15715 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15716 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15718 #define SMALL_DATA_RELOC "sda21"
15719 #define SMALL_DATA_REG 0
15723 print_operand (FILE *file
, rtx x
, int code
)
15727 unsigned HOST_WIDE_INT uval
;
15732 /* Write out an instruction after the call which may be replaced
15733 with glue code by the loader. This depends on the AIX version. */
15734 asm_fprintf (file
, RS6000_CALL_GLUE
);
15737 /* %a is output_address. */
15740 /* If X is a constant integer whose low-order 5 bits are zero,
15741 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15742 in the AIX assembler where "sri" with a zero shift count
15743 writes a trash instruction. */
15744 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
15751 /* If constant, low-order 16 bits of constant, unsigned.
15752 Otherwise, write normally. */
15754 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
15756 print_operand (file
, x
, 0);
15760 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15761 for 64-bit mask direction. */
15762 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
15765 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15769 /* X is a CR register. Print the number of the GT bit of the CR. */
15770 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15771 output_operand_lossage ("invalid %%c value");
15773 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
15777 /* Like 'J' but get to the GT bit only. */
15778 gcc_assert (GET_CODE (x
) == REG
);
15780 /* Bit 1 is GT bit. */
15781 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
15783 /* Add one for shift count in rlinm for scc. */
15784 fprintf (file
, "%d", i
+ 1);
15788 /* X is a CR register. Print the number of the EQ bit of the CR */
15789 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15790 output_operand_lossage ("invalid %%E value");
15792 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
15796 /* X is a CR register. Print the shift count needed to move it
15797 to the high-order four bits. */
15798 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15799 output_operand_lossage ("invalid %%f value");
15801 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
15805 /* Similar, but print the count for the rotate in the opposite
15807 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15808 output_operand_lossage ("invalid %%F value");
15810 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
15814 /* X is a constant integer. If it is negative, print "m",
15815 otherwise print "z". This is to make an aze or ame insn. */
15816 if (GET_CODE (x
) != CONST_INT
)
15817 output_operand_lossage ("invalid %%G value");
15818 else if (INTVAL (x
) >= 0)
15825 /* If constant, output low-order five bits. Otherwise, write
15828 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
15830 print_operand (file
, x
, 0);
15834 /* If constant, output low-order six bits. Otherwise, write
15837 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
15839 print_operand (file
, x
, 0);
15843 /* Print `i' if this is a constant, else nothing. */
15849 /* Write the bit number in CCR for jump. */
15850 i
= ccr_bit (x
, 0);
15852 output_operand_lossage ("invalid %%j code");
15854 fprintf (file
, "%d", i
);
15858 /* Similar, but add one for shift count in rlinm for scc and pass
15859 scc flag to `ccr_bit'. */
15860 i
= ccr_bit (x
, 1);
15862 output_operand_lossage ("invalid %%J code");
15864 /* If we want bit 31, write a shift count of zero, not 32. */
15865 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15869 /* X must be a constant. Write the 1's complement of the
15872 output_operand_lossage ("invalid %%k value");
15874 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
15878 /* X must be a symbolic constant on ELF. Write an
15879 expression suitable for an 'addi' that adds in the low 16
15880 bits of the MEM. */
15881 if (GET_CODE (x
) == CONST
)
15883 if (GET_CODE (XEXP (x
, 0)) != PLUS
15884 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
15885 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
15886 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
15887 output_operand_lossage ("invalid %%K value");
15889 print_operand_address (file
, x
);
15890 fputs ("@l", file
);
15893 /* %l is output_asm_label. */
15896 /* Write second word of DImode or DFmode reference. Works on register
15897 or non-indexed memory only. */
15898 if (GET_CODE (x
) == REG
)
15899 fputs (reg_names
[REGNO (x
) + 1], file
);
15900 else if (GET_CODE (x
) == MEM
)
15902 /* Handle possible auto-increment. Since it is pre-increment and
15903 we have already done it, we can just use an offset of word. */
15904 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15905 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15906 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15908 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15909 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15912 output_address (XEXP (adjust_address_nv (x
, SImode
,
15916 if (small_data_operand (x
, GET_MODE (x
)))
15917 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15918 reg_names
[SMALL_DATA_REG
]);
15923 /* MB value for a mask operand. */
15924 if (! mask_operand (x
, SImode
))
15925 output_operand_lossage ("invalid %%m value");
15927 fprintf (file
, "%d", extract_MB (x
));
15931 /* ME value for a mask operand. */
15932 if (! mask_operand (x
, SImode
))
15933 output_operand_lossage ("invalid %%M value");
15935 fprintf (file
, "%d", extract_ME (x
));
15938 /* %n outputs the negative of its operand. */
15941 /* Write the number of elements in the vector times 4. */
15942 if (GET_CODE (x
) != PARALLEL
)
15943 output_operand_lossage ("invalid %%N value");
15945 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
15949 /* Similar, but subtract 1 first. */
15950 if (GET_CODE (x
) != PARALLEL
)
15951 output_operand_lossage ("invalid %%O value");
15953 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
15957 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15959 || INT_LOWPART (x
) < 0
15960 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
15961 output_operand_lossage ("invalid %%p value");
15963 fprintf (file
, "%d", i
);
15967 /* The operand must be an indirect memory reference. The result
15968 is the register name. */
15969 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
15970 || REGNO (XEXP (x
, 0)) >= 32)
15971 output_operand_lossage ("invalid %%P value");
15973 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
15977 /* This outputs the logical code corresponding to a boolean
15978 expression. The expression may have one or both operands
15979 negated (if one, only the first one). For condition register
15980 logical operations, it will also treat the negated
15981 CR codes as NOTs, but not handle NOTs of them. */
15983 const char *const *t
= 0;
15985 enum rtx_code code
= GET_CODE (x
);
15986 static const char * const tbl
[3][3] = {
15987 { "and", "andc", "nor" },
15988 { "or", "orc", "nand" },
15989 { "xor", "eqv", "xor" } };
15993 else if (code
== IOR
)
15995 else if (code
== XOR
)
15998 output_operand_lossage ("invalid %%q value");
16000 if (GET_CODE (XEXP (x
, 0)) != NOT
)
16004 if (GET_CODE (XEXP (x
, 1)) == NOT
)
16022 /* X is a CR register. Print the mask for `mtcrf'. */
16023 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
16024 output_operand_lossage ("invalid %%R value");
16026 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
16030 /* Low 5 bits of 32 - value */
16032 output_operand_lossage ("invalid %%s value");
16034 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
16038 /* PowerPC64 mask position. All 0's is excluded.
16039 CONST_INT 32-bit mask is considered sign-extended so any
16040 transition must occur within the CONST_INT, not on the boundary. */
16041 if (! mask64_operand (x
, DImode
))
16042 output_operand_lossage ("invalid %%S value");
16044 uval
= INT_LOWPART (x
);
16046 if (uval
& 1) /* Clear Left */
16048 #if HOST_BITS_PER_WIDE_INT > 64
16049 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
16053 else /* Clear Right */
16056 #if HOST_BITS_PER_WIDE_INT > 64
16057 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
16063 gcc_assert (i
>= 0);
16064 fprintf (file
, "%d", i
);
16068 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16069 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
16071 /* Bit 3 is OV bit. */
16072 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
16074 /* If we want bit 31, write a shift count of zero, not 32. */
16075 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
16079 /* Print the symbolic name of a branch target register. */
16080 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
16081 && REGNO (x
) != CTR_REGNO
))
16082 output_operand_lossage ("invalid %%T value");
16083 else if (REGNO (x
) == LR_REGNO
)
16084 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
16086 fputs ("ctr", file
);
16090 /* High-order 16 bits of constant for use in unsigned operand. */
16092 output_operand_lossage ("invalid %%u value");
16094 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
16095 (INT_LOWPART (x
) >> 16) & 0xffff);
16099 /* High-order 16 bits of constant for use in signed operand. */
16101 output_operand_lossage ("invalid %%v value");
16103 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
16104 (INT_LOWPART (x
) >> 16) & 0xffff);
16108 /* Print `u' if this has an auto-increment or auto-decrement. */
16109 if (GET_CODE (x
) == MEM
16110 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
16111 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
16112 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
16117 /* Print the trap code for this operand. */
16118 switch (GET_CODE (x
))
16121 fputs ("eq", file
); /* 4 */
16124 fputs ("ne", file
); /* 24 */
16127 fputs ("lt", file
); /* 16 */
16130 fputs ("le", file
); /* 20 */
16133 fputs ("gt", file
); /* 8 */
16136 fputs ("ge", file
); /* 12 */
16139 fputs ("llt", file
); /* 2 */
16142 fputs ("lle", file
); /* 6 */
16145 fputs ("lgt", file
); /* 1 */
16148 fputs ("lge", file
); /* 5 */
16151 gcc_unreachable ();
16156 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16159 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
16160 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
16162 print_operand (file
, x
, 0);
16166 /* MB value for a PowerPC64 rldic operand. */
16167 val
= (GET_CODE (x
) == CONST_INT
16168 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
16173 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
16174 if ((val
<<= 1) < 0)
16177 #if HOST_BITS_PER_WIDE_INT == 32
16178 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
16179 i
+= 32; /* zero-extend high-part was all 0's */
16180 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
16182 val
= CONST_DOUBLE_LOW (x
);
16188 for ( ; i
< 64; i
++)
16189 if ((val
<<= 1) < 0)
16194 fprintf (file
, "%d", i
+ 1);
16198 /* X is a FPR or Altivec register used in a VSX context. */
16199 if (GET_CODE (x
) != REG
|| !VSX_REGNO_P (REGNO (x
)))
16200 output_operand_lossage ("invalid %%x value");
16203 int reg
= REGNO (x
);
16204 int vsx_reg
= (FP_REGNO_P (reg
)
16206 : reg
- FIRST_ALTIVEC_REGNO
+ 32);
16208 #ifdef TARGET_REGNAMES
16209 if (TARGET_REGNAMES
)
16210 fprintf (file
, "%%vs%d", vsx_reg
);
16213 fprintf (file
, "%d", vsx_reg
);
16218 if (GET_CODE (x
) == MEM
16219 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
16220 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
16221 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
16226 /* Like 'L', for third word of TImode */
16227 if (GET_CODE (x
) == REG
)
16228 fputs (reg_names
[REGNO (x
) + 2], file
);
16229 else if (GET_CODE (x
) == MEM
)
16231 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16232 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16233 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
16234 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16235 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
16237 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
16238 if (small_data_operand (x
, GET_MODE (x
)))
16239 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16240 reg_names
[SMALL_DATA_REG
]);
16245 /* X is a SYMBOL_REF. Write out the name preceded by a
16246 period and without any trailing data in brackets. Used for function
16247 names. If we are configured for System V (or the embedded ABI) on
16248 the PowerPC, do not emit the period, since those systems do not use
16249 TOCs and the like. */
16250 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
16252 /* Mark the decl as referenced so that cgraph will output the
16254 if (SYMBOL_REF_DECL (x
))
16255 mark_decl_referenced (SYMBOL_REF_DECL (x
));
16257 /* For macho, check to see if we need a stub. */
16260 const char *name
= XSTR (x
, 0);
16262 if (darwin_emit_branch_islands
16263 && MACHOPIC_INDIRECT
16264 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
16265 name
= machopic_indirection_name (x
, /*stub_p=*/true);
16267 assemble_name (file
, name
);
16269 else if (!DOT_SYMBOLS
)
16270 assemble_name (file
, XSTR (x
, 0));
16272 rs6000_output_function_entry (file
, XSTR (x
, 0));
16276 /* Like 'L', for last word of TImode. */
16277 if (GET_CODE (x
) == REG
)
16278 fputs (reg_names
[REGNO (x
) + 3], file
);
16279 else if (GET_CODE (x
) == MEM
)
16281 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16282 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16283 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
16284 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16285 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
16287 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
16288 if (small_data_operand (x
, GET_MODE (x
)))
16289 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16290 reg_names
[SMALL_DATA_REG
]);
16294 /* Print AltiVec or SPE memory operand. */
16299 gcc_assert (GET_CODE (x
) == MEM
);
16303 /* Ugly hack because %y is overloaded. */
16304 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
16305 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
16306 || GET_MODE (x
) == TFmode
16307 || GET_MODE (x
) == TImode
))
16309 /* Handle [reg]. */
16310 if (GET_CODE (tmp
) == REG
)
16312 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
16315 /* Handle [reg+UIMM]. */
16316 else if (GET_CODE (tmp
) == PLUS
&&
16317 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
16321 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
16323 x
= INTVAL (XEXP (tmp
, 1));
16324 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
16328 /* Fall through. Must be [reg+reg]. */
16330 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x
))
16331 && GET_CODE (tmp
) == AND
16332 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
16333 && INTVAL (XEXP (tmp
, 1)) == -16)
16334 tmp
= XEXP (tmp
, 0);
16335 else if (VECTOR_MEM_VSX_P (GET_MODE (x
))
16336 && GET_CODE (tmp
) == PRE_MODIFY
)
16337 tmp
= XEXP (tmp
, 1);
16338 if (GET_CODE (tmp
) == REG
)
16339 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
16342 if (!GET_CODE (tmp
) == PLUS
16343 || !REG_P (XEXP (tmp
, 0))
16344 || !REG_P (XEXP (tmp
, 1)))
16346 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16350 if (REGNO (XEXP (tmp
, 0)) == 0)
16351 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
16352 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
16354 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
16355 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
16361 if (GET_CODE (x
) == REG
)
16362 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
16363 else if (GET_CODE (x
) == MEM
)
16365 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16366 know the width from the mode. */
16367 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
16368 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
16369 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
16370 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16371 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
16372 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
16373 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16374 output_address (XEXP (XEXP (x
, 0), 1));
16376 output_address (XEXP (x
, 0));
16380 if (toc_relative_expr_p (x
))
16381 /* This hack along with a corresponding hack in
16382 rs6000_output_addr_const_extra arranges to output addends
16383 where the assembler expects to find them. eg.
16384 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16385 without this hack would be output as "x@toc+4". We
16387 output_addr_const (file
, tocrel_base
);
16389 output_addr_const (file
, x
);
16394 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
16398 output_operand_lossage ("invalid %%xn code");
16402 /* Print the address of an operand. */
16405 print_operand_address (FILE *file
, rtx x
)
16407 if (GET_CODE (x
) == REG
)
16408 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
16409 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
16410 || GET_CODE (x
) == LABEL_REF
)
16412 output_addr_const (file
, x
);
16413 if (small_data_operand (x
, GET_MODE (x
)))
16414 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16415 reg_names
[SMALL_DATA_REG
]);
16417 gcc_assert (!TARGET_TOC
);
16419 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
16421 gcc_assert (REG_P (XEXP (x
, 0)));
16422 if (REGNO (XEXP (x
, 0)) == 0)
16423 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
16424 reg_names
[ REGNO (XEXP (x
, 0)) ]);
16426 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
16427 reg_names
[ REGNO (XEXP (x
, 1)) ]);
16429 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
16430 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
16431 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
16433 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16434 && CONSTANT_P (XEXP (x
, 1)))
16436 fprintf (file
, "lo16(");
16437 output_addr_const (file
, XEXP (x
, 1));
16438 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16441 else if (legitimate_constant_pool_address_p (x
, QImode
, true))
16443 /* This hack along with a corresponding hack in
16444 rs6000_output_addr_const_extra arranges to output addends
16445 where the assembler expects to find them. eg.
16447 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16448 without this hack would be output as "x@toc+8@l(9)". We
16449 want "x+8@toc@l(9)". */
16450 output_addr_const (file
, tocrel_base
);
16451 if (GET_CODE (x
) == LO_SUM
)
16452 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16454 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
16457 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16458 && CONSTANT_P (XEXP (x
, 1)))
16460 output_addr_const (file
, XEXP (x
, 1));
16461 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16465 gcc_unreachable ();
16468 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16471 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
16473 if (GET_CODE (x
) == UNSPEC
)
16474 switch (XINT (x
, 1))
16476 case UNSPEC_TOCREL
:
16477 gcc_assert (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
);
16478 output_addr_const (file
, XVECEXP (x
, 0, 0));
16479 if (x
== tocrel_base
&& tocrel_offset
!= const0_rtx
)
16481 if (INTVAL (tocrel_offset
) >= 0)
16482 fprintf (file
, "+");
16483 output_addr_const (file
, tocrel_offset
);
16485 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
16488 assemble_name (file
, toc_label_name
);
16490 else if (TARGET_ELF
)
16491 fputs ("@toc", file
);
16495 case UNSPEC_MACHOPIC_OFFSET
:
16496 output_addr_const (file
, XVECEXP (x
, 0, 0));
16498 machopic_output_function_base_name (file
);
16505 /* Target hook for assembling integer objects. The PowerPC version has
16506 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16507 is defined. It also needs to handle DI-mode objects on 64-bit
16511 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
16513 #ifdef RELOCATABLE_NEEDS_FIXUP
16514 /* Special handling for SI values. */
16515 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
16517 static int recurse
= 0;
16519 /* For -mrelocatable, we mark all addresses that need to be fixed up
16520 in the .fixup section. */
16521 if (TARGET_RELOCATABLE
16522 && in_section
!= toc_section
16523 && in_section
!= text_section
16524 && !unlikely_text_section_p (in_section
)
16526 && GET_CODE (x
) != CONST_INT
16527 && GET_CODE (x
) != CONST_DOUBLE
16533 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
16535 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
16536 fprintf (asm_out_file
, "\t.long\t(");
16537 output_addr_const (asm_out_file
, x
);
16538 fprintf (asm_out_file
, ")@fixup\n");
16539 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
16540 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
16541 fprintf (asm_out_file
, "\t.long\t");
16542 assemble_name (asm_out_file
, buf
);
16543 fprintf (asm_out_file
, "\n\t.previous\n");
16547 /* Remove initial .'s to turn a -mcall-aixdesc function
16548 address into the address of the descriptor, not the function
16550 else if (GET_CODE (x
) == SYMBOL_REF
16551 && XSTR (x
, 0)[0] == '.'
16552 && DEFAULT_ABI
== ABI_AIX
)
16554 const char *name
= XSTR (x
, 0);
16555 while (*name
== '.')
16558 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
16562 #endif /* RELOCATABLE_NEEDS_FIXUP */
16563 return default_assemble_integer (x
, size
, aligned_p
);
16566 #ifdef HAVE_GAS_HIDDEN
16567 /* Emit an assembler directive to set symbol visibility for DECL to
16568 VISIBILITY_TYPE. */
16571 rs6000_assemble_visibility (tree decl
, int vis
)
16573 /* Functions need to have their entry point symbol visibility set as
16574 well as their descriptor symbol visibility. */
16575 if (DEFAULT_ABI
== ABI_AIX
16577 && TREE_CODE (decl
) == FUNCTION_DECL
)
16579 static const char * const visibility_types
[] = {
16580 NULL
, "internal", "hidden", "protected"
16583 const char *name
, *type
;
16585 name
= ((* targetm
.strip_name_encoding
)
16586 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
16587 type
= visibility_types
[vis
];
16589 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
16590 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
16593 default_assemble_visibility (decl
, vis
);
16598 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
16600 /* Reversal of FP compares takes care -- an ordered compare
16601 becomes an unordered compare and vice versa. */
16602 if (mode
== CCFPmode
16603 && (!flag_finite_math_only
16604 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
16605 || code
== UNEQ
|| code
== LTGT
))
16606 return reverse_condition_maybe_unordered (code
);
16608 return reverse_condition (code
);
16611 /* Generate a compare for CODE. Return a brand-new rtx that
16612 represents the result of the compare. */
16615 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
16617 enum machine_mode comp_mode
;
16618 rtx compare_result
;
16619 enum rtx_code code
= GET_CODE (cmp
);
16620 rtx op0
= XEXP (cmp
, 0);
16621 rtx op1
= XEXP (cmp
, 1);
16623 if (FLOAT_MODE_P (mode
))
16624 comp_mode
= CCFPmode
;
16625 else if (code
== GTU
|| code
== LTU
16626 || code
== GEU
|| code
== LEU
)
16627 comp_mode
= CCUNSmode
;
16628 else if ((code
== EQ
|| code
== NE
)
16629 && GET_CODE (op0
) == SUBREG
16630 && GET_CODE (op1
) == SUBREG
16631 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
16632 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
16633 /* These are unsigned values, perhaps there will be a later
16634 ordering compare that can be shared with this one.
16635 Unfortunately we cannot detect the signedness of the operands
16636 for non-subregs. */
16637 comp_mode
= CCUNSmode
;
16639 comp_mode
= CCmode
;
16641 /* First, the compare. */
16642 compare_result
= gen_reg_rtx (comp_mode
);
16644 /* E500 FP compare instructions on the GPRs. Yuck! */
16645 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16646 && FLOAT_MODE_P (mode
))
16648 rtx cmp
, or_result
, compare_result2
;
16649 enum machine_mode op_mode
= GET_MODE (op0
);
16651 if (op_mode
== VOIDmode
)
16652 op_mode
= GET_MODE (op1
);
16654 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16655 This explains the following mess. */
16659 case EQ
: case UNEQ
: case NE
: case LTGT
:
16663 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16664 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
16665 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
16669 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16670 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
16671 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
16675 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16676 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
16677 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
16681 gcc_unreachable ();
16685 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
16689 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16690 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
16691 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
16695 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16696 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
16697 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
16701 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16702 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
16703 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
16707 gcc_unreachable ();
16711 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
16715 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16716 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
16717 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
16721 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16722 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
16723 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
16727 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16728 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
16729 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
16733 gcc_unreachable ();
16737 gcc_unreachable ();
16740 /* Synthesize LE and GE from LT/GT || EQ. */
16741 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
16747 case LE
: code
= LT
; break;
16748 case GE
: code
= GT
; break;
16749 case LEU
: code
= LT
; break;
16750 case GEU
: code
= GT
; break;
16751 default: gcc_unreachable ();
16754 compare_result2
= gen_reg_rtx (CCFPmode
);
16760 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16761 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
16762 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
16766 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16767 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
16768 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
16772 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16773 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
16774 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
16778 gcc_unreachable ();
16782 /* OR them together. */
16783 or_result
= gen_reg_rtx (CCFPmode
);
16784 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
16786 compare_result
= or_result
;
16791 if (code
== NE
|| code
== LTGT
)
16801 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16802 CLOBBERs to match cmptf_internal2 pattern. */
16803 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
16804 && GET_MODE (op0
) == TFmode
16805 && !TARGET_IEEEQUAD
16806 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
16807 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
16809 gen_rtx_SET (VOIDmode
,
16811 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
16812 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16813 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16814 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16815 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16816 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16817 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16818 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16819 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16820 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (Pmode
)))));
16821 else if (GET_CODE (op1
) == UNSPEC
16822 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
16824 rtx op1b
= XVECEXP (op1
, 0, 0);
16825 comp_mode
= CCEQmode
;
16826 compare_result
= gen_reg_rtx (CCEQmode
);
16828 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
16830 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
16833 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
16834 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
16837 /* Some kinds of FP comparisons need an OR operation;
16838 under flag_finite_math_only we don't bother. */
16839 if (FLOAT_MODE_P (mode
)
16840 && !flag_finite_math_only
16841 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
16842 && (code
== LE
|| code
== GE
16843 || code
== UNEQ
|| code
== LTGT
16844 || code
== UNGT
|| code
== UNLT
))
16846 enum rtx_code or1
, or2
;
16847 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
16848 rtx or_result
= gen_reg_rtx (CCEQmode
);
16852 case LE
: or1
= LT
; or2
= EQ
; break;
16853 case GE
: or1
= GT
; or2
= EQ
; break;
16854 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
16855 case LTGT
: or1
= LT
; or2
= GT
; break;
16856 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
16857 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
16858 default: gcc_unreachable ();
16860 validate_condition_mode (or1
, comp_mode
);
16861 validate_condition_mode (or2
, comp_mode
);
16862 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
16863 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
16864 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
16865 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
16867 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
16869 compare_result
= or_result
;
16873 validate_condition_mode (code
, GET_MODE (compare_result
));
16875 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
16879 /* Emit the RTL for an sISEL pattern. */
16882 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx operands
[])
16884 rs6000_emit_int_cmove (operands
[0], operands
[1], const1_rtx
, const0_rtx
);
16888 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
16891 enum machine_mode op_mode
;
16892 enum rtx_code cond_code
;
16893 rtx result
= operands
[0];
16895 if (TARGET_ISEL
&& (mode
== SImode
|| mode
== DImode
))
16897 rs6000_emit_sISEL (mode
, operands
);
16901 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
16902 cond_code
= GET_CODE (condition_rtx
);
16904 if (FLOAT_MODE_P (mode
)
16905 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16909 PUT_MODE (condition_rtx
, SImode
);
16910 t
= XEXP (condition_rtx
, 0);
16912 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
16914 if (cond_code
== NE
)
16915 emit_insn (gen_e500_flip_gt_bit (t
, t
));
16917 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
16921 if (cond_code
== NE
16922 || cond_code
== GE
|| cond_code
== LE
16923 || cond_code
== GEU
|| cond_code
== LEU
16924 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
16926 rtx not_result
= gen_reg_rtx (CCEQmode
);
16927 rtx not_op
, rev_cond_rtx
;
16928 enum machine_mode cc_mode
;
16930 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
16932 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
16933 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
16934 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
16935 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
16936 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
16939 op_mode
= GET_MODE (XEXP (operands
[1], 0));
16940 if (op_mode
== VOIDmode
)
16941 op_mode
= GET_MODE (XEXP (operands
[1], 1));
16943 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
16945 PUT_MODE (condition_rtx
, DImode
);
16946 convert_move (result
, condition_rtx
, 0);
16950 PUT_MODE (condition_rtx
, SImode
);
16951 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
16955 /* Emit a branch of kind CODE to location LOC. */
16958 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
16960 rtx condition_rtx
, loc_ref
;
16962 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
16963 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
16964 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
16965 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
16966 loc_ref
, pc_rtx
)));
16969 /* Return the string to output a conditional branch to LABEL, which is
16970 the operand number of the label, or -1 if the branch is really a
16971 conditional return.
16973 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16974 condition code register and its mode specifies what kind of
16975 comparison we made.
16977 REVERSED is nonzero if we should reverse the sense of the comparison.
16979 INSN is the insn. */
16982 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
16984 static char string
[64];
16985 enum rtx_code code
= GET_CODE (op
);
16986 rtx cc_reg
= XEXP (op
, 0);
16987 enum machine_mode mode
= GET_MODE (cc_reg
);
16988 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
16989 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
16990 int really_reversed
= reversed
^ need_longbranch
;
16996 validate_condition_mode (code
, mode
);
16998 /* Work out which way this really branches. We could use
16999 reverse_condition_maybe_unordered here always but this
17000 makes the resulting assembler clearer. */
17001 if (really_reversed
)
17003 /* Reversal of FP compares takes care -- an ordered compare
17004 becomes an unordered compare and vice versa. */
17005 if (mode
== CCFPmode
)
17006 code
= reverse_condition_maybe_unordered (code
);
17008 code
= reverse_condition (code
);
17011 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
17013 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17018 /* Opposite of GT. */
17027 gcc_unreachable ();
17033 /* Not all of these are actually distinct opcodes, but
17034 we distinguish them for clarity of the resulting assembler. */
17035 case NE
: case LTGT
:
17036 ccode
= "ne"; break;
17037 case EQ
: case UNEQ
:
17038 ccode
= "eq"; break;
17040 ccode
= "ge"; break;
17041 case GT
: case GTU
: case UNGT
:
17042 ccode
= "gt"; break;
17044 ccode
= "le"; break;
17045 case LT
: case LTU
: case UNLT
:
17046 ccode
= "lt"; break;
17047 case UNORDERED
: ccode
= "un"; break;
17048 case ORDERED
: ccode
= "nu"; break;
17049 case UNGE
: ccode
= "nl"; break;
17050 case UNLE
: ccode
= "ng"; break;
17052 gcc_unreachable ();
17055 /* Maybe we have a guess as to how likely the branch is.
17056 The old mnemonics don't have a way to specify this information. */
17058 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
17059 if (note
!= NULL_RTX
)
17061 /* PROB is the difference from 50%. */
17062 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
17064 /* Only hint for highly probable/improbable branches on newer
17065 cpus as static prediction overrides processor dynamic
17066 prediction. For older cpus we may as well always hint, but
17067 assume not taken for branches that are very close to 50% as a
17068 mispredicted taken branch is more expensive than a
17069 mispredicted not-taken branch. */
17070 if (rs6000_always_hint
17071 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
17072 && br_prob_note_reliable_p (note
)))
17074 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
17075 && ((prob
> 0) ^ need_longbranch
))
17083 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
17085 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
17087 /* We need to escape any '%' characters in the reg_names string.
17088 Assume they'd only be the first character.... */
17089 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
17091 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
17095 /* If the branch distance was too far, we may have to use an
17096 unconditional branch to go the distance. */
17097 if (need_longbranch
)
17098 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
17100 s
+= sprintf (s
, ",%s", label
);
17106 /* Return the string to flip the GT bit on a CR. */
17108 output_e500_flip_gt_bit (rtx dst
, rtx src
)
17110 static char string
[64];
17113 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
17114 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
17117 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
17118 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
17120 sprintf (string
, "crnot %d,%d", a
, b
);
17124 /* Return insn for VSX or Altivec comparisons. */
17127 rs6000_emit_vector_compare_inner (enum rtx_code code
, rtx op0
, rtx op1
)
17130 enum machine_mode mode
= GET_MODE (op0
);
17138 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
17144 mask
= gen_reg_rtx (mode
);
17145 emit_insn (gen_rtx_SET (VOIDmode
,
17147 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17154 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17155 DMODE is expected destination mode. This is a recursive function. */
17158 rs6000_emit_vector_compare (enum rtx_code rcode
,
17160 enum machine_mode dmode
)
17163 bool swap_operands
= false;
17164 bool try_again
= false;
17166 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode
));
17167 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
17169 /* See if the comparison works as is. */
17170 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
17178 swap_operands
= true;
17183 swap_operands
= true;
17191 /* Invert condition and try again.
17192 e.g., A != B becomes ~(A==B). */
17194 enum rtx_code rev_code
;
17195 enum insn_code nor_code
;
17198 rev_code
= reverse_condition_maybe_unordered (rcode
);
17199 if (rev_code
== UNKNOWN
)
17202 nor_code
= optab_handler (one_cmpl_optab
, dmode
);
17203 if (nor_code
== CODE_FOR_nothing
)
17206 mask2
= rs6000_emit_vector_compare (rev_code
, op0
, op1
, dmode
);
17210 mask
= gen_reg_rtx (dmode
);
17211 emit_insn (GEN_FCN (nor_code
) (mask
, mask2
));
17219 /* Try GT/GTU/LT/LTU OR EQ */
17222 enum insn_code ior_code
;
17223 enum rtx_code new_code
;
17244 gcc_unreachable ();
17247 ior_code
= optab_handler (ior_optab
, dmode
);
17248 if (ior_code
== CODE_FOR_nothing
)
17251 c_rtx
= rs6000_emit_vector_compare (new_code
, op0
, op1
, dmode
);
17255 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
, dmode
);
17259 mask
= gen_reg_rtx (dmode
);
17260 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
17278 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
17283 /* You only get two chances. */
17287 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17288 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17289 operands for the relation operation COND. */
17292 rs6000_emit_vector_cond_expr (rtx dest
, rtx op_true
, rtx op_false
,
17293 rtx cond
, rtx cc_op0
, rtx cc_op1
)
17295 enum machine_mode dest_mode
= GET_MODE (dest
);
17296 enum rtx_code rcode
= GET_CODE (cond
);
17297 enum machine_mode cc_mode
= CCmode
;
17301 bool invert_move
= false;
17303 if (VECTOR_UNIT_NONE_P (dest_mode
))
17308 /* Swap operands if we can, and fall back to doing the operation as
17309 specified, and doing a NOR to invert the test. */
17315 /* Invert condition and try again.
17316 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17317 invert_move
= true;
17318 rcode
= reverse_condition_maybe_unordered (rcode
);
17319 if (rcode
== UNKNOWN
)
17323 /* Mark unsigned tests with CCUNSmode. */
17328 cc_mode
= CCUNSmode
;
17335 /* Get the vector mask for the given relational operations. */
17336 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
17344 op_true
= op_false
;
17348 cond2
= gen_rtx_fmt_ee (NE
, cc_mode
, mask
, const0_rtx
);
17349 emit_insn (gen_rtx_SET (VOIDmode
,
17351 gen_rtx_IF_THEN_ELSE (dest_mode
,
17358 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17359 operands of the last comparison is nonzero/true, FALSE_COND if it
17360 is zero/false. Return 0 if the hardware has no such operation. */
17363 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17365 enum rtx_code code
= GET_CODE (op
);
17366 rtx op0
= XEXP (op
, 0);
17367 rtx op1
= XEXP (op
, 1);
17368 REAL_VALUE_TYPE c1
;
17369 enum machine_mode compare_mode
= GET_MODE (op0
);
17370 enum machine_mode result_mode
= GET_MODE (dest
);
17372 bool is_against_zero
;
17374 /* These modes should always match. */
17375 if (GET_MODE (op1
) != compare_mode
17376 /* In the isel case however, we can use a compare immediate, so
17377 op1 may be a small constant. */
17378 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
17380 if (GET_MODE (true_cond
) != result_mode
)
17382 if (GET_MODE (false_cond
) != result_mode
)
17385 /* First, work out if the hardware can do this at all, or
17386 if it's too slow.... */
17387 if (!FLOAT_MODE_P (compare_mode
))
17390 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
17393 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
17394 && SCALAR_FLOAT_MODE_P (compare_mode
))
17397 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
17399 /* A floating-point subtract might overflow, underflow, or produce
17400 an inexact result, thus changing the floating-point flags, so it
17401 can't be generated if we care about that. It's safe if one side
17402 of the construct is zero, since then no subtract will be
17404 if (SCALAR_FLOAT_MODE_P (compare_mode
)
17405 && flag_trapping_math
&& ! is_against_zero
)
17408 /* Eliminate half of the comparisons by switching operands, this
17409 makes the remaining code simpler. */
17410 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
17411 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
17413 code
= reverse_condition_maybe_unordered (code
);
17415 true_cond
= false_cond
;
17419 /* UNEQ and LTGT take four instructions for a comparison with zero,
17420 it'll probably be faster to use a branch here too. */
17421 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
17424 if (GET_CODE (op1
) == CONST_DOUBLE
)
17425 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
17427 /* We're going to try to implement comparisons by performing
17428 a subtract, then comparing against zero. Unfortunately,
17429 Inf - Inf is NaN which is not zero, and so if we don't
17430 know that the operand is finite and the comparison
17431 would treat EQ different to UNORDERED, we can't do it. */
17432 if (HONOR_INFINITIES (compare_mode
)
17433 && code
!= GT
&& code
!= UNGE
17434 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
17435 /* Constructs of the form (a OP b ? a : b) are safe. */
17436 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
17437 || (! rtx_equal_p (op0
, true_cond
)
17438 && ! rtx_equal_p (op1
, true_cond
))))
17441 /* At this point we know we can use fsel. */
17443 /* Reduce the comparison to a comparison against zero. */
17444 if (! is_against_zero
)
17446 temp
= gen_reg_rtx (compare_mode
);
17447 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17448 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
17450 op1
= CONST0_RTX (compare_mode
);
17453 /* If we don't care about NaNs we can reduce some of the comparisons
17454 down to faster ones. */
17455 if (! HONOR_NANS (compare_mode
))
17461 true_cond
= false_cond
;
17474 /* Now, reduce everything down to a GE. */
17481 temp
= gen_reg_rtx (compare_mode
);
17482 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17487 temp
= gen_reg_rtx (compare_mode
);
17488 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
17493 temp
= gen_reg_rtx (compare_mode
);
17494 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17495 gen_rtx_NEG (compare_mode
,
17496 gen_rtx_ABS (compare_mode
, op0
))));
17501 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17502 temp
= gen_reg_rtx (result_mode
);
17503 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17504 gen_rtx_IF_THEN_ELSE (result_mode
,
17505 gen_rtx_GE (VOIDmode
,
17507 true_cond
, false_cond
)));
17508 false_cond
= true_cond
;
17511 temp
= gen_reg_rtx (compare_mode
);
17512 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17517 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17518 temp
= gen_reg_rtx (result_mode
);
17519 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17520 gen_rtx_IF_THEN_ELSE (result_mode
,
17521 gen_rtx_GE (VOIDmode
,
17523 true_cond
, false_cond
)));
17524 true_cond
= false_cond
;
17527 temp
= gen_reg_rtx (compare_mode
);
17528 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17533 gcc_unreachable ();
17536 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
17537 gen_rtx_IF_THEN_ELSE (result_mode
,
17538 gen_rtx_GE (VOIDmode
,
17540 true_cond
, false_cond
)));
17544 /* Same as above, but for ints (isel). */
17547 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17549 rtx condition_rtx
, cr
;
17550 enum machine_mode mode
= GET_MODE (dest
);
17551 enum rtx_code cond_code
;
17552 rtx (*isel_func
) (rtx
, rtx
, rtx
, rtx
, rtx
);
17555 if (mode
!= SImode
&& (!TARGET_POWERPC64
|| mode
!= DImode
))
17558 /* We still have to do the compare, because isel doesn't do a
17559 compare, it just looks at the CRx bits set by a previous compare
17561 condition_rtx
= rs6000_generate_compare (op
, mode
);
17562 cond_code
= GET_CODE (condition_rtx
);
17563 cr
= XEXP (condition_rtx
, 0);
17564 signedp
= GET_MODE (cr
) == CCmode
;
17566 isel_func
= (mode
== SImode
17567 ? (signedp
? gen_isel_signed_si
: gen_isel_unsigned_si
)
17568 : (signedp
? gen_isel_signed_di
: gen_isel_unsigned_di
));
17572 case LT
: case GT
: case LTU
: case GTU
: case EQ
:
17573 /* isel handles these directly. */
17577 /* We need to swap the sense of the comparison. */
17580 true_cond
= false_cond
;
17582 PUT_CODE (condition_rtx
, reverse_condition (cond_code
));
17587 false_cond
= force_reg (mode
, false_cond
);
17588 if (true_cond
!= const0_rtx
)
17589 true_cond
= force_reg (mode
, true_cond
);
17591 emit_insn (isel_func (dest
, condition_rtx
, true_cond
, false_cond
, cr
));
17597 output_isel (rtx
*operands
)
17599 enum rtx_code code
;
17601 code
= GET_CODE (operands
[1]);
17603 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
17605 gcc_assert (GET_CODE (operands
[2]) == REG
17606 && GET_CODE (operands
[3]) == REG
);
17607 PUT_CODE (operands
[1], reverse_condition (code
));
17608 return "isel %0,%3,%2,%j1";
17611 return "isel %0,%2,%3,%j1";
17615 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
17617 enum machine_mode mode
= GET_MODE (op0
);
17621 /* VSX/altivec have direct min/max insns. */
17622 if ((code
== SMAX
|| code
== SMIN
)
17623 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
17624 || (mode
== SFmode
&& VECTOR_UNIT_VSX_P (DFmode
))))
17626 emit_insn (gen_rtx_SET (VOIDmode
,
17628 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17632 if (code
== SMAX
|| code
== SMIN
)
17637 if (code
== SMAX
|| code
== UMAX
)
17638 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17639 op0
, op1
, mode
, 0);
17641 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17642 op1
, op0
, mode
, 0);
17643 gcc_assert (target
);
17644 if (target
!= dest
)
17645 emit_move_insn (dest
, target
);
17648 /* Emit instructions to perform a load-reserved/store-conditional operation.
17649 The operation performed is an atomic
17650 (set M (CODE:MODE M OP))
17651 If not NULL, BEFORE is atomically set to M before the operation, and
17652 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17653 If SYNC_P then a memory barrier is emitted before the operation.
17654 Either OP or M may be wrapped in a NOT operation. */
17657 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
17658 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
17661 enum machine_mode used_mode
;
17662 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
17665 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17666 rtx shift
= NULL_RTX
;
17669 emit_insn (gen_lwsync ());
17673 /* If this is smaller than SImode, we'll have to use SImode with
17675 if (mode
== QImode
|| mode
== HImode
)
17679 if (MEM_ALIGN (used_m
) >= 32)
17682 if (BYTES_BIG_ENDIAN
)
17683 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
17685 shift
= GEN_INT (ishift
);
17686 used_m
= change_address (used_m
, SImode
, 0);
17690 rtx addrSI
, aligned_addr
;
17691 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
17693 addrSI
= gen_lowpart_common (SImode
,
17694 force_reg (Pmode
, XEXP (used_m
, 0)));
17695 addrSI
= force_reg (SImode
, addrSI
);
17696 shift
= gen_reg_rtx (SImode
);
17698 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
17699 GEN_INT (shift_mask
)));
17700 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
17702 aligned_addr
= expand_binop (Pmode
, and_optab
,
17704 GEN_INT (-4), NULL_RTX
,
17705 1, OPTAB_LIB_WIDEN
);
17706 used_m
= change_address (used_m
, SImode
, aligned_addr
);
17707 set_mem_align (used_m
, 32);
17709 /* It's safe to keep the old alias set of USED_M, because
17710 the operation is atomic and only affects the original
17714 if (GET_CODE (op
) == NOT
)
17716 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
17717 oldop
= gen_rtx_NOT (SImode
, oldop
);
17720 oldop
= lowpart_subreg (SImode
, op
, mode
);
17726 newop
= expand_binop (SImode
, and_optab
,
17727 oldop
, GEN_INT (imask
), NULL_RTX
,
17728 1, OPTAB_LIB_WIDEN
);
17729 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17732 case NOT
: /* NAND */
17733 newop
= expand_binop (SImode
, ior_optab
,
17734 oldop
, GEN_INT (~imask
), NULL_RTX
,
17735 1, OPTAB_LIB_WIDEN
);
17736 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17740 newop
= expand_binop (SImode
, ior_optab
,
17741 oldop
, GEN_INT (~imask
), NULL_RTX
,
17742 1, OPTAB_LIB_WIDEN
);
17743 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17751 newop
= expand_binop (SImode
, and_optab
,
17752 oldop
, GEN_INT (imask
), NULL_RTX
,
17753 1, OPTAB_LIB_WIDEN
);
17754 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17756 mask
= gen_reg_rtx (SImode
);
17757 emit_move_insn (mask
, GEN_INT (imask
));
17758 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
17761 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
17763 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
17764 newop
= gen_rtx_AND (SImode
, newop
, mask
);
17765 newop
= gen_rtx_IOR (SImode
, newop
,
17766 gen_rtx_AND (SImode
,
17767 gen_rtx_NOT (SImode
, mask
),
17773 gcc_unreachable ();
17777 used_mode
= SImode
;
17778 before
= gen_reg_rtx (used_mode
);
17779 after
= gen_reg_rtx (used_mode
);
17784 before
= before_param
;
17785 after
= after_param
;
17787 if (before
== NULL_RTX
)
17788 before
= gen_reg_rtx (used_mode
);
17789 if (after
== NULL_RTX
)
17790 after
= gen_reg_rtx (used_mode
);
17793 if ((code
== PLUS
|| code
== MINUS
)
17794 && used_mode
!= mode
)
17795 the_op
= op
; /* Computed above. */
17796 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
17797 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
17798 else if (code
== NOT
)
17799 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
17800 gen_rtx_NOT (used_mode
, m
),
17801 gen_rtx_NOT (used_mode
, op
));
17803 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
17805 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
17806 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
17807 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
17808 gen_rtx_UNSPEC (used_mode
,
17809 gen_rtvec (1, the_op
),
17811 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
17813 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
17814 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
17815 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
17817 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
17818 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
17820 /* Shift and mask the return values properly. */
17821 if (used_mode
!= mode
&& before_param
)
17823 emit_insn (gen_lshrsi3 (before
, before
, shift
));
17824 convert_move (before_param
, before
, 1);
17827 if (used_mode
!= mode
&& after_param
)
17829 emit_insn (gen_lshrsi3 (after
, after
, shift
));
17830 convert_move (after_param
, after
, 1);
17833 /* The previous sequence will end with a branch that's dependent on
17834 the conditional store, so placing an isync will ensure that no
17835 other instructions (especially, no load or store instructions)
17836 can start before the atomic operation completes. */
17838 emit_insn (gen_isync ());
17841 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17842 COND is true. Mark the jump as unlikely to be taken. */
17845 emit_unlikely_jump (rtx cond
, rtx label
)
17847 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
17850 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
17851 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
17852 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
17855 /* A subroutine of the atomic operation splitters. Emit a load-locked
17856 instruction in MODE. */
17859 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
17861 rtx (*fn
) (rtx
, rtx
) = NULL
;
17862 if (mode
== SImode
)
17863 fn
= gen_load_locked_si
;
17864 else if (mode
== DImode
)
17865 fn
= gen_load_locked_di
;
17866 emit_insn (fn (reg
, mem
));
17869 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17870 instruction in MODE. */
17873 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
17875 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
17876 if (mode
== SImode
)
17877 fn
= gen_store_conditional_si
;
17878 else if (mode
== DImode
)
17879 fn
= gen_store_conditional_di
;
17881 /* Emit sync before stwcx. to address PPC405 Erratum. */
17882 if (PPC405_ERRATUM77
)
17883 emit_insn (gen_memory_barrier ());
17885 emit_insn (fn (res
, mem
, val
));
17888 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17889 to perform. MEM is the memory on which to operate. VAL is the second
17890 operand of the binary operator. BEFORE and AFTER are optional locations to
17891 return the value of MEM either before of after the operation. SCRATCH is
17892 a scratch register. */
17895 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
17896 rtx before
, rtx after
, rtx scratch
)
17898 enum machine_mode mode
= GET_MODE (mem
);
17899 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17901 emit_insn (gen_lwsync ());
17903 label
= gen_label_rtx ();
17904 emit_label (label
);
17905 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
17907 if (before
== NULL_RTX
)
17909 emit_load_locked (mode
, before
, mem
);
17912 x
= gen_rtx_IOR (mode
,
17913 gen_rtx_NOT (mode
, before
),
17914 gen_rtx_NOT (mode
, val
));
17915 else if (code
== AND
)
17916 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
17918 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
17920 if (after
!= NULL_RTX
)
17921 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
17922 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
17924 emit_store_conditional (mode
, cond
, mem
, scratch
);
17926 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17927 emit_unlikely_jump (x
, label
);
17929 emit_insn (gen_isync ());
17932 /* Expand an atomic compare and swap operation. MEM is the memory on which
17933 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17934 value to be stored. SCRATCH is a scratch GPR. */
17937 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
17940 enum machine_mode mode
= GET_MODE (mem
);
17941 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17943 emit_insn (gen_lwsync ());
17945 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17946 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17947 emit_label (XEXP (label1
, 0));
17949 emit_load_locked (mode
, retval
, mem
);
17951 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
17952 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
17954 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17955 emit_unlikely_jump (x
, label2
);
17957 emit_move_insn (scratch
, newval
);
17958 emit_store_conditional (mode
, cond
, mem
, scratch
);
17960 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17961 emit_unlikely_jump (x
, label1
);
17963 emit_insn (gen_isync ());
17964 emit_label (XEXP (label2
, 0));
17967 /* Expand an atomic test and set operation. MEM is the memory on which
17968 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17971 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
17973 enum machine_mode mode
= GET_MODE (mem
);
17974 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17976 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17977 emit_label (XEXP (label
, 0));
17979 emit_load_locked (mode
, retval
, mem
);
17980 emit_move_insn (scratch
, val
);
17981 emit_store_conditional (mode
, cond
, mem
, scratch
);
17983 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17984 emit_unlikely_jump (x
, label
);
17986 emit_insn (gen_isync ());
17990 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
17992 enum machine_mode mode
= GET_MODE (mem
);
17993 rtx addrSI
, align
, wdst
, shift
, mask
;
17994 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
17995 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17997 /* Shift amount for subword relative to aligned word. */
17998 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
17999 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
18000 shift
= gen_reg_rtx (SImode
);
18001 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
18002 GEN_INT (shift_mask
)));
18003 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
18005 /* Shift and mask old value into position within word. */
18006 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
18007 oldval
= expand_binop (SImode
, and_optab
,
18008 oldval
, GEN_INT (imask
), NULL_RTX
,
18009 1, OPTAB_LIB_WIDEN
);
18010 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
18012 /* Shift and mask new value into position within word. */
18013 newval
= convert_modes (SImode
, mode
, newval
, 1);
18014 newval
= expand_binop (SImode
, and_optab
,
18015 newval
, GEN_INT (imask
), NULL_RTX
,
18016 1, OPTAB_LIB_WIDEN
);
18017 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
18019 /* Mask for insertion. */
18020 mask
= gen_reg_rtx (SImode
);
18021 emit_move_insn (mask
, GEN_INT (imask
));
18022 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
18024 /* Address of aligned word containing subword. */
18025 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
18026 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
18027 mem
= change_address (mem
, SImode
, align
);
18028 set_mem_align (mem
, 32);
18029 MEM_VOLATILE_P (mem
) = 1;
18031 wdst
= gen_reg_rtx (SImode
);
18032 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
18033 oldval
, newval
, mem
));
18035 /* Shift the result back. */
18036 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
18038 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
18042 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
18043 rtx oldval
, rtx newval
, rtx mem
,
18046 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18048 emit_insn (gen_lwsync ());
18049 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18050 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18051 emit_label (XEXP (label1
, 0));
18053 emit_load_locked (SImode
, scratch
, mem
);
18055 /* Mask subword within loaded value for comparison with oldval.
18056 Use UNSPEC_AND to avoid clobber.*/
18057 emit_insn (gen_rtx_SET (SImode
, dest
,
18058 gen_rtx_UNSPEC (SImode
,
18059 gen_rtvec (2, scratch
, mask
),
18062 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
18063 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
18065 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18066 emit_unlikely_jump (x
, label2
);
18068 /* Clear subword within loaded value for insertion of new value. */
18069 emit_insn (gen_rtx_SET (SImode
, scratch
,
18070 gen_rtx_AND (SImode
,
18071 gen_rtx_NOT (SImode
, mask
), scratch
)));
18072 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
18073 emit_store_conditional (SImode
, cond
, mem
, scratch
);
18075 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18076 emit_unlikely_jump (x
, label1
);
18078 emit_insn (gen_isync ());
18079 emit_label (XEXP (label2
, 0));
18083 /* Emit instructions to move SRC to DST. Called by splitters for
18084 multi-register moves. It will emit at most one instruction for
18085 each register that is accessed; that is, it won't emit li/lis pairs
18086 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18090 rs6000_split_multireg_move (rtx dst
, rtx src
)
18092 /* The register number of the first register being moved. */
18094 /* The mode that is to be moved. */
18095 enum machine_mode mode
;
18096 /* The mode that the move is being done in, and its size. */
18097 enum machine_mode reg_mode
;
18099 /* The number of registers that will be moved. */
18102 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
18103 mode
= GET_MODE (dst
);
18104 nregs
= hard_regno_nregs
[reg
][mode
];
18105 if (FP_REGNO_P (reg
))
18106 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
18107 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
18108 else if (ALTIVEC_REGNO_P (reg
))
18109 reg_mode
= V16QImode
;
18110 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
18113 reg_mode
= word_mode
;
18114 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
18116 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
18118 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
18120 /* Move register range backwards, if we might have destructive
18123 for (i
= nregs
- 1; i
>= 0; i
--)
18124 emit_insn (gen_rtx_SET (VOIDmode
,
18125 simplify_gen_subreg (reg_mode
, dst
, mode
,
18126 i
* reg_mode_size
),
18127 simplify_gen_subreg (reg_mode
, src
, mode
,
18128 i
* reg_mode_size
)));
18134 bool used_update
= false;
18135 rtx restore_basereg
= NULL_RTX
;
18137 if (MEM_P (src
) && INT_REGNO_P (reg
))
18141 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
18142 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
18145 breg
= XEXP (XEXP (src
, 0), 0);
18146 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
18147 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
18148 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
18149 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
18150 src
= replace_equiv_address (src
, breg
);
18152 else if (! rs6000_offsettable_memref_p (src
))
18154 if (GET_CODE (XEXP (src
, 0)) == PRE_MODIFY
)
18156 rtx basereg
= XEXP (XEXP (src
, 0), 0);
18159 rtx ndst
= simplify_gen_subreg (reg_mode
, dst
, mode
, 0);
18160 emit_insn (gen_rtx_SET (VOIDmode
, ndst
,
18161 gen_rtx_MEM (reg_mode
, XEXP (src
, 0))));
18162 used_update
= true;
18165 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
18166 XEXP (XEXP (src
, 0), 1)));
18167 src
= replace_equiv_address (src
, basereg
);
18171 rtx basereg
= gen_rtx_REG (Pmode
, reg
);
18172 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
18173 src
= replace_equiv_address (src
, basereg
);
18177 breg
= XEXP (src
, 0);
18178 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
18179 breg
= XEXP (breg
, 0);
18181 /* If the base register we are using to address memory is
18182 also a destination reg, then change that register last. */
18184 && REGNO (breg
) >= REGNO (dst
)
18185 && REGNO (breg
) < REGNO (dst
) + nregs
)
18186 j
= REGNO (breg
) - REGNO (dst
);
18188 else if (MEM_P (dst
) && INT_REGNO_P (reg
))
18192 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
18193 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
18196 breg
= XEXP (XEXP (dst
, 0), 0);
18197 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
18198 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
18199 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
18201 /* We have to update the breg before doing the store.
18202 Use store with update, if available. */
18206 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
18207 emit_insn (TARGET_32BIT
18208 ? (TARGET_POWERPC64
18209 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
18210 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
18211 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
18212 used_update
= true;
18215 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
18216 dst
= replace_equiv_address (dst
, breg
);
18218 else if (!rs6000_offsettable_memref_p (dst
)
18219 && GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
18221 if (GET_CODE (XEXP (dst
, 0)) == PRE_MODIFY
)
18223 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
18226 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
18227 emit_insn (gen_rtx_SET (VOIDmode
,
18228 gen_rtx_MEM (reg_mode
, XEXP (dst
, 0)), nsrc
));
18229 used_update
= true;
18232 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
18233 XEXP (XEXP (dst
, 0), 1)));
18234 dst
= replace_equiv_address (dst
, basereg
);
18238 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
18239 rtx offsetreg
= XEXP (XEXP (dst
, 0), 1);
18240 gcc_assert (GET_CODE (XEXP (dst
, 0)) == PLUS
18242 && REG_P (offsetreg
)
18243 && REGNO (basereg
) != REGNO (offsetreg
));
18244 if (REGNO (basereg
) == 0)
18246 rtx tmp
= offsetreg
;
18247 offsetreg
= basereg
;
18250 emit_insn (gen_add3_insn (basereg
, basereg
, offsetreg
));
18251 restore_basereg
= gen_sub3_insn (basereg
, basereg
, offsetreg
);
18252 dst
= replace_equiv_address (dst
, basereg
);
18255 else if (GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
18256 gcc_assert (rs6000_offsettable_memref_p (dst
));
18259 for (i
= 0; i
< nregs
; i
++)
18261 /* Calculate index to next subword. */
18266 /* If compiler already emitted move of first word by
18267 store with update, no need to do anything. */
18268 if (j
== 0 && used_update
)
18271 emit_insn (gen_rtx_SET (VOIDmode
,
18272 simplify_gen_subreg (reg_mode
, dst
, mode
,
18273 j
* reg_mode_size
),
18274 simplify_gen_subreg (reg_mode
, src
, mode
,
18275 j
* reg_mode_size
)));
18277 if (restore_basereg
!= NULL_RTX
)
18278 emit_insn (restore_basereg
);
18283 /* This page contains routines that are used to determine what the
18284 function prologue and epilogue code will do and write them out. */
18286 /* Return the first fixed-point register that is required to be
18287 saved. 32 if none. */
18290 first_reg_to_save (void)
18294 /* Find lowest numbered live register. */
18295 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
18296 if (df_regs_ever_live_p (first_reg
)
18297 && (! call_used_regs
[first_reg
]
18298 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
18299 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
18300 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
18301 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
18306 && crtl
->uses_pic_offset_table
18307 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18308 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
18314 /* Similar, for FP regs. */
18317 first_fp_reg_to_save (void)
18321 /* Find lowest numbered live register. */
18322 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
18323 if (df_regs_ever_live_p (first_reg
))
18329 /* Similar, for AltiVec regs. */
18332 first_altivec_reg_to_save (void)
18336 /* Stack frame remains as is unless we are in AltiVec ABI. */
18337 if (! TARGET_ALTIVEC_ABI
)
18338 return LAST_ALTIVEC_REGNO
+ 1;
18340 /* On Darwin, the unwind routines are compiled without
18341 TARGET_ALTIVEC, and use save_world to save/restore the
18342 altivec registers when necessary. */
18343 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
18344 && ! TARGET_ALTIVEC
)
18345 return FIRST_ALTIVEC_REGNO
+ 20;
18347 /* Find lowest numbered live register. */
18348 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
18349 if (df_regs_ever_live_p (i
))
18355 /* Return a 32-bit mask of the AltiVec registers we need to set in
18356 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18357 the 32-bit word is 0. */
18359 static unsigned int
18360 compute_vrsave_mask (void)
18362 unsigned int i
, mask
= 0;
18364 /* On Darwin, the unwind routines are compiled without
18365 TARGET_ALTIVEC, and use save_world to save/restore the
18366 call-saved altivec registers when necessary. */
18367 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
18368 && ! TARGET_ALTIVEC
)
18371 /* First, find out if we use _any_ altivec registers. */
18372 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
18373 if (df_regs_ever_live_p (i
))
18374 mask
|= ALTIVEC_REG_BIT (i
);
18379 /* Next, remove the argument registers from the set. These must
18380 be in the VRSAVE mask set by the caller, so we don't need to add
18381 them in again. More importantly, the mask we compute here is
18382 used to generate CLOBBERs in the set_vrsave insn, and we do not
18383 wish the argument registers to die. */
18384 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
18385 mask
&= ~ALTIVEC_REG_BIT (i
);
18387 /* Similarly, remove the return value from the set. */
18390 diddle_return_value (is_altivec_return_reg
, &yes
);
18392 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
18398 /* For a very restricted set of circumstances, we can cut down the
18399 size of prologues/epilogues by calling our own save/restore-the-world
18403 compute_save_world_info (rs6000_stack_t
*info_ptr
)
18405 info_ptr
->world_save_p
= 1;
18406 info_ptr
->world_save_p
18407 = (WORLD_SAVE_P (info_ptr
)
18408 && DEFAULT_ABI
== ABI_DARWIN
18409 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
18410 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
18411 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
18412 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
18413 && info_ptr
->cr_save_p
);
18415 /* This will not work in conjunction with sibcalls. Make sure there
18416 are none. (This check is expensive, but seldom executed.) */
18417 if (WORLD_SAVE_P (info_ptr
))
18420 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
18421 if ( GET_CODE (insn
) == CALL_INSN
18422 && SIBLING_CALL_P (insn
))
18424 info_ptr
->world_save_p
= 0;
18429 if (WORLD_SAVE_P (info_ptr
))
18431 /* Even if we're not touching VRsave, make sure there's room on the
18432 stack for it, if it looks like we're calling SAVE_WORLD, which
18433 will attempt to save it. */
18434 info_ptr
->vrsave_size
= 4;
18436 /* If we are going to save the world, we need to save the link register too. */
18437 info_ptr
->lr_save_p
= 1;
18439 /* "Save" the VRsave register too if we're saving the world. */
18440 if (info_ptr
->vrsave_mask
== 0)
18441 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18443 /* Because the Darwin register save/restore routines only handle
18444 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18446 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
18447 && (info_ptr
->first_altivec_reg_save
18448 >= FIRST_SAVED_ALTIVEC_REGNO
));
18455 is_altivec_return_reg (rtx reg
, void *xyes
)
18457 bool *yes
= (bool *) xyes
;
18458 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
18463 /* Determine the strategy for savings/restoring registers. */
18466 SAVRES_MULTIPLE
= 0x1,
18467 SAVE_INLINE_FPRS
= 0x2,
18468 SAVE_INLINE_GPRS
= 0x4,
18469 REST_INLINE_FPRS
= 0x8,
18470 REST_INLINE_GPRS
= 0x10,
18471 SAVE_NOINLINE_GPRS_SAVES_LR
= 0x20,
18472 SAVE_NOINLINE_FPRS_SAVES_LR
= 0x40,
18473 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
= 0x80
18477 rs6000_savres_strategy (rs6000_stack_t
*info
,
18478 bool using_static_chain_p
)
18482 if (TARGET_MULTIPLE
18483 && !TARGET_POWERPC64
18484 && !(TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
)
18485 && info
->first_gp_reg_save
< 31
18486 && no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true))
18487 strategy
|= SAVRES_MULTIPLE
;
18489 if (crtl
->calls_eh_return
18490 || cfun
->machine
->ra_need_lr
18491 || info
->total_size
> 32767)
18492 strategy
|= (SAVE_INLINE_FPRS
| REST_INLINE_FPRS
18493 | SAVE_INLINE_GPRS
| REST_INLINE_GPRS
);
18495 if (info
->first_fp_reg_save
== 64
18496 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
18497 /* The out-of-line FP routines use double-precision stores;
18498 we can't use those routines if we don't have such stores. */
18499 || (TARGET_HARD_FLOAT
&& !TARGET_DOUBLE_FLOAT
)
18500 || !no_global_regs_above (info
->first_fp_reg_save
, /*gpr=*/false))
18501 strategy
|= SAVE_INLINE_FPRS
| REST_INLINE_FPRS
;
18503 if (info
->first_gp_reg_save
== 32
18504 || GP_SAVE_INLINE (info
->first_gp_reg_save
)
18505 || !((strategy
& SAVRES_MULTIPLE
)
18506 || no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true)))
18507 strategy
|= SAVE_INLINE_GPRS
| REST_INLINE_GPRS
;
18509 /* Don't bother to try to save things out-of-line if r11 is occupied
18510 by the static chain. It would require too much fiddling and the
18511 static chain is rarely used anyway. */
18512 if (using_static_chain_p
)
18513 strategy
|= SAVE_INLINE_FPRS
| SAVE_INLINE_GPRS
;
18515 /* If we are going to use store multiple, then don't even bother
18516 with the out-of-line routines, since the store-multiple
18517 instruction will always be smaller. */
18518 if ((strategy
& SAVRES_MULTIPLE
))
18519 strategy
|= SAVE_INLINE_GPRS
;
18521 /* The situation is more complicated with load multiple. We'd
18522 prefer to use the out-of-line routines for restores, since the
18523 "exit" out-of-line routines can handle the restore of LR and the
18524 frame teardown. However if doesn't make sense to use the
18525 out-of-line routine if that is the only reason we'd need to save
18526 LR, and we can't use the "exit" out-of-line gpr restore if we
18527 have saved some fprs; In those cases it is advantageous to use
18528 load multiple when available. */
18529 if ((strategy
& SAVRES_MULTIPLE
)
18530 && (!info
->lr_save_p
18531 || info
->first_fp_reg_save
!= 64))
18532 strategy
|= REST_INLINE_GPRS
;
18534 /* We can only use load multiple or the out-of-line routines to
18535 restore if we've used store multiple or out-of-line routines
18536 in the prologue, i.e. if we've saved all the registers from
18537 first_gp_reg_save. Otherwise, we risk loading garbage. */
18538 if ((strategy
& (SAVE_INLINE_GPRS
| SAVRES_MULTIPLE
)) == SAVE_INLINE_GPRS
)
18539 strategy
|= REST_INLINE_GPRS
;
18541 /* Saving CR interferes with the exit routines used on the SPE, so
18544 && info
->spe_64bit_regs_used
18545 && info
->cr_save_p
)
18546 strategy
|= REST_INLINE_GPRS
;
18548 #ifdef POWERPC_LINUX
18551 if (!(strategy
& SAVE_INLINE_FPRS
))
18552 strategy
|= SAVE_NOINLINE_FPRS_SAVES_LR
;
18553 else if (!(strategy
& SAVE_INLINE_GPRS
)
18554 && info
->first_fp_reg_save
== 64)
18555 strategy
|= SAVE_NOINLINE_GPRS_SAVES_LR
;
18558 if (TARGET_AIX
&& !(strategy
& REST_INLINE_FPRS
))
18559 strategy
|= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
;
18564 /* Calculate the stack information for the current function. This is
18565 complicated by having two separate calling sequences, the AIX calling
18566 sequence and the V.4 calling sequence.
18568 AIX (and Darwin/Mac OS X) stack frames look like:
18570 SP----> +---------------------------------------+
18571 | back chain to caller | 0 0
18572 +---------------------------------------+
18573 | saved CR | 4 8 (8-11)
18574 +---------------------------------------+
18576 +---------------------------------------+
18577 | reserved for compilers | 12 24
18578 +---------------------------------------+
18579 | reserved for binders | 16 32
18580 +---------------------------------------+
18581 | saved TOC pointer | 20 40
18582 +---------------------------------------+
18583 | Parameter save area (P) | 24 48
18584 +---------------------------------------+
18585 | Alloca space (A) | 24+P etc.
18586 +---------------------------------------+
18587 | Local variable space (L) | 24+P+A
18588 +---------------------------------------+
18589 | Float/int conversion temporary (X) | 24+P+A+L
18590 +---------------------------------------+
18591 | Save area for AltiVec registers (W) | 24+P+A+L+X
18592 +---------------------------------------+
18593 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18594 +---------------------------------------+
18595 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18596 +---------------------------------------+
18597 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18598 +---------------------------------------+
18599 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18600 +---------------------------------------+
18601 old SP->| back chain to caller's caller |
18602 +---------------------------------------+
18604 The required alignment for AIX configurations is two words (i.e., 8
18608 V.4 stack frames look like:
18610 SP----> +---------------------------------------+
18611 | back chain to caller | 0
18612 +---------------------------------------+
18613 | caller's saved LR | 4
18614 +---------------------------------------+
18615 | Parameter save area (P) | 8
18616 +---------------------------------------+
18617 | Alloca space (A) | 8+P
18618 +---------------------------------------+
18619 | Varargs save area (V) | 8+P+A
18620 +---------------------------------------+
18621 | Local variable space (L) | 8+P+A+V
18622 +---------------------------------------+
18623 | Float/int conversion temporary (X) | 8+P+A+V+L
18624 +---------------------------------------+
18625 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18626 +---------------------------------------+
18627 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18628 +---------------------------------------+
18629 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18630 +---------------------------------------+
18631 | SPE: area for 64-bit GP registers |
18632 +---------------------------------------+
18633 | SPE alignment padding |
18634 +---------------------------------------+
18635 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18636 +---------------------------------------+
18637 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18638 +---------------------------------------+
18639 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18640 +---------------------------------------+
18641 old SP->| back chain to caller's caller |
18642 +---------------------------------------+
18644 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18645 given. (But note below and in sysv4.h that we require only 8 and
18646 may round up the size of our stack frame anyways. The historical
18647 reason is early versions of powerpc-linux which didn't properly
18648 align the stack at program startup. A happy side-effect is that
18649 -mno-eabi libraries can be used with -meabi programs.)
18651 The EABI configuration defaults to the V.4 layout. However,
18652 the stack alignment requirements may differ. If -mno-eabi is not
18653 given, the required stack alignment is 8 bytes; if -mno-eabi is
18654 given, the required alignment is 16 bytes. (But see V.4 comment
18657 #ifndef ABI_STACK_BOUNDARY
18658 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18661 static rs6000_stack_t
*
18662 rs6000_stack_info (void)
18664 rs6000_stack_t
*info_ptr
= &stack_info
;
18665 int reg_size
= TARGET_32BIT
? 4 : 8;
18669 HOST_WIDE_INT non_fixed_size
;
18670 bool using_static_chain_p
;
18672 if (reload_completed
&& info_ptr
->reload_completed
)
18675 memset (info_ptr
, 0, sizeof (*info_ptr
));
18676 info_ptr
->reload_completed
= reload_completed
;
18680 /* Cache value so we don't rescan instruction chain over and over. */
18681 if (cfun
->machine
->insn_chain_scanned_p
== 0)
18682 cfun
->machine
->insn_chain_scanned_p
18683 = spe_func_has_64bit_regs_p () + 1;
18684 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
18687 /* Select which calling sequence. */
18688 info_ptr
->abi
= DEFAULT_ABI
;
18690 /* Calculate which registers need to be saved & save area size. */
18691 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
18692 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18693 even if it currently looks like we won't. Reload may need it to
18694 get at a constant; if so, it will have already created a constant
18695 pool entry for it. */
18696 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
18697 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
18698 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
18699 && crtl
->uses_const_pool
18700 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18701 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
18703 first_gp
= info_ptr
->first_gp_reg_save
;
18705 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
18707 /* For the SPE, we have an additional upper 32-bits on each GPR.
18708 Ideally we should save the entire 64-bits only when the upper
18709 half is used in SIMD instructions. Since we only record
18710 registers live (not the size they are used in), this proves
18711 difficult because we'd have to traverse the instruction chain at
18712 the right time, taking reload into account. This is a real pain,
18713 so we opt to save the GPRs in 64-bits always if but one register
18714 gets used in 64-bits. Otherwise, all the registers in the frame
18715 get saved in 32-bits.
18717 So... since when we save all GPRs (except the SP) in 64-bits, the
18718 traditional GP save area will be empty. */
18719 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18720 info_ptr
->gp_size
= 0;
18722 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
18723 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
18725 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
18726 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
18727 - info_ptr
->first_altivec_reg_save
);
18729 /* Does this function call anything? */
18730 info_ptr
->calls_p
= (! current_function_is_leaf
18731 || cfun
->machine
->ra_needs_full_frame
);
18733 /* Determine if we need to save the condition code registers. */
18734 if (df_regs_ever_live_p (CR2_REGNO
)
18735 || df_regs_ever_live_p (CR3_REGNO
)
18736 || df_regs_ever_live_p (CR4_REGNO
))
18738 info_ptr
->cr_save_p
= 1;
18739 if (DEFAULT_ABI
== ABI_V4
)
18740 info_ptr
->cr_size
= reg_size
;
18743 /* If the current function calls __builtin_eh_return, then we need
18744 to allocate stack space for registers that will hold data for
18745 the exception handler. */
18746 if (crtl
->calls_eh_return
)
18749 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
18752 /* SPE saves EH registers in 64-bits. */
18753 ehrd_size
= i
* (TARGET_SPE_ABI
18754 && info_ptr
->spe_64bit_regs_used
!= 0
18755 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
18760 /* Determine various sizes. */
18761 info_ptr
->reg_size
= reg_size
;
18762 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
18763 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
18764 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
18765 TARGET_ALTIVEC
? 16 : 8);
18766 if (FRAME_GROWS_DOWNWARD
)
18767 info_ptr
->vars_size
18768 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
18769 + info_ptr
->parm_size
,
18770 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
18771 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
18772 + info_ptr
->parm_size
);
18774 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18775 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
18777 info_ptr
->spe_gp_size
= 0;
18779 if (TARGET_ALTIVEC_ABI
)
18780 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18782 info_ptr
->vrsave_mask
= 0;
18784 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
18785 info_ptr
->vrsave_size
= 4;
18787 info_ptr
->vrsave_size
= 0;
18789 compute_save_world_info (info_ptr
);
18791 /* Calculate the offsets. */
18792 switch (DEFAULT_ABI
)
18796 gcc_unreachable ();
18800 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18801 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18803 if (TARGET_ALTIVEC_ABI
)
18805 info_ptr
->vrsave_save_offset
18806 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
18808 /* Align stack so vector save area is on a quadword boundary.
18809 The padding goes above the vectors. */
18810 if (info_ptr
->altivec_size
!= 0)
18811 info_ptr
->altivec_padding_size
18812 = info_ptr
->vrsave_save_offset
& 0xF;
18814 info_ptr
->altivec_padding_size
= 0;
18816 info_ptr
->altivec_save_offset
18817 = info_ptr
->vrsave_save_offset
18818 - info_ptr
->altivec_padding_size
18819 - info_ptr
->altivec_size
;
18820 gcc_assert (info_ptr
->altivec_size
== 0
18821 || info_ptr
->altivec_save_offset
% 16 == 0);
18823 /* Adjust for AltiVec case. */
18824 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
18827 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
18828 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
18829 info_ptr
->lr_save_offset
= 2*reg_size
;
18833 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18834 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18835 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
18837 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18839 /* Align stack so SPE GPR save area is aligned on a
18840 double-word boundary. */
18841 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
18842 info_ptr
->spe_padding_size
18843 = 8 - (-info_ptr
->cr_save_offset
% 8);
18845 info_ptr
->spe_padding_size
= 0;
18847 info_ptr
->spe_gp_save_offset
18848 = info_ptr
->cr_save_offset
18849 - info_ptr
->spe_padding_size
18850 - info_ptr
->spe_gp_size
;
18852 /* Adjust for SPE case. */
18853 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
18855 else if (TARGET_ALTIVEC_ABI
)
18857 info_ptr
->vrsave_save_offset
18858 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
18860 /* Align stack so vector save area is on a quadword boundary. */
18861 if (info_ptr
->altivec_size
!= 0)
18862 info_ptr
->altivec_padding_size
18863 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
18865 info_ptr
->altivec_padding_size
= 0;
18867 info_ptr
->altivec_save_offset
18868 = info_ptr
->vrsave_save_offset
18869 - info_ptr
->altivec_padding_size
18870 - info_ptr
->altivec_size
;
18872 /* Adjust for AltiVec case. */
18873 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
18876 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
18877 info_ptr
->ehrd_offset
-= ehrd_size
;
18878 info_ptr
->lr_save_offset
= reg_size
;
18882 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
18883 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
18884 + info_ptr
->gp_size
18885 + info_ptr
->altivec_size
18886 + info_ptr
->altivec_padding_size
18887 + info_ptr
->spe_gp_size
18888 + info_ptr
->spe_padding_size
18890 + info_ptr
->cr_size
18891 + info_ptr
->vrsave_size
,
18894 non_fixed_size
= (info_ptr
->vars_size
18895 + info_ptr
->parm_size
18896 + info_ptr
->save_size
);
18898 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
18899 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
18901 /* Determine if we need to save the link register. */
18902 if (info_ptr
->calls_p
18903 || (DEFAULT_ABI
== ABI_AIX
18905 && !TARGET_PROFILE_KERNEL
)
18906 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
18907 #ifdef TARGET_RELOCATABLE
18908 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
18910 || rs6000_ra_ever_killed ())
18911 info_ptr
->lr_save_p
= 1;
18913 using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
18914 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
18915 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
18916 info_ptr
->savres_strategy
= rs6000_savres_strategy (info_ptr
,
18917 using_static_chain_p
);
18919 if (!(info_ptr
->savres_strategy
& SAVE_INLINE_GPRS
)
18920 || !(info_ptr
->savres_strategy
& SAVE_INLINE_FPRS
)
18921 || !(info_ptr
->savres_strategy
& REST_INLINE_GPRS
)
18922 || !(info_ptr
->savres_strategy
& REST_INLINE_FPRS
))
18923 info_ptr
->lr_save_p
= 1;
18925 if (info_ptr
->lr_save_p
)
18926 df_set_regs_ever_live (LR_REGNO
, true);
18928 /* Determine if we need to allocate any stack frame:
18930 For AIX we need to push the stack if a frame pointer is needed
18931 (because the stack might be dynamically adjusted), if we are
18932 debugging, if we make calls, or if the sum of fp_save, gp_save,
18933 and local variables are more than the space needed to save all
18934 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18935 + 18*8 = 288 (GPR13 reserved).
18937 For V.4 we don't have the stack cushion that AIX uses, but assume
18938 that the debugger can handle stackless frames. */
18940 if (info_ptr
->calls_p
)
18941 info_ptr
->push_p
= 1;
18943 else if (DEFAULT_ABI
== ABI_V4
)
18944 info_ptr
->push_p
= non_fixed_size
!= 0;
18946 else if (frame_pointer_needed
)
18947 info_ptr
->push_p
= 1;
18949 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
18950 info_ptr
->push_p
= 1;
18953 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
18955 /* Zero offsets if we're not saving those registers. */
18956 if (info_ptr
->fp_size
== 0)
18957 info_ptr
->fp_save_offset
= 0;
18959 if (info_ptr
->gp_size
== 0)
18960 info_ptr
->gp_save_offset
= 0;
18962 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
18963 info_ptr
->altivec_save_offset
= 0;
18965 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
18966 info_ptr
->vrsave_save_offset
= 0;
18968 if (! TARGET_SPE_ABI
18969 || info_ptr
->spe_64bit_regs_used
== 0
18970 || info_ptr
->spe_gp_size
== 0)
18971 info_ptr
->spe_gp_save_offset
= 0;
18973 if (! info_ptr
->lr_save_p
)
18974 info_ptr
->lr_save_offset
= 0;
18976 if (! info_ptr
->cr_save_p
)
18977 info_ptr
->cr_save_offset
= 0;
18982 /* Return true if the current function uses any GPRs in 64-bit SIMD
18986 spe_func_has_64bit_regs_p (void)
18990 /* Functions that save and restore all the call-saved registers will
18991 need to save/restore the registers in 64-bits. */
18992 if (crtl
->calls_eh_return
18993 || cfun
->calls_setjmp
18994 || crtl
->has_nonlocal_goto
)
18997 insns
= get_insns ();
18999 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
19005 /* FIXME: This should be implemented with attributes...
19007 (set_attr "spe64" "true")....then,
19008 if (get_spe64(insn)) return true;
19010 It's the only reliable way to do the stuff below. */
19012 i
= PATTERN (insn
);
19013 if (GET_CODE (i
) == SET
)
19015 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
19017 if (SPE_VECTOR_MODE (mode
))
19019 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
19029 debug_stack_info (rs6000_stack_t
*info
)
19031 const char *abi_string
;
19034 info
= rs6000_stack_info ();
19036 fprintf (stderr
, "\nStack information for function %s:\n",
19037 ((current_function_decl
&& DECL_NAME (current_function_decl
))
19038 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
19043 default: abi_string
= "Unknown"; break;
19044 case ABI_NONE
: abi_string
= "NONE"; break;
19045 case ABI_AIX
: abi_string
= "AIX"; break;
19046 case ABI_DARWIN
: abi_string
= "Darwin"; break;
19047 case ABI_V4
: abi_string
= "V.4"; break;
19050 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
19052 if (TARGET_ALTIVEC_ABI
)
19053 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
19055 if (TARGET_SPE_ABI
)
19056 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
19058 if (info
->first_gp_reg_save
!= 32)
19059 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
19061 if (info
->first_fp_reg_save
!= 64)
19062 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
19064 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
19065 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
19066 info
->first_altivec_reg_save
);
19068 if (info
->lr_save_p
)
19069 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
19071 if (info
->cr_save_p
)
19072 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
19074 if (info
->vrsave_mask
)
19075 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
19078 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
19081 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
19083 if (info
->gp_save_offset
)
19084 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
19086 if (info
->fp_save_offset
)
19087 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
19089 if (info
->altivec_save_offset
)
19090 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
19091 info
->altivec_save_offset
);
19093 if (info
->spe_gp_save_offset
)
19094 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
19095 info
->spe_gp_save_offset
);
19097 if (info
->vrsave_save_offset
)
19098 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
19099 info
->vrsave_save_offset
);
19101 if (info
->lr_save_offset
)
19102 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
19104 if (info
->cr_save_offset
)
19105 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
19107 if (info
->varargs_save_offset
)
19108 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
19110 if (info
->total_size
)
19111 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
19114 if (info
->vars_size
)
19115 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
19118 if (info
->parm_size
)
19119 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
19121 if (info
->fixed_size
)
19122 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
19125 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
19127 if (info
->spe_gp_size
)
19128 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
19131 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
19133 if (info
->altivec_size
)
19134 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
19136 if (info
->vrsave_size
)
19137 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
19139 if (info
->altivec_padding_size
)
19140 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
19141 info
->altivec_padding_size
);
19143 if (info
->spe_padding_size
)
19144 fprintf (stderr
, "\tspe_padding_size = %5d\n",
19145 info
->spe_padding_size
);
19148 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
19150 if (info
->save_size
)
19151 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
19153 if (info
->reg_size
!= 4)
19154 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
19156 fprintf (stderr
, "\n");
19160 rs6000_return_addr (int count
, rtx frame
)
19162 /* Currently we don't optimize very well between prolog and body
19163 code and for PIC code the code can be actually quite bad, so
19164 don't try to be too clever here. */
19165 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
19167 cfun
->machine
->ra_needs_full_frame
= 1;
19174 plus_constant (copy_to_reg
19175 (gen_rtx_MEM (Pmode
,
19176 memory_address (Pmode
, frame
))),
19177 RETURN_ADDRESS_OFFSET
)));
19180 cfun
->machine
->ra_need_lr
= 1;
19181 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
19184 /* Say whether a function is a candidate for sibcall handling or not. */
19187 rs6000_function_ok_for_sibcall (tree decl
, tree exp
)
19192 fntype
= TREE_TYPE (decl
);
19194 fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp
)));
19196 /* We can't do it if the called function has more vector parameters
19197 than the current function; there's nowhere to put the VRsave code. */
19198 if (TARGET_ALTIVEC_ABI
19199 && TARGET_ALTIVEC_VRSAVE
19200 && !(decl
&& decl
== current_function_decl
))
19202 function_args_iterator args_iter
;
19206 /* Functions with vector parameters are required to have a
19207 prototype, so the argument type info must be available
19209 FOREACH_FUNCTION_ARGS(fntype
, type
, args_iter
)
19210 if (TREE_CODE (type
) == VECTOR_TYPE
19211 && (ALTIVEC_VECTOR_MODE (TYPE_MODE (type
))
19212 || VSX_VECTOR_MODE (TYPE_MODE (type
))))
19215 FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl
), type
, args_iter
)
19216 if (TREE_CODE (type
) == VECTOR_TYPE
19217 && (ALTIVEC_VECTOR_MODE (TYPE_MODE (type
))
19218 || VSX_VECTOR_MODE (TYPE_MODE (type
))))
19225 /* Under the AIX ABI we can't allow calls to non-local functions,
19226 because the callee may have a different TOC pointer to the
19227 caller and there's no way to ensure we restore the TOC when we
19228 return. With the secure-plt SYSV ABI we can't make non-local
19229 calls when -fpic/PIC because the plt call stubs use r30. */
19230 if (DEFAULT_ABI
== ABI_DARWIN
19231 || (DEFAULT_ABI
== ABI_AIX
19233 && !DECL_EXTERNAL (decl
)
19234 && (*targetm
.binds_local_p
) (decl
))
19235 || (DEFAULT_ABI
== ABI_V4
19236 && (!TARGET_SECURE_PLT
19239 && (*targetm
.binds_local_p
) (decl
)))))
19241 tree attr_list
= TYPE_ATTRIBUTES (fntype
);
19243 if (!lookup_attribute ("longcall", attr_list
)
19244 || lookup_attribute ("shortcall", attr_list
))
19251 /* NULL if INSN insn is valid within a low-overhead loop.
19252 Otherwise return why doloop cannot be applied.
19253 PowerPC uses the COUNT register for branch on table instructions. */
19255 static const char *
19256 rs6000_invalid_within_doloop (const_rtx insn
)
19259 return "Function call in the loop.";
19262 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
19263 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
19264 return "Computed branch in the loop.";
19270 rs6000_ra_ever_killed (void)
19276 if (cfun
->is_thunk
)
19279 if (cfun
->machine
->lr_save_state
)
19280 return cfun
->machine
->lr_save_state
- 1;
19282 /* regs_ever_live has LR marked as used if any sibcalls are present,
19283 but this should not force saving and restoring in the
19284 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19285 clobbers LR, so that is inappropriate. */
19287 /* Also, the prologue can generate a store into LR that
19288 doesn't really count, like this:
19291 bcl to set PIC register
19295 When we're called from the epilogue, we need to avoid counting
19296 this as a store. */
19298 push_topmost_sequence ();
19299 top
= get_insns ();
19300 pop_topmost_sequence ();
19301 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
19303 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
19309 if (!SIBLING_CALL_P (insn
))
19312 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
19314 else if (set_of (reg
, insn
) != NULL_RTX
19315 && !prologue_epilogue_contains (insn
))
19322 /* Emit instructions needed to load the TOC register.
19323 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19324 a constant pool; or for SVR4 -fpic. */
19327 rs6000_emit_load_toc_table (int fromprolog
)
19330 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
19332 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
19335 rtx lab
, tmp1
, tmp2
, got
;
19337 lab
= gen_label_rtx ();
19338 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (lab
));
19339 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19341 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
19343 got
= rs6000_got_sym ();
19344 tmp1
= tmp2
= dest
;
19347 tmp1
= gen_reg_rtx (Pmode
);
19348 tmp2
= gen_reg_rtx (Pmode
);
19350 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
19351 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
19352 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
19353 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
19355 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
19357 emit_insn (gen_load_toc_v4_pic_si ());
19358 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19360 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
19363 rtx temp0
= (fromprolog
19364 ? gen_rtx_REG (Pmode
, 0)
19365 : gen_reg_rtx (Pmode
));
19371 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
19372 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19374 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
19375 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19377 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
19378 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19379 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
19385 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
19386 lab
= gen_label_rtx ();
19387 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
, lab
));
19388 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19389 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
19391 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
19393 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
19395 /* This is for AIX code running in non-PIC ELF32. */
19398 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
19399 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19401 emit_insn (gen_elf_high (dest
, realsym
));
19402 emit_insn (gen_elf_low (dest
, dest
, realsym
));
19406 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
19409 emit_insn (gen_load_toc_aix_si (dest
));
19411 emit_insn (gen_load_toc_aix_di (dest
));
19415 /* Emit instructions to restore the link register after determining where
19416 its value has been stored. */
19419 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
19421 rs6000_stack_t
*info
= rs6000_stack_info ();
19424 operands
[0] = source
;
19425 operands
[1] = scratch
;
19427 if (info
->lr_save_p
)
19429 rtx frame_rtx
= stack_pointer_rtx
;
19430 HOST_WIDE_INT sp_offset
= 0;
19433 if (frame_pointer_needed
19434 || cfun
->calls_alloca
19435 || info
->total_size
> 32767)
19437 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
19438 emit_move_insn (operands
[1], tmp
);
19439 frame_rtx
= operands
[1];
19441 else if (info
->push_p
)
19442 sp_offset
= info
->total_size
;
19444 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
19445 tmp
= gen_frame_mem (Pmode
, tmp
);
19446 emit_move_insn (tmp
, operands
[0]);
19449 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
19451 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19452 state of lr_save_p so any change from here on would be a bug. In
19453 particular, stop rs6000_ra_ever_killed from considering the SET
19454 of lr we may have added just above. */
19455 cfun
->machine
->lr_save_state
= info
->lr_save_p
+ 1;
19458 static GTY(()) alias_set_type set
= -1;
19461 get_TOC_alias_set (void)
19464 set
= new_alias_set ();
19468 /* This returns nonzero if the current function uses the TOC. This is
19469 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19470 is generated by the ABI_V4 load_toc_* patterns. */
19477 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
19480 rtx pat
= PATTERN (insn
);
19483 if (GET_CODE (pat
) == PARALLEL
)
19484 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19486 rtx sub
= XVECEXP (pat
, 0, i
);
19487 if (GET_CODE (sub
) == USE
)
19489 sub
= XEXP (sub
, 0);
19490 if (GET_CODE (sub
) == UNSPEC
19491 && XINT (sub
, 1) == UNSPEC_TOC
)
19501 create_TOC_reference (rtx symbol
, rtx largetoc_reg
)
19503 rtx tocrel
, tocreg
;
19505 if (TARGET_DEBUG_ADDR
)
19507 if (GET_CODE (symbol
) == SYMBOL_REF
)
19508 fprintf (stderr
, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19512 fprintf (stderr
, "\ncreate_TOC_reference, code %s:\n",
19513 GET_RTX_NAME (GET_CODE (symbol
)));
19514 debug_rtx (symbol
);
19518 if (!can_create_pseudo_p ())
19519 df_set_regs_ever_live (TOC_REGISTER
, true);
19521 tocrel
= gen_rtx_CONST (Pmode
,
19522 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
),
19524 tocreg
= gen_rtx_REG (Pmode
, TOC_REGISTER
);
19525 if (TARGET_CMODEL
!= CMODEL_SMALL
)
19527 rtx hi
= gen_rtx_PLUS (Pmode
, tocreg
, gen_rtx_HIGH (Pmode
, tocrel
));
19528 if (largetoc_reg
!= NULL
)
19530 emit_move_insn (largetoc_reg
, hi
);
19533 return gen_rtx_LO_SUM (Pmode
, hi
, copy_rtx (tocrel
));
19536 return gen_rtx_PLUS (Pmode
, tocreg
, tocrel
);
19539 /* Issue assembly directives that create a reference to the given DWARF
19540 FRAME_TABLE_LABEL from the current function section. */
19542 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label
)
19544 fprintf (asm_out_file
, "\t.ref %s\n",
19545 TARGET_STRIP_NAME_ENCODING (frame_table_label
));
19548 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19549 and the change to the stack pointer. */
19552 rs6000_emit_stack_tie (void)
19554 rtx mem
= gen_frame_mem (BLKmode
,
19555 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
19557 emit_insn (gen_stack_tie (mem
));
19560 /* Emit the correct code for allocating stack space, as insns.
19561 If COPY_REG, make sure a copy of the old frame is left there.
19562 The generated code may use hard register 0 as a temporary. */
19565 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, rtx copy_reg
)
19568 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19569 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
19570 rtx todec
= gen_int_mode (-size
, Pmode
);
19573 if (INTVAL (todec
) != -size
)
19575 warning (0, "stack frame too large");
19576 emit_insn (gen_trap ());
19580 if (crtl
->limit_stack
)
19582 if (REG_P (stack_limit_rtx
)
19583 && REGNO (stack_limit_rtx
) > 1
19584 && REGNO (stack_limit_rtx
) <= 31)
19586 emit_insn (gen_add3_insn (tmp_reg
, stack_limit_rtx
, GEN_INT (size
)));
19587 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19590 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
19592 && DEFAULT_ABI
== ABI_V4
)
19594 rtx toload
= gen_rtx_CONST (VOIDmode
,
19595 gen_rtx_PLUS (Pmode
,
19599 emit_insn (gen_elf_high (tmp_reg
, toload
));
19600 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
19601 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19605 warning (0, "stack limit expression is not supported");
19609 emit_move_insn (copy_reg
, stack_reg
);
19613 /* Need a note here so that try_split doesn't get confused. */
19614 if (get_last_insn () == NULL_RTX
)
19615 emit_note (NOTE_INSN_DELETED
);
19616 insn
= emit_move_insn (tmp_reg
, todec
);
19617 try_split (PATTERN (insn
), insn
, 0);
19621 insn
= emit_insn (TARGET_32BIT
19622 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
19624 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
19625 todec
, stack_reg
));
19626 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19627 it now and set the alias set/attributes. The above gen_*_update
19628 calls will generate a PARALLEL with the MEM set being the first
19630 par
= PATTERN (insn
);
19631 gcc_assert (GET_CODE (par
) == PARALLEL
);
19632 set
= XVECEXP (par
, 0, 0);
19633 gcc_assert (GET_CODE (set
) == SET
);
19634 mem
= SET_DEST (set
);
19635 gcc_assert (MEM_P (mem
));
19636 MEM_NOTRAP_P (mem
) = 1;
19637 set_mem_alias_set (mem
, get_frame_alias_set ());
19639 RTX_FRAME_RELATED_P (insn
) = 1;
19640 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
19641 gen_rtx_SET (VOIDmode
, stack_reg
,
19642 gen_rtx_PLUS (Pmode
, stack_reg
,
19643 GEN_INT (-size
))));
19646 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19648 #if PROBE_INTERVAL > 32768
19649 #error Cannot use indexed addressing mode for stack probing
19652 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19653 inclusive. These are offsets from the current stack pointer. */
19656 rs6000_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
19658 /* See if we have a constant small number of probes to generate. If so,
19659 that's the easy case. */
19660 if (first
+ size
<= 32768)
19664 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19665 it exceeds SIZE. If only one probe is needed, this will not
19666 generate any code. Then probe at FIRST + SIZE. */
19667 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
19668 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ i
)));
19670 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ size
)));
19673 /* Otherwise, do the same as above, but in a loop. Note that we must be
19674 extra careful with variables wrapping around because we might be at
19675 the very top (or the very bottom) of the address space and we have
19676 to be able to handle this case properly; in particular, we use an
19677 equality test for the loop condition. */
19680 HOST_WIDE_INT rounded_size
;
19681 rtx r12
= gen_rtx_REG (Pmode
, 12);
19682 rtx r0
= gen_rtx_REG (Pmode
, 0);
19684 /* Sanity check for the addressing mode we're going to use. */
19685 gcc_assert (first
<= 32768);
19687 /* Step 1: round SIZE to the previous multiple of the interval. */
19689 rounded_size
= size
& -PROBE_INTERVAL
;
19692 /* Step 2: compute initial and final value of the loop counter. */
19694 /* TEST_ADDR = SP + FIRST. */
19695 emit_insn (gen_rtx_SET (VOIDmode
, r12
,
19696 plus_constant (stack_pointer_rtx
, -first
)));
19698 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19699 if (rounded_size
> 32768)
19701 emit_move_insn (r0
, GEN_INT (-rounded_size
));
19702 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19703 gen_rtx_PLUS (Pmode
, r12
, r0
)));
19706 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19707 plus_constant (r12
, -rounded_size
)));
19710 /* Step 3: the loop
19712 while (TEST_ADDR != LAST_ADDR)
19714 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19718 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19719 until it is equal to ROUNDED_SIZE. */
19722 emit_insn (gen_probe_stack_rangedi (r12
, r12
, r0
));
19724 emit_insn (gen_probe_stack_rangesi (r12
, r12
, r0
));
19727 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19728 that SIZE is equal to ROUNDED_SIZE. */
19730 if (size
!= rounded_size
)
19731 emit_stack_probe (plus_constant (r12
, rounded_size
- size
));
19735 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19736 absolute addresses. */
19739 output_probe_stack_range (rtx reg1
, rtx reg2
)
19741 static int labelno
= 0;
19742 char loop_lab
[32], end_lab
[32];
19745 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
);
19746 ASM_GENERATE_INTERNAL_LABEL (end_lab
, "LPSRE", labelno
++);
19748 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
19750 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19754 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops
);
19756 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops
);
19758 fputs ("\tbeq 0,", asm_out_file
);
19759 assemble_name_raw (asm_out_file
, end_lab
);
19760 fputc ('\n', asm_out_file
);
19762 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19763 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
19764 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops
);
19766 /* Probe at TEST_ADDR and branch. */
19767 output_asm_insn ("{st|stw} 0,0(%0)", xops
);
19768 fprintf (asm_out_file
, "\tb ");
19769 assemble_name_raw (asm_out_file
, loop_lab
);
19770 fputc ('\n', asm_out_file
);
19772 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, end_lab
);
19777 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19778 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19779 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19780 deduce these equivalences by itself so it wasn't necessary to hold
19781 its hand so much. */
19784 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
19785 rtx reg2
, rtx rreg
)
19789 /* copy_rtx will not make unique copies of registers, so we need to
19790 ensure we don't have unwanted sharing here. */
19792 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19795 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19797 real
= copy_rtx (PATTERN (insn
));
19799 if (reg2
!= NULL_RTX
)
19800 real
= replace_rtx (real
, reg2
, rreg
);
19802 real
= replace_rtx (real
, reg
,
19803 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
19804 STACK_POINTER_REGNUM
),
19807 /* We expect that 'real' is either a SET or a PARALLEL containing
19808 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19809 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19811 if (GET_CODE (real
) == SET
)
19815 temp
= simplify_rtx (SET_SRC (set
));
19817 SET_SRC (set
) = temp
;
19818 temp
= simplify_rtx (SET_DEST (set
));
19820 SET_DEST (set
) = temp
;
19821 if (GET_CODE (SET_DEST (set
)) == MEM
)
19823 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19825 XEXP (SET_DEST (set
), 0) = temp
;
19832 gcc_assert (GET_CODE (real
) == PARALLEL
);
19833 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
19834 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
19836 rtx set
= XVECEXP (real
, 0, i
);
19838 temp
= simplify_rtx (SET_SRC (set
));
19840 SET_SRC (set
) = temp
;
19841 temp
= simplify_rtx (SET_DEST (set
));
19843 SET_DEST (set
) = temp
;
19844 if (GET_CODE (SET_DEST (set
)) == MEM
)
19846 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19848 XEXP (SET_DEST (set
), 0) = temp
;
19850 RTX_FRAME_RELATED_P (set
) = 1;
19854 RTX_FRAME_RELATED_P (insn
) = 1;
19855 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
19858 /* Returns an insn that has a vrsave set operation with the
19859 appropriate CLOBBERs. */
19862 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
19865 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
19866 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
19869 = gen_rtx_SET (VOIDmode
,
19871 gen_rtx_UNSPEC_VOLATILE (SImode
,
19872 gen_rtvec (2, reg
, vrsave
),
19873 UNSPECV_SET_VRSAVE
));
19877 /* We need to clobber the registers in the mask so the scheduler
19878 does not move sets to VRSAVE before sets of AltiVec registers.
19880 However, if the function receives nonlocal gotos, reload will set
19881 all call saved registers live. We will end up with:
19883 (set (reg 999) (mem))
19884 (parallel [ (set (reg vrsave) (unspec blah))
19885 (clobber (reg 999))])
19887 The clobber will cause the store into reg 999 to be dead, and
19888 flow will attempt to delete an epilogue insn. In this case, we
19889 need an unspec use/set of the register. */
19891 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
19892 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
19894 if (!epiloguep
|| call_used_regs
[i
])
19895 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
19896 gen_rtx_REG (V4SImode
, i
));
19899 rtx reg
= gen_rtx_REG (V4SImode
, i
);
19902 = gen_rtx_SET (VOIDmode
,
19904 gen_rtx_UNSPEC (V4SImode
,
19905 gen_rtvec (1, reg
), 27));
19909 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
19911 for (i
= 0; i
< nclobs
; ++i
)
19912 XVECEXP (insn
, 0, i
) = clobs
[i
];
19917 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19918 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19921 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
19922 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
19924 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
19925 rtx replacea
, replaceb
;
19927 int_rtx
= GEN_INT (offset
);
19929 /* Some cases that need register indexed addressing. */
19930 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
19931 || (TARGET_VSX
&& VSX_VECTOR_MODE (mode
))
19932 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
19934 && SPE_VECTOR_MODE (mode
)
19935 && !SPE_CONST_OFFSET_OK (offset
)))
19937 /* Whomever calls us must make sure r11 is available in the
19938 flow path of instructions in the prologue. */
19939 offset_rtx
= gen_rtx_REG (Pmode
, 11);
19940 emit_move_insn (offset_rtx
, int_rtx
);
19942 replacea
= offset_rtx
;
19943 replaceb
= int_rtx
;
19947 offset_rtx
= int_rtx
;
19948 replacea
= NULL_RTX
;
19949 replaceb
= NULL_RTX
;
19952 reg
= gen_rtx_REG (mode
, regno
);
19953 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
19954 mem
= gen_frame_mem (mode
, addr
);
19956 insn
= emit_move_insn (mem
, reg
);
19958 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
19961 /* Emit an offset memory reference suitable for a frame store, while
19962 converting to a valid addressing mode. */
19965 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
19967 rtx int_rtx
, offset_rtx
;
19969 int_rtx
= GEN_INT (offset
);
19971 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
19972 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
19974 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
19975 emit_move_insn (offset_rtx
, int_rtx
);
19978 offset_rtx
= int_rtx
;
19980 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
19983 /* Look for user-defined global regs. We should not save and restore these,
19984 and cannot use stmw/lmw if there are any in its range. */
19987 no_global_regs_above (int first
, bool gpr
)
19990 int last
= gpr
? 32 : 64;
19991 for (i
= first
; i
< last
; i
++)
19992 if (global_regs
[i
])
19997 #ifndef TARGET_FIX_AND_CONTINUE
19998 #define TARGET_FIX_AND_CONTINUE 0
20001 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20002 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20003 #define LAST_SAVRES_REGISTER 31
20004 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20006 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
20008 /* Temporary holding space for an out-of-line register save/restore
20010 static char savres_routine_name
[30];
20012 /* Return the name for an out-of-line register save/restore routine.
20013 We are saving/restoring GPRs if GPR is true. */
20016 rs6000_savres_routine_name (rs6000_stack_t
*info
, int regno
,
20017 bool savep
, bool gpr
, bool lr
)
20019 const char *prefix
= "";
20020 const char *suffix
= "";
20022 /* Different targets are supposed to define
20023 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20024 routine name could be defined with:
20026 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20028 This is a nice idea in practice, but in reality, things are
20029 complicated in several ways:
20031 - ELF targets have save/restore routines for GPRs.
20033 - SPE targets use different prefixes for 32/64-bit registers, and
20034 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20036 - PPC64 ELF targets have routines for save/restore of GPRs that
20037 differ in what they do with the link register, so having a set
20038 prefix doesn't work. (We only use one of the save routines at
20039 the moment, though.)
20041 - PPC32 elf targets have "exit" versions of the restore routines
20042 that restore the link register and can save some extra space.
20043 These require an extra suffix. (There are also "tail" versions
20044 of the restore routines and "GOT" versions of the save routines,
20045 but we don't generate those at present. Same problems apply,
20048 We deal with all this by synthesizing our own prefix/suffix and
20049 using that for the simple sprintf call shown above. */
20052 /* No floating point saves on the SPE. */
20056 prefix
= info
->spe_64bit_regs_used
? "_save64gpr_" : "_save32gpr_";
20058 prefix
= info
->spe_64bit_regs_used
? "_rest64gpr_" : "_rest32gpr_";
20063 else if (DEFAULT_ABI
== ABI_V4
)
20069 prefix
= savep
? "_savegpr_" : "_restgpr_";
20071 prefix
= savep
? "_savefpr_" : "_restfpr_";
20076 else if (DEFAULT_ABI
== ABI_AIX
)
20078 #ifndef POWERPC_LINUX
20079 /* No out-of-line save/restore routines for GPRs on AIX. */
20080 gcc_assert (!TARGET_AIX
|| !gpr
);
20086 ? (lr
? "_savegpr0_" : "_savegpr1_")
20087 : (lr
? "_restgpr0_" : "_restgpr1_"));
20088 #ifdef POWERPC_LINUX
20090 prefix
= (savep
? "_savefpr_" : "_restfpr_");
20094 prefix
= savep
? SAVE_FP_PREFIX
: RESTORE_FP_PREFIX
;
20095 suffix
= savep
? SAVE_FP_SUFFIX
: RESTORE_FP_SUFFIX
;
20098 else if (DEFAULT_ABI
== ABI_DARWIN
)
20099 sorry ("out-of-line save/restore routines not supported on Darwin");
20101 sprintf (savres_routine_name
, "%s%d%s", prefix
, regno
, suffix
);
20103 return savres_routine_name
;
20106 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20107 We are saving/restoring GPRs if GPR is true. */
20110 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
,
20113 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
20115 int select
= ((savep
? 1 : 0) << 2
20117 /* On the SPE, we never have any FPRs, but we do have
20118 32/64-bit versions of the routines. */
20119 ? (info
->spe_64bit_regs_used
? 1 : 0)
20120 : (gpr
? 1 : 0)) << 1)
20123 /* Don't generate bogus routine names. */
20124 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
20125 && regno
<= LAST_SAVRES_REGISTER
);
20127 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
20133 name
= rs6000_savres_routine_name (info
, regno
, savep
, gpr
, lr
);
20135 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
20136 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
20137 SYMBOL_REF_FLAGS (sym
) |= SYMBOL_FLAG_FUNCTION
;
20143 /* Emit a sequence of insns, including a stack tie if needed, for
20144 resetting the stack pointer. If SAVRES is true, then don't reset the
20145 stack pointer, but move the base of the frame into r11 for use by
20146 out-of-line register restore routines. */
20149 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
20150 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
20151 int sp_offset
, bool savres
)
20153 /* This blockage is needed so that sched doesn't decide to move
20154 the sp change before the register restores. */
20155 if (frame_reg_rtx
!= sp_reg_rtx
20157 && info
->spe_64bit_regs_used
!= 0
20158 && info
->first_gp_reg_save
!= 32))
20159 rs6000_emit_stack_tie ();
20161 if (frame_reg_rtx
!= sp_reg_rtx
)
20163 if (sp_offset
!= 0)
20165 rtx dest_reg
= savres
? gen_rtx_REG (Pmode
, 11) : sp_reg_rtx
;
20166 return emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
,
20167 GEN_INT (sp_offset
)));
20170 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
20172 else if (sp_offset
!= 0)
20174 /* If we are restoring registers out-of-line, we will be using the
20175 "exit" variants of the restore routines, which will reset the
20176 stack for us. But we do need to point r11 into the right place
20177 for those routines. */
20178 rtx dest_reg
= (savres
20179 ? gen_rtx_REG (Pmode
, 11)
20182 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
20183 GEN_INT (sp_offset
)));
20190 /* Construct a parallel rtx describing the effect of a call to an
20191 out-of-line register save/restore routine. */
20194 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
20195 rtx frame_reg_rtx
, int save_area_offset
,
20196 enum machine_mode reg_mode
,
20197 bool savep
, bool gpr
, bool lr
)
20200 int offset
, start_reg
, end_reg
, n_regs
;
20201 int reg_size
= GET_MODE_SIZE (reg_mode
);
20207 ? info
->first_gp_reg_save
20208 : info
->first_fp_reg_save
);
20209 end_reg
= gpr
? 32 : 64;
20210 n_regs
= end_reg
- start_reg
;
20211 p
= rtvec_alloc ((lr
? 4 : 3) + n_regs
);
20214 RTVEC_ELT (p
, offset
++) = ret_rtx
;
20216 RTVEC_ELT (p
, offset
++)
20217 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
20219 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, lr
);
20220 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
20221 RTVEC_ELT (p
, offset
++)
20222 = gen_rtx_USE (VOIDmode
,
20223 gen_rtx_REG (Pmode
, DEFAULT_ABI
!= ABI_AIX
? 11
20227 for (i
= 0; i
< end_reg
- start_reg
; i
++)
20229 rtx addr
, reg
, mem
;
20230 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
20231 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20232 GEN_INT (save_area_offset
+ reg_size
*i
));
20233 mem
= gen_frame_mem (reg_mode
, addr
);
20235 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
20237 savep
? reg
: mem
);
20242 rtx addr
, reg
, mem
;
20243 reg
= gen_rtx_REG (Pmode
, 0);
20244 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20245 GEN_INT (info
->lr_save_offset
));
20246 mem
= gen_frame_mem (Pmode
, addr
);
20247 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20250 return gen_rtx_PARALLEL (VOIDmode
, p
);
20253 /* Determine whether the gp REG is really used. */
20256 rs6000_reg_live_or_pic_offset_p (int reg
)
20258 /* If the function calls eh_return, claim used all the registers that would
20259 be checked for liveness otherwise. This is required for the PIC offset
20260 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20261 register allocation purposes in this case. */
20263 return (((crtl
->calls_eh_return
|| df_regs_ever_live_p (reg
))
20264 && (!call_used_regs
[reg
]
20265 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
20266 && !TARGET_SINGLE_PIC_BASE
20267 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
20268 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
20269 && !TARGET_SINGLE_PIC_BASE
20270 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
20271 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
20274 /* Emit function prologue as insns. */
20277 rs6000_emit_prologue (void)
20279 rs6000_stack_t
*info
= rs6000_stack_info ();
20280 enum machine_mode reg_mode
= Pmode
;
20281 int reg_size
= TARGET_32BIT
? 4 : 8;
20282 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
20283 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
20284 rtx frame_reg_rtx
= sp_reg_rtx
;
20285 rtx cr_save_rtx
= NULL_RTX
;
20288 int saving_FPRs_inline
;
20289 int saving_GPRs_inline
;
20290 int using_store_multiple
;
20291 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
20292 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
20293 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
20294 HOST_WIDE_INT sp_offset
= 0;
20296 if (flag_stack_usage
)
20297 current_function_static_stack_size
= info
->total_size
;
20299 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
&& info
->total_size
)
20300 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT
, info
->total_size
);
20302 if (TARGET_FIX_AND_CONTINUE
)
20304 /* gdb on darwin arranges to forward a function from the old
20305 address by modifying the first 5 instructions of the function
20306 to branch to the overriding function. This is necessary to
20307 permit function pointers that point to the old function to
20308 actually forward to the new function. */
20309 emit_insn (gen_nop ());
20310 emit_insn (gen_nop ());
20311 emit_insn (gen_nop ());
20312 emit_insn (gen_nop ());
20313 emit_insn (gen_nop ());
20316 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
20318 reg_mode
= V2SImode
;
20322 strategy
= info
->savres_strategy
;
20323 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
20324 saving_FPRs_inline
= strategy
& SAVE_INLINE_FPRS
;
20325 saving_GPRs_inline
= strategy
& SAVE_INLINE_GPRS
;
20327 /* For V.4, update stack before we do any saving and set back pointer. */
20328 if (! WORLD_SAVE_P (info
)
20330 && (DEFAULT_ABI
== ABI_V4
20331 || crtl
->calls_eh_return
))
20333 bool need_r11
= (TARGET_SPE
20334 ? (!saving_GPRs_inline
20335 && info
->spe_64bit_regs_used
== 0)
20336 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
20337 rtx copy_reg
= need_r11
? gen_rtx_REG (Pmode
, 11) : NULL
;
20339 if (info
->total_size
< 32767)
20340 sp_offset
= info
->total_size
;
20342 frame_reg_rtx
= copy_reg
;
20343 else if (info
->cr_save_p
20345 || info
->first_fp_reg_save
< 64
20346 || info
->first_gp_reg_save
< 32
20347 || info
->altivec_size
!= 0
20348 || info
->vrsave_mask
!= 0
20349 || crtl
->calls_eh_return
)
20351 copy_reg
= frame_ptr_rtx
;
20352 frame_reg_rtx
= copy_reg
;
20356 /* The prologue won't be saving any regs so there is no need
20357 to set up a frame register to access any frame save area.
20358 We also won't be using sp_offset anywhere below, but set
20359 the correct value anyway to protect against future
20360 changes to this function. */
20361 sp_offset
= info
->total_size
;
20363 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20364 if (frame_reg_rtx
!= sp_reg_rtx
)
20365 rs6000_emit_stack_tie ();
20368 /* Handle world saves specially here. */
20369 if (WORLD_SAVE_P (info
))
20376 /* save_world expects lr in r0. */
20377 reg0
= gen_rtx_REG (Pmode
, 0);
20378 if (info
->lr_save_p
)
20380 insn
= emit_move_insn (reg0
,
20381 gen_rtx_REG (Pmode
, LR_REGNO
));
20382 RTX_FRAME_RELATED_P (insn
) = 1;
20385 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20386 assumptions about the offsets of various bits of the stack
20388 gcc_assert (info
->gp_save_offset
== -220
20389 && info
->fp_save_offset
== -144
20390 && info
->lr_save_offset
== 8
20391 && info
->cr_save_offset
== 4
20394 && (!crtl
->calls_eh_return
20395 || info
->ehrd_offset
== -432)
20396 && info
->vrsave_save_offset
== -224
20397 && info
->altivec_save_offset
== -416);
20399 treg
= gen_rtx_REG (SImode
, 11);
20400 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
20402 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20403 in R11. It also clobbers R12, so beware! */
20405 /* Preserve CR2 for save_world prologues */
20407 sz
+= 32 - info
->first_gp_reg_save
;
20408 sz
+= 64 - info
->first_fp_reg_save
;
20409 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
20410 p
= rtvec_alloc (sz
);
20412 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
20413 gen_rtx_REG (SImode
,
20415 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
20416 gen_rtx_SYMBOL_REF (Pmode
,
20418 /* We do floats first so that the instruction pattern matches
20420 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20422 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20423 ? DFmode
: SFmode
),
20424 info
->first_fp_reg_save
+ i
);
20425 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20426 GEN_INT (info
->fp_save_offset
20427 + sp_offset
+ 8 * i
));
20428 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20429 ? DFmode
: SFmode
), addr
);
20431 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20433 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
20435 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
20436 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20437 GEN_INT (info
->altivec_save_offset
20438 + sp_offset
+ 16 * i
));
20439 rtx mem
= gen_frame_mem (V4SImode
, addr
);
20441 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20443 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20445 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20446 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20447 GEN_INT (info
->gp_save_offset
20448 + sp_offset
+ reg_size
* i
));
20449 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20451 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20455 /* CR register traditionally saved as CR2. */
20456 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
20457 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20458 GEN_INT (info
->cr_save_offset
20460 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20462 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20464 /* Explain about use of R0. */
20465 if (info
->lr_save_p
)
20467 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20468 GEN_INT (info
->lr_save_offset
20470 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20472 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
20474 /* Explain what happens to the stack pointer. */
20476 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
20477 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
20480 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20481 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20482 treg
, GEN_INT (-info
->total_size
));
20483 sp_offset
= info
->total_size
;
20486 /* If we use the link register, get it into r0. */
20487 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
20489 rtx addr
, reg
, mem
;
20491 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
20492 gen_rtx_REG (Pmode
, LR_REGNO
));
20493 RTX_FRAME_RELATED_P (insn
) = 1;
20495 if (!(strategy
& (SAVE_NOINLINE_GPRS_SAVES_LR
20496 | SAVE_NOINLINE_FPRS_SAVES_LR
)))
20498 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20499 GEN_INT (info
->lr_save_offset
+ sp_offset
));
20500 reg
= gen_rtx_REG (Pmode
, 0);
20501 mem
= gen_rtx_MEM (Pmode
, addr
);
20502 /* This should not be of rs6000_sr_alias_set, because of
20503 __builtin_return_address. */
20505 insn
= emit_move_insn (mem
, reg
);
20506 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20507 NULL_RTX
, NULL_RTX
);
20511 /* If we need to save CR, put it into r12 or r11. */
20512 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
20517 = gen_rtx_REG (SImode
, DEFAULT_ABI
== ABI_AIX
&& !saving_GPRs_inline
20519 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20520 RTX_FRAME_RELATED_P (insn
) = 1;
20521 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20522 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20523 But that's OK. All we have to do is specify that _one_ condition
20524 code register is saved in this stack slot. The thrower's epilogue
20525 will then restore all the call-saved registers.
20526 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20527 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
20528 gen_rtx_REG (SImode
, CR2_REGNO
));
20529 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20532 /* Do any required saving of fpr's. If only one or two to save, do
20533 it ourselves. Otherwise, call function. */
20534 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
20537 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20538 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
20539 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
20540 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
20541 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20543 info
->first_fp_reg_save
+ i
,
20544 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
20547 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
20551 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20552 info
->fp_save_offset
+ sp_offset
,
20554 /*savep=*/true, /*gpr=*/false,
20556 & SAVE_NOINLINE_FPRS_SAVES_LR
)
20558 insn
= emit_insn (par
);
20559 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20560 NULL_RTX
, NULL_RTX
);
20563 /* Save GPRs. This is done as a PARALLEL if we are using
20564 the store-multiple instructions. */
20565 if (!WORLD_SAVE_P (info
)
20567 && info
->spe_64bit_regs_used
!= 0
20568 && info
->first_gp_reg_save
!= 32)
20571 rtx spe_save_area_ptr
;
20573 /* Determine whether we can address all of the registers that need
20574 to be saved with an offset from the stack pointer that fits in
20575 the small const field for SPE memory instructions. */
20576 int spe_regs_addressable_via_sp
20577 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
20578 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
20579 && saving_GPRs_inline
);
20582 if (spe_regs_addressable_via_sp
)
20584 spe_save_area_ptr
= frame_reg_rtx
;
20585 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
20589 /* Make r11 point to the start of the SPE save area. We need
20590 to be careful here if r11 is holding the static chain. If
20591 it is, then temporarily save it in r0. We would use r0 as
20592 our base register here, but using r0 as a base register in
20593 loads and stores means something different from what we
20595 int ool_adjust
= (saving_GPRs_inline
20597 : (info
->first_gp_reg_save
20598 - (FIRST_SAVRES_REGISTER
+1))*8);
20599 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
20600 + sp_offset
- ool_adjust
);
20602 if (using_static_chain_p
)
20604 rtx r0
= gen_rtx_REG (Pmode
, 0);
20605 gcc_assert (info
->first_gp_reg_save
> 11);
20607 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
20610 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
20611 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
20613 GEN_INT (offset
)));
20614 /* We need to make sure the move to r11 gets noted for
20615 properly outputting unwind information. */
20616 if (!saving_GPRs_inline
)
20617 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
20618 NULL_RTX
, NULL_RTX
);
20622 if (saving_GPRs_inline
)
20624 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20625 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20627 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20628 rtx offset
, addr
, mem
;
20630 /* We're doing all this to ensure that the offset fits into
20631 the immediate offset of 'evstdd'. */
20632 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
20634 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
20635 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
20636 mem
= gen_rtx_MEM (V2SImode
, addr
);
20638 insn
= emit_move_insn (mem
, reg
);
20640 rs6000_frame_related (insn
, spe_save_area_ptr
,
20641 info
->spe_gp_save_offset
20642 + sp_offset
+ reg_size
* i
,
20643 offset
, const0_rtx
);
20650 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
20652 /*savep=*/true, /*gpr=*/true,
20654 insn
= emit_insn (par
);
20655 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20656 NULL_RTX
, NULL_RTX
);
20660 /* Move the static chain pointer back. */
20661 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
20662 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
20664 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
20668 /* Need to adjust r11 (r12) if we saved any FPRs. */
20669 if (info
->first_fp_reg_save
!= 64)
20671 rtx dest_reg
= gen_rtx_REG (reg_mode
, DEFAULT_ABI
== ABI_AIX
20673 rtx offset
= GEN_INT (sp_offset
20674 + (-8 * (64-info
->first_fp_reg_save
)));
20675 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
20678 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20679 info
->gp_save_offset
+ sp_offset
,
20681 /*savep=*/true, /*gpr=*/true,
20683 & SAVE_NOINLINE_GPRS_SAVES_LR
)
20685 insn
= emit_insn (par
);
20686 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20687 NULL_RTX
, NULL_RTX
);
20689 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
20693 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
20694 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20696 rtx addr
, reg
, mem
;
20697 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20698 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20699 GEN_INT (info
->gp_save_offset
20702 mem
= gen_frame_mem (reg_mode
, addr
);
20704 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20706 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20707 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20708 NULL_RTX
, NULL_RTX
);
20710 else if (!WORLD_SAVE_P (info
))
20713 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20714 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20716 rtx addr
, reg
, mem
;
20717 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20719 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20720 GEN_INT (info
->gp_save_offset
20723 mem
= gen_frame_mem (reg_mode
, addr
);
20725 insn
= emit_move_insn (mem
, reg
);
20726 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20727 NULL_RTX
, NULL_RTX
);
20731 /* ??? There's no need to emit actual instructions here, but it's the
20732 easiest way to get the frame unwind information emitted. */
20733 if (crtl
->calls_eh_return
)
20735 unsigned int i
, regno
;
20739 regno
= EH_RETURN_DATA_REGNO (i
);
20740 if (regno
== INVALID_REGNUM
)
20743 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
20744 info
->ehrd_offset
+ sp_offset
20745 + reg_size
* (int) i
,
20750 /* In AIX ABI we need to make sure r2 is really saved. */
20751 if (TARGET_AIX
&& crtl
->calls_eh_return
)
20753 rtx tmp_reg
, tmp_reg_si
, hi
, lo
, compare_result
, toc_save_done
, jump
;
20754 long toc_restore_insn
;
20756 gcc_assert (frame_reg_rtx
== frame_ptr_rtx
20757 || frame_reg_rtx
== sp_reg_rtx
);
20758 tmp_reg
= gen_rtx_REG (Pmode
, 11);
20759 tmp_reg_si
= gen_rtx_REG (SImode
, 11);
20760 if (using_static_chain_p
)
20761 emit_move_insn (gen_rtx_REG (Pmode
, 0), tmp_reg
);
20762 gcc_assert (saving_GPRs_inline
&& saving_FPRs_inline
);
20763 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, LR_REGNO
));
20764 /* Peek at instruction to which this function returns. If it's
20765 restoring r2, then we know we've already saved r2. We can't
20766 unconditionally save r2 because the value we have will already
20767 be updated if we arrived at this function via a plt call or
20768 toc adjusting stub. */
20769 emit_move_insn (tmp_reg_si
, gen_rtx_MEM (SImode
, tmp_reg
));
20770 toc_restore_insn
= TARGET_32BIT
? 0x80410014 : 0xE8410028;
20771 hi
= gen_int_mode (toc_restore_insn
& ~0xffff, SImode
);
20772 emit_insn (gen_xorsi3 (tmp_reg_si
, tmp_reg_si
, hi
));
20773 compare_result
= gen_rtx_REG (CCUNSmode
, CR0_REGNO
);
20774 validate_condition_mode (EQ
, CCUNSmode
);
20775 lo
= gen_int_mode (toc_restore_insn
& 0xffff, SImode
);
20776 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
20777 gen_rtx_COMPARE (CCUNSmode
, tmp_reg_si
, lo
)));
20778 toc_save_done
= gen_label_rtx ();
20779 jump
= gen_rtx_IF_THEN_ELSE (VOIDmode
,
20780 gen_rtx_EQ (VOIDmode
, compare_result
,
20782 gen_rtx_LABEL_REF (VOIDmode
, toc_save_done
),
20784 jump
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, jump
));
20785 JUMP_LABEL (jump
) = toc_save_done
;
20786 LABEL_NUSES (toc_save_done
) += 1;
20788 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, 2,
20789 sp_offset
+ 5 * reg_size
, info
->total_size
);
20790 emit_label (toc_save_done
);
20791 if (using_static_chain_p
)
20792 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, 0));
20795 /* Save CR if we use any that must be preserved. */
20796 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
20798 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20799 GEN_INT (info
->cr_save_offset
+ sp_offset
));
20800 rtx mem
= gen_frame_mem (SImode
, addr
);
20801 /* See the large comment above about why CR2_REGNO is used. */
20802 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
20804 /* If r12 was used to hold the original sp, copy cr into r0 now
20806 if (REGNO (frame_reg_rtx
) == 12)
20810 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
20811 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20812 RTX_FRAME_RELATED_P (insn
) = 1;
20813 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
20814 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20816 insn
= emit_move_insn (mem
, cr_save_rtx
);
20818 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20819 NULL_RTX
, NULL_RTX
);
20822 /* Update stack and set back pointer unless this is V.4,
20823 for which it was done previously. */
20824 if (!WORLD_SAVE_P (info
) && info
->push_p
20825 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
20827 rtx copy_reg
= NULL
;
20829 if (info
->total_size
< 32767)
20830 sp_offset
= info
->total_size
;
20831 else if (info
->altivec_size
!= 0
20832 || info
->vrsave_mask
!= 0)
20834 copy_reg
= frame_ptr_rtx
;
20835 frame_reg_rtx
= copy_reg
;
20838 sp_offset
= info
->total_size
;
20839 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20840 if (frame_reg_rtx
!= sp_reg_rtx
)
20841 rs6000_emit_stack_tie ();
20844 /* Set frame pointer, if needed. */
20845 if (frame_pointer_needed
)
20847 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
20849 RTX_FRAME_RELATED_P (insn
) = 1;
20852 /* Save AltiVec registers if needed. Save here because the red zone does
20853 not include AltiVec registers. */
20854 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
20858 /* There should be a non inline version of this, for when we
20859 are saving lots of vector registers. */
20860 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20861 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20863 rtx areg
, savereg
, mem
;
20866 offset
= info
->altivec_save_offset
+ sp_offset
20867 + 16 * (i
- info
->first_altivec_reg_save
);
20869 savereg
= gen_rtx_REG (V4SImode
, i
);
20871 areg
= gen_rtx_REG (Pmode
, 0);
20872 emit_move_insn (areg
, GEN_INT (offset
));
20874 /* AltiVec addressing mode is [reg+reg]. */
20875 mem
= gen_frame_mem (V4SImode
,
20876 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
20878 insn
= emit_move_insn (mem
, savereg
);
20880 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20881 areg
, GEN_INT (offset
));
20885 /* VRSAVE is a bit vector representing which AltiVec registers
20886 are used. The OS uses this to determine which vector
20887 registers to save on a context switch. We need to save
20888 VRSAVE on the stack frame, add whatever AltiVec registers we
20889 used in this function, and do the corresponding magic in the
20892 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
20893 && info
->vrsave_mask
!= 0)
20895 rtx reg
, mem
, vrsave
;
20898 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20899 as frame_reg_rtx and r11 as the static chain pointer for
20900 nested functions. */
20901 reg
= gen_rtx_REG (SImode
, 0);
20902 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
20904 emit_insn (gen_get_vrsave_internal (reg
));
20906 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
20908 if (!WORLD_SAVE_P (info
))
20911 offset
= info
->vrsave_save_offset
+ sp_offset
;
20912 mem
= gen_frame_mem (SImode
,
20913 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20914 GEN_INT (offset
)));
20915 insn
= emit_move_insn (mem
, reg
);
20918 /* Include the registers in the mask. */
20919 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
20921 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
20924 if (TARGET_SINGLE_PIC_BASE
)
20925 return; /* Do not set PIC register */
20927 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20928 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
20929 || (DEFAULT_ABI
== ABI_V4
20930 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
20931 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
20933 /* If emit_load_toc_table will use the link register, we need to save
20934 it. We use R12 for this purpose because emit_load_toc_table
20935 can use register 0. This allows us to use a plain 'blr' to return
20936 from the procedure more often. */
20937 int save_LR_around_toc_setup
= (TARGET_ELF
20938 && DEFAULT_ABI
!= ABI_AIX
20940 && ! info
->lr_save_p
20941 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
20942 if (save_LR_around_toc_setup
)
20944 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20946 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
20947 RTX_FRAME_RELATED_P (insn
) = 1;
20949 rs6000_emit_load_toc_table (TRUE
);
20951 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
20952 RTX_FRAME_RELATED_P (insn
) = 1;
20955 rs6000_emit_load_toc_table (TRUE
);
20959 if (DEFAULT_ABI
== ABI_DARWIN
20960 && flag_pic
&& crtl
->uses_pic_offset_table
)
20962 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20963 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
20965 /* Save and restore LR locally around this call (in R0). */
20966 if (!info
->lr_save_p
)
20967 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
20969 emit_insn (gen_load_macho_picbase (src
));
20971 emit_move_insn (gen_rtx_REG (Pmode
,
20972 RS6000_PIC_OFFSET_TABLE_REGNUM
),
20975 if (!info
->lr_save_p
)
20976 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
20981 /* Write function prologue. */
20984 rs6000_output_function_prologue (FILE *file
,
20985 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
20987 rs6000_stack_t
*info
= rs6000_stack_info ();
20989 if (TARGET_DEBUG_STACK
)
20990 debug_stack_info (info
);
20992 /* Write .extern for any function we will call to save and restore
20994 if (info
->first_fp_reg_save
< 64)
20997 int regno
= info
->first_fp_reg_save
- 32;
20999 if ((info
->savres_strategy
& SAVE_INLINE_FPRS
) == 0)
21001 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/true,
21002 /*gpr=*/false, /*lr=*/false);
21003 fprintf (file
, "\t.extern %s\n", name
);
21005 if ((info
->savres_strategy
& REST_INLINE_FPRS
) == 0)
21007 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/false,
21008 /*gpr=*/false, /*lr=*/true);
21009 fprintf (file
, "\t.extern %s\n", name
);
21013 /* Write .extern for AIX common mode routines, if needed. */
21014 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
21016 fputs ("\t.extern __mulh\n", file
);
21017 fputs ("\t.extern __mull\n", file
);
21018 fputs ("\t.extern __divss\n", file
);
21019 fputs ("\t.extern __divus\n", file
);
21020 fputs ("\t.extern __quoss\n", file
);
21021 fputs ("\t.extern __quous\n", file
);
21022 common_mode_defined
= 1;
21025 if (! HAVE_prologue
)
21031 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21032 the "toplevel" insn chain. */
21033 emit_note (NOTE_INSN_DELETED
);
21034 rs6000_emit_prologue ();
21035 emit_note (NOTE_INSN_DELETED
);
21037 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21041 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
21043 INSN_ADDRESSES_NEW (insn
, addr
);
21048 prologue
= get_insns ();
21051 if (TARGET_DEBUG_STACK
)
21052 debug_rtx_list (prologue
, 100);
21054 emit_insn_before_noloc (prologue
, BB_HEAD (ENTRY_BLOCK_PTR
->next_bb
),
21058 rs6000_pic_labelno
++;
21061 /* Non-zero if vmx regs are restored before the frame pop, zero if
21062 we restore after the pop when possible. */
21063 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21065 /* Reload CR from REG. */
21068 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
21073 if (using_mfcr_multiple
)
21075 for (i
= 0; i
< 8; i
++)
21076 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21078 gcc_assert (count
);
21081 if (using_mfcr_multiple
&& count
> 1)
21086 p
= rtvec_alloc (count
);
21089 for (i
= 0; i
< 8; i
++)
21090 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21092 rtvec r
= rtvec_alloc (2);
21093 RTVEC_ELT (r
, 0) = reg
;
21094 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
21095 RTVEC_ELT (p
, ndx
) =
21096 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
21097 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
21100 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21101 gcc_assert (ndx
== count
);
21104 for (i
= 0; i
< 8; i
++)
21105 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21107 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
21113 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21114 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21115 below stack pointer not cloberred by signals. */
21118 offset_below_red_zone_p (HOST_WIDE_INT offset
)
21120 return offset
< (DEFAULT_ABI
== ABI_V4
21122 : TARGET_32BIT
? -220 : -288);
21125 /* Emit function epilogue as insns. */
21128 rs6000_emit_epilogue (int sibcall
)
21130 rs6000_stack_t
*info
;
21131 int restoring_GPRs_inline
;
21132 int restoring_FPRs_inline
;
21133 int using_load_multiple
;
21134 int using_mtcr_multiple
;
21135 int use_backchain_to_restore_sp
;
21139 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
21140 rtx frame_reg_rtx
= sp_reg_rtx
;
21141 rtx cfa_restores
= NULL_RTX
;
21143 rtx cr_save_reg
= NULL_RTX
;
21144 enum machine_mode reg_mode
= Pmode
;
21145 int reg_size
= TARGET_32BIT
? 4 : 8;
21148 info
= rs6000_stack_info ();
21150 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
21152 reg_mode
= V2SImode
;
21156 strategy
= info
->savres_strategy
;
21157 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
21158 restoring_FPRs_inline
= sibcall
|| (strategy
& REST_INLINE_FPRS
);
21159 restoring_GPRs_inline
= sibcall
|| (strategy
& REST_INLINE_GPRS
);
21160 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
21161 || rs6000_cpu
== PROCESSOR_PPC603
21162 || rs6000_cpu
== PROCESSOR_PPC750
21164 /* Restore via the backchain when we have a large frame, since this
21165 is more efficient than an addis, addi pair. The second condition
21166 here will not trigger at the moment; We don't actually need a
21167 frame pointer for alloca, but the generic parts of the compiler
21168 give us one anyway. */
21169 use_backchain_to_restore_sp
= (info
->total_size
> 32767
21170 || info
->total_size
21171 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
21173 || (cfun
->calls_alloca
21174 && !frame_pointer_needed
));
21175 restore_lr
= (info
->lr_save_p
21176 && (restoring_FPRs_inline
21177 || (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
))
21178 && (restoring_GPRs_inline
21179 || info
->first_fp_reg_save
< 64));
21181 if (WORLD_SAVE_P (info
))
21185 const char *alloc_rname
;
21188 /* eh_rest_world_r10 will return to the location saved in the LR
21189 stack slot (which is not likely to be our caller.)
21190 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21191 rest_world is similar, except any R10 parameter is ignored.
21192 The exception-handling stuff that was here in 2.95 is no
21193 longer necessary. */
21197 + 32 - info
->first_gp_reg_save
21198 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
21199 + 63 + 1 - info
->first_fp_reg_save
);
21201 strcpy (rname
, ((crtl
->calls_eh_return
) ?
21202 "*eh_rest_world_r10" : "*rest_world"));
21203 alloc_rname
= ggc_strdup (rname
);
21206 RTVEC_ELT (p
, j
++) = ret_rtx
;
21207 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
21208 gen_rtx_REG (Pmode
,
21211 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
21212 /* The instruction pattern requires a clobber here;
21213 it is shared with the restVEC helper. */
21215 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
21218 /* CR register traditionally saved as CR2. */
21219 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
21220 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21221 GEN_INT (info
->cr_save_offset
));
21222 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21224 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21227 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21229 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21230 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21231 GEN_INT (info
->gp_save_offset
21233 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21235 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21237 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
21239 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
21240 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21241 GEN_INT (info
->altivec_save_offset
21243 rtx mem
= gen_frame_mem (V4SImode
, addr
);
21245 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21247 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
21249 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21250 ? DFmode
: SFmode
),
21251 info
->first_fp_reg_save
+ i
);
21252 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21253 GEN_INT (info
->fp_save_offset
21255 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21256 ? DFmode
: SFmode
), addr
);
21258 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21261 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
21263 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
21265 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
21267 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
21269 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
21270 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21275 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21277 sp_offset
= info
->total_size
;
21279 /* Restore AltiVec registers if we must do so before adjusting the
21281 if (TARGET_ALTIVEC_ABI
21282 && info
->altivec_size
!= 0
21283 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21284 || (DEFAULT_ABI
!= ABI_V4
21285 && offset_below_red_zone_p (info
->altivec_save_offset
))))
21289 if (use_backchain_to_restore_sp
)
21291 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21292 emit_move_insn (frame_reg_rtx
,
21293 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21296 else if (frame_pointer_needed
)
21297 frame_reg_rtx
= hard_frame_pointer_rtx
;
21299 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21300 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21302 rtx addr
, areg
, mem
, reg
;
21304 areg
= gen_rtx_REG (Pmode
, 0);
21306 (areg
, GEN_INT (info
->altivec_save_offset
21308 + 16 * (i
- info
->first_altivec_reg_save
)));
21310 /* AltiVec addressing mode is [reg+reg]. */
21311 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
21312 mem
= gen_frame_mem (V4SImode
, addr
);
21314 reg
= gen_rtx_REG (V4SImode
, i
);
21315 emit_move_insn (reg
, mem
);
21316 if (offset_below_red_zone_p (info
->altivec_save_offset
21317 + (i
- info
->first_altivec_reg_save
)
21319 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21324 /* Restore VRSAVE if we must do so before adjusting the stack. */
21326 && TARGET_ALTIVEC_VRSAVE
21327 && info
->vrsave_mask
!= 0
21328 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21329 || (DEFAULT_ABI
!= ABI_V4
21330 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
21332 rtx addr
, mem
, reg
;
21334 if (frame_reg_rtx
== sp_reg_rtx
)
21336 if (use_backchain_to_restore_sp
)
21338 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21339 emit_move_insn (frame_reg_rtx
,
21340 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21343 else if (frame_pointer_needed
)
21344 frame_reg_rtx
= hard_frame_pointer_rtx
;
21347 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21348 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
21349 mem
= gen_frame_mem (SImode
, addr
);
21350 reg
= gen_rtx_REG (SImode
, 12);
21351 emit_move_insn (reg
, mem
);
21353 emit_insn (generate_set_vrsave (reg
, info
, 1));
21357 /* If we have a large stack frame, restore the old stack pointer
21358 using the backchain. */
21359 if (use_backchain_to_restore_sp
)
21361 if (frame_reg_rtx
== sp_reg_rtx
)
21363 /* Under V.4, don't reset the stack pointer until after we're done
21364 loading the saved registers. */
21365 if (DEFAULT_ABI
== ABI_V4
)
21366 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21368 insn
= emit_move_insn (frame_reg_rtx
,
21369 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21372 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21373 && DEFAULT_ABI
== ABI_V4
)
21374 /* frame_reg_rtx has been set up by the altivec restore. */
21378 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
21379 frame_reg_rtx
= sp_reg_rtx
;
21382 /* If we have a frame pointer, we can restore the old stack pointer
21384 else if (frame_pointer_needed
)
21386 frame_reg_rtx
= sp_reg_rtx
;
21387 if (DEFAULT_ABI
== ABI_V4
)
21388 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21389 /* Prevent reordering memory accesses against stack pointer restore. */
21390 else if (cfun
->calls_alloca
21391 || offset_below_red_zone_p (-info
->total_size
))
21393 rtx mem1
= gen_rtx_MEM (BLKmode
, hard_frame_pointer_rtx
);
21394 rtx mem2
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
21395 MEM_NOTRAP_P (mem1
) = 1;
21396 MEM_NOTRAP_P (mem2
) = 1;
21397 emit_insn (gen_frame_tie (mem1
, mem2
));
21400 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
21401 GEN_INT (info
->total_size
)));
21404 else if (info
->push_p
21405 && DEFAULT_ABI
!= ABI_V4
21406 && !crtl
->calls_eh_return
)
21408 /* Prevent reordering memory accesses against stack pointer restore. */
21409 if (cfun
->calls_alloca
21410 || offset_below_red_zone_p (-info
->total_size
))
21412 rtx mem
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
21413 MEM_NOTRAP_P (mem
) = 1;
21414 emit_insn (gen_stack_tie (mem
));
21416 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
21417 GEN_INT (info
->total_size
)));
21420 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
21424 REG_NOTES (insn
) = cfa_restores
;
21425 cfa_restores
= NULL_RTX
;
21427 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21428 RTX_FRAME_RELATED_P (insn
) = 1;
21431 /* Restore AltiVec registers if we have not done so already. */
21432 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21433 && TARGET_ALTIVEC_ABI
21434 && info
->altivec_size
!= 0
21435 && (DEFAULT_ABI
== ABI_V4
21436 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
21440 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21441 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21443 rtx addr
, areg
, mem
, reg
;
21445 areg
= gen_rtx_REG (Pmode
, 0);
21447 (areg
, GEN_INT (info
->altivec_save_offset
21449 + 16 * (i
- info
->first_altivec_reg_save
)));
21451 /* AltiVec addressing mode is [reg+reg]. */
21452 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
21453 mem
= gen_frame_mem (V4SImode
, addr
);
21455 reg
= gen_rtx_REG (V4SImode
, i
);
21456 emit_move_insn (reg
, mem
);
21457 if (DEFAULT_ABI
== ABI_V4
)
21458 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21463 /* Restore VRSAVE if we have not done so already. */
21464 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21466 && TARGET_ALTIVEC_VRSAVE
21467 && info
->vrsave_mask
!= 0
21468 && (DEFAULT_ABI
== ABI_V4
21469 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
21471 rtx addr
, mem
, reg
;
21473 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21474 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
21475 mem
= gen_frame_mem (SImode
, addr
);
21476 reg
= gen_rtx_REG (SImode
, 12);
21477 emit_move_insn (reg
, mem
);
21479 emit_insn (generate_set_vrsave (reg
, info
, 1));
21482 /* Get the old lr if we saved it. If we are restoring registers
21483 out-of-line, then the out-of-line routines can do this for us. */
21484 if (restore_lr
&& restoring_GPRs_inline
)
21486 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21487 info
->lr_save_offset
+ sp_offset
);
21489 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21492 /* Get the old cr if we saved it. */
21493 if (info
->cr_save_p
)
21495 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21496 GEN_INT (info
->cr_save_offset
+ sp_offset
));
21497 rtx mem
= gen_frame_mem (SImode
, addr
);
21499 cr_save_reg
= gen_rtx_REG (SImode
,
21500 DEFAULT_ABI
== ABI_AIX
21501 && !restoring_GPRs_inline
21502 && info
->first_fp_reg_save
< 64
21504 emit_move_insn (cr_save_reg
, mem
);
21507 /* Set LR here to try to overlap restores below. LR is always saved
21508 above incoming stack, so it never needs REG_CFA_RESTORE. */
21509 if (restore_lr
&& restoring_GPRs_inline
)
21510 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21511 gen_rtx_REG (Pmode
, 0));
21513 /* Load exception handler data registers, if needed. */
21514 if (crtl
->calls_eh_return
)
21516 unsigned int i
, regno
;
21520 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21521 GEN_INT (sp_offset
+ 5 * reg_size
));
21522 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21524 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
21531 regno
= EH_RETURN_DATA_REGNO (i
);
21532 if (regno
== INVALID_REGNUM
)
21535 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
21536 info
->ehrd_offset
+ sp_offset
21537 + reg_size
* (int) i
);
21539 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
21543 /* Restore GPRs. This is done as a PARALLEL if we are using
21544 the load-multiple instructions. */
21546 && info
->spe_64bit_regs_used
!= 0
21547 && info
->first_gp_reg_save
!= 32)
21549 /* Determine whether we can address all of the registers that need
21550 to be saved with an offset from the stack pointer that fits in
21551 the small const field for SPE memory instructions. */
21552 int spe_regs_addressable_via_sp
21553 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
21554 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
21555 && restoring_GPRs_inline
);
21558 if (spe_regs_addressable_via_sp
)
21559 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
21562 rtx old_frame_reg_rtx
= frame_reg_rtx
;
21563 /* Make r11 point to the start of the SPE save area. We worried about
21564 not clobbering it when we were saving registers in the prologue.
21565 There's no need to worry here because the static chain is passed
21566 anew to every function. */
21567 int ool_adjust
= (restoring_GPRs_inline
21569 : (info
->first_gp_reg_save
21570 - (FIRST_SAVRES_REGISTER
+1))*8);
21572 if (frame_reg_rtx
== sp_reg_rtx
)
21573 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21574 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
21575 GEN_INT (info
->spe_gp_save_offset
21578 /* Keep the invariant that frame_reg_rtx + sp_offset points
21579 at the top of the stack frame. */
21580 sp_offset
= -info
->spe_gp_save_offset
;
21585 if (restoring_GPRs_inline
)
21587 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21588 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21590 rtx offset
, addr
, mem
, reg
;
21592 /* We're doing all this to ensure that the immediate offset
21593 fits into the immediate field of 'evldd'. */
21594 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
21596 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
21597 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
21598 mem
= gen_rtx_MEM (V2SImode
, addr
);
21599 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21601 insn
= emit_move_insn (reg
, mem
);
21602 if (DEFAULT_ABI
== ABI_V4
)
21604 if (frame_pointer_needed
21605 && info
->first_gp_reg_save
+ i
21606 == HARD_FRAME_POINTER_REGNUM
)
21608 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21609 plus_constant (frame_reg_rtx
,
21611 RTX_FRAME_RELATED_P (insn
) = 1;
21614 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21623 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
21625 /*savep=*/false, /*gpr=*/true,
21627 emit_jump_insn (par
);
21628 /* We don't want anybody else emitting things after we jumped
21633 else if (!restoring_GPRs_inline
)
21635 /* We are jumping to an out-of-line function. */
21636 bool can_use_exit
= info
->first_fp_reg_save
== 64;
21639 /* Emit stack reset code if we need it. */
21641 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21642 sp_offset
, can_use_exit
);
21645 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode
, DEFAULT_ABI
== ABI_AIX
21648 GEN_INT (sp_offset
- info
->fp_size
)));
21649 if (REGNO (frame_reg_rtx
) == 11)
21650 sp_offset
+= info
->fp_size
;
21653 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
21654 info
->gp_save_offset
, reg_mode
,
21655 /*savep=*/false, /*gpr=*/true,
21656 /*lr=*/can_use_exit
);
21660 if (info
->cr_save_p
)
21662 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21663 if (DEFAULT_ABI
== ABI_V4
)
21665 = alloc_reg_note (REG_CFA_RESTORE
,
21666 gen_rtx_REG (SImode
, CR2_REGNO
),
21670 emit_jump_insn (par
);
21672 /* We don't want anybody else emitting things after we jumped
21677 insn
= emit_insn (par
);
21678 if (DEFAULT_ABI
== ABI_V4
)
21680 if (frame_pointer_needed
)
21682 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21683 plus_constant (frame_reg_rtx
, sp_offset
));
21684 RTX_FRAME_RELATED_P (insn
) = 1;
21687 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
21689 = alloc_reg_note (REG_CFA_RESTORE
,
21690 gen_rtx_REG (reg_mode
, i
), cfa_restores
);
21693 else if (using_load_multiple
)
21696 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
21697 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21699 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21700 GEN_INT (info
->gp_save_offset
21703 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21704 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21706 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21707 if (DEFAULT_ABI
== ABI_V4
)
21708 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21711 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21712 if (DEFAULT_ABI
== ABI_V4
&& frame_pointer_needed
)
21714 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21715 plus_constant (frame_reg_rtx
, sp_offset
));
21716 RTX_FRAME_RELATED_P (insn
) = 1;
21721 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21722 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21724 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21725 GEN_INT (info
->gp_save_offset
21728 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21729 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21731 insn
= emit_move_insn (reg
, mem
);
21732 if (DEFAULT_ABI
== ABI_V4
)
21734 if (frame_pointer_needed
21735 && info
->first_gp_reg_save
+ i
21736 == HARD_FRAME_POINTER_REGNUM
)
21738 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21739 plus_constant (frame_reg_rtx
, sp_offset
));
21740 RTX_FRAME_RELATED_P (insn
) = 1;
21743 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21749 if (restore_lr
&& !restoring_GPRs_inline
)
21751 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21752 info
->lr_save_offset
+ sp_offset
);
21754 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21755 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21756 gen_rtx_REG (Pmode
, 0));
21759 /* Restore fpr's if we need to do it without calling a function. */
21760 if (restoring_FPRs_inline
)
21761 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21762 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
21763 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
21765 rtx addr
, mem
, reg
;
21766 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21767 GEN_INT (info
->fp_save_offset
21770 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21771 ? DFmode
: SFmode
), addr
);
21772 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21773 ? DFmode
: SFmode
),
21774 info
->first_fp_reg_save
+ i
);
21776 emit_move_insn (reg
, mem
);
21777 if (DEFAULT_ABI
== ABI_V4
)
21778 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21782 /* If we saved cr, restore it here. Just those that were used. */
21783 if (info
->cr_save_p
)
21785 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21786 if (DEFAULT_ABI
== ABI_V4
)
21788 = alloc_reg_note (REG_CFA_RESTORE
, gen_rtx_REG (SImode
, CR2_REGNO
),
21792 /* If this is V.4, unwind the stack pointer after all of the loads
21794 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21795 sp_offset
, !restoring_FPRs_inline
);
21800 REG_NOTES (insn
) = cfa_restores
;
21801 cfa_restores
= NULL_RTX
;
21803 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21804 RTX_FRAME_RELATED_P (insn
) = 1;
21807 if (crtl
->calls_eh_return
)
21809 rtx sa
= EH_RETURN_STACKADJ_RTX
;
21810 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
21816 bool lr
= (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
) == 0;
21817 if (! restoring_FPRs_inline
)
21818 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
21820 p
= rtvec_alloc (2);
21822 RTVEC_ELT (p
, 0) = ret_rtx
;
21823 RTVEC_ELT (p
, 1) = ((restoring_FPRs_inline
|| !lr
)
21824 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
21825 : gen_rtx_CLOBBER (VOIDmode
,
21826 gen_rtx_REG (Pmode
, 65)));
21828 /* If we have to restore more than two FP registers, branch to the
21829 restore function. It will return to our caller. */
21830 if (! restoring_FPRs_inline
)
21835 sym
= rs6000_savres_routine_sym (info
,
21839 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
21840 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
21841 gen_rtx_REG (Pmode
,
21842 DEFAULT_ABI
== ABI_AIX
21844 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21847 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
21848 GEN_INT (info
->fp_save_offset
+ 8*i
));
21849 mem
= gen_frame_mem (DFmode
, addr
);
21851 RTVEC_ELT (p
, i
+4) =
21852 gen_rtx_SET (VOIDmode
,
21853 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
21858 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21862 /* Write function epilogue. */
21865 rs6000_output_function_epilogue (FILE *file
,
21866 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
21868 if (! HAVE_epilogue
)
21870 rtx insn
= get_last_insn ();
21871 /* If the last insn was a BARRIER, we don't have to write anything except
21872 the trace table. */
21873 if (GET_CODE (insn
) == NOTE
)
21874 insn
= prev_nonnote_insn (insn
);
21875 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
21877 /* This is slightly ugly, but at least we don't have two
21878 copies of the epilogue-emitting code. */
21881 /* A NOTE_INSN_DELETED is supposed to be at the start
21882 and end of the "toplevel" insn chain. */
21883 emit_note (NOTE_INSN_DELETED
);
21884 rs6000_emit_epilogue (FALSE
);
21885 emit_note (NOTE_INSN_DELETED
);
21887 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21891 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
21893 INSN_ADDRESSES_NEW (insn
, addr
);
21898 if (TARGET_DEBUG_STACK
)
21899 debug_rtx_list (get_insns (), 100);
21900 final (get_insns (), file
, FALSE
);
21906 macho_branch_islands ();
21907 /* Mach-O doesn't support labels at the end of objects, so if
21908 it looks like we might want one, insert a NOP. */
21910 rtx insn
= get_last_insn ();
21913 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
21914 insn
= PREV_INSN (insn
);
21918 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
21919 fputs ("\tnop\n", file
);
21923 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21926 We don't output a traceback table if -finhibit-size-directive was
21927 used. The documentation for -finhibit-size-directive reads
21928 ``don't output a @code{.size} assembler directive, or anything
21929 else that would cause trouble if the function is split in the
21930 middle, and the two halves are placed at locations far apart in
21931 memory.'' The traceback table has this property, since it
21932 includes the offset from the start of the function to the
21933 traceback table itself.
21935 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21936 different traceback table. */
21937 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
21938 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
21940 const char *fname
= NULL
;
21941 const char *language_string
= lang_hooks
.name
;
21942 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
21944 int optional_tbtab
;
21945 rs6000_stack_t
*info
= rs6000_stack_info ();
21947 if (rs6000_traceback
== traceback_full
)
21948 optional_tbtab
= 1;
21949 else if (rs6000_traceback
== traceback_part
)
21950 optional_tbtab
= 0;
21952 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
21954 if (optional_tbtab
)
21956 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
21957 while (*fname
== '.') /* V.4 encodes . in the name */
21960 /* Need label immediately before tbtab, so we can compute
21961 its offset from the function start. */
21962 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
21963 ASM_OUTPUT_LABEL (file
, fname
);
21966 /* The .tbtab pseudo-op can only be used for the first eight
21967 expressions, since it can't handle the possibly variable
21968 length fields that follow. However, if you omit the optional
21969 fields, the assembler outputs zeros for all optional fields
21970 anyways, giving each variable length field is minimum length
21971 (as defined in sys/debug.h). Thus we can not use the .tbtab
21972 pseudo-op at all. */
21974 /* An all-zero word flags the start of the tbtab, for debuggers
21975 that have to find it by searching forward from the entry
21976 point or from the current pc. */
21977 fputs ("\t.long 0\n", file
);
21979 /* Tbtab format type. Use format type 0. */
21980 fputs ("\t.byte 0,", file
);
21982 /* Language type. Unfortunately, there does not seem to be any
21983 official way to discover the language being compiled, so we
21984 use language_string.
21985 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21986 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21987 a number, so for now use 9. LTO and Go aren't assigned numbers
21988 either, so for now use 0. */
21989 if (! strcmp (language_string
, "GNU C")
21990 || ! strcmp (language_string
, "GNU GIMPLE")
21991 || ! strcmp (language_string
, "GNU Go"))
21993 else if (! strcmp (language_string
, "GNU F77")
21994 || ! strcmp (language_string
, "GNU Fortran"))
21996 else if (! strcmp (language_string
, "GNU Pascal"))
21998 else if (! strcmp (language_string
, "GNU Ada"))
22000 else if (! strcmp (language_string
, "GNU C++")
22001 || ! strcmp (language_string
, "GNU Objective-C++"))
22003 else if (! strcmp (language_string
, "GNU Java"))
22005 else if (! strcmp (language_string
, "GNU Objective-C"))
22008 gcc_unreachable ();
22009 fprintf (file
, "%d,", i
);
22011 /* 8 single bit fields: global linkage (not set for C extern linkage,
22012 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22013 from start of procedure stored in tbtab, internal function, function
22014 has controlled storage, function has no toc, function uses fp,
22015 function logs/aborts fp operations. */
22016 /* Assume that fp operations are used if any fp reg must be saved. */
22017 fprintf (file
, "%d,",
22018 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
22020 /* 6 bitfields: function is interrupt handler, name present in
22021 proc table, function calls alloca, on condition directives
22022 (controls stack walks, 3 bits), saves condition reg, saves
22024 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22025 set up as a frame pointer, even when there is no alloca call. */
22026 fprintf (file
, "%d,",
22027 ((optional_tbtab
<< 6)
22028 | ((optional_tbtab
& frame_pointer_needed
) << 5)
22029 | (info
->cr_save_p
<< 1)
22030 | (info
->lr_save_p
)));
22032 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22034 fprintf (file
, "%d,",
22035 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
22037 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22038 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
22040 if (optional_tbtab
)
22042 /* Compute the parameter info from the function decl argument
22045 int next_parm_info_bit
= 31;
22047 for (decl
= DECL_ARGUMENTS (current_function_decl
);
22048 decl
; decl
= DECL_CHAIN (decl
))
22050 rtx parameter
= DECL_INCOMING_RTL (decl
);
22051 enum machine_mode mode
= GET_MODE (parameter
);
22053 if (GET_CODE (parameter
) == REG
)
22055 if (SCALAR_FLOAT_MODE_P (mode
))
22076 gcc_unreachable ();
22079 /* If only one bit will fit, don't or in this entry. */
22080 if (next_parm_info_bit
> 0)
22081 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
22082 next_parm_info_bit
-= 2;
22086 fixed_parms
+= ((GET_MODE_SIZE (mode
)
22087 + (UNITS_PER_WORD
- 1))
22089 next_parm_info_bit
-= 1;
22095 /* Number of fixed point parameters. */
22096 /* This is actually the number of words of fixed point parameters; thus
22097 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22098 fprintf (file
, "%d,", fixed_parms
);
22100 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22102 /* This is actually the number of fp registers that hold parameters;
22103 and thus the maximum value is 13. */
22104 /* Set parameters on stack bit if parameters are not in their original
22105 registers, regardless of whether they are on the stack? Xlc
22106 seems to set the bit when not optimizing. */
22107 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
22109 if (! optional_tbtab
)
22112 /* Optional fields follow. Some are variable length. */
22114 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22115 11 double float. */
22116 /* There is an entry for each parameter in a register, in the order that
22117 they occur in the parameter list. Any intervening arguments on the
22118 stack are ignored. If the list overflows a long (max possible length
22119 34 bits) then completely leave off all elements that don't fit. */
22120 /* Only emit this long if there was at least one parameter. */
22121 if (fixed_parms
|| float_parms
)
22122 fprintf (file
, "\t.long %d\n", parm_info
);
22124 /* Offset from start of code to tb table. */
22125 fputs ("\t.long ", file
);
22126 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
22127 RS6000_OUTPUT_BASENAME (file
, fname
);
22129 rs6000_output_function_entry (file
, fname
);
22132 /* Interrupt handler mask. */
22133 /* Omit this long, since we never set the interrupt handler bit
22136 /* Number of CTL (controlled storage) anchors. */
22137 /* Omit this long, since the has_ctl bit is never set above. */
22139 /* Displacement into stack of each CTL anchor. */
22140 /* Omit this list of longs, because there are no CTL anchors. */
22142 /* Length of function name. */
22145 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
22147 /* Function name. */
22148 assemble_string (fname
, strlen (fname
));
22150 /* Register for alloca automatic storage; this is always reg 31.
22151 Only emit this if the alloca bit was set above. */
22152 if (frame_pointer_needed
)
22153 fputs ("\t.byte 31\n", file
);
22155 fputs ("\t.align 2\n", file
);
22159 /* A C compound statement that outputs the assembler code for a thunk
22160 function, used to implement C++ virtual function calls with
22161 multiple inheritance. The thunk acts as a wrapper around a virtual
22162 function, adjusting the implicit object parameter before handing
22163 control off to the real function.
22165 First, emit code to add the integer DELTA to the location that
22166 contains the incoming first argument. Assume that this argument
22167 contains a pointer, and is the one used to pass the `this' pointer
22168 in C++. This is the incoming argument *before* the function
22169 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22170 values of all other incoming arguments.
22172 After the addition, emit code to jump to FUNCTION, which is a
22173 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22174 not touch the return address. Hence returning from FUNCTION will
22175 return to whoever called the current `thunk'.
22177 The effect must be as if FUNCTION had been called directly with the
22178 adjusted first argument. This macro is responsible for emitting
22179 all of the code for a thunk function; output_function_prologue()
22180 and output_function_epilogue() are not invoked.
22182 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22183 been extracted from it.) It might possibly be useful on some
22184 targets, but probably not.
22186 If you do not define this macro, the target-independent code in the
22187 C++ frontend will generate a less efficient heavyweight thunk that
22188 calls FUNCTION instead of jumping to it. The generic approach does
22189 not support varargs. */
22192 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
22193 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
22196 rtx this_rtx
, insn
, funexp
;
22198 reload_completed
= 1;
22199 epilogue_completed
= 1;
22201 /* Mark the end of the (empty) prologue. */
22202 emit_note (NOTE_INSN_PROLOGUE_END
);
22204 /* Find the "this" pointer. If the function returns a structure,
22205 the structure return pointer is in r3. */
22206 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
22207 this_rtx
= gen_rtx_REG (Pmode
, 4);
22209 this_rtx
= gen_rtx_REG (Pmode
, 3);
22211 /* Apply the constant offset, if required. */
22213 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
22215 /* Apply the offset from the vtable, if required. */
22218 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
22219 rtx tmp
= gen_rtx_REG (Pmode
, 12);
22221 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
22222 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
22224 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
22225 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
22229 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
22231 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
22233 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
22236 /* Generate a tail call to the target function. */
22237 if (!TREE_USED (function
))
22239 assemble_external (function
);
22240 TREE_USED (function
) = 1;
22242 funexp
= XEXP (DECL_RTL (function
), 0);
22243 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
22246 if (MACHOPIC_INDIRECT
)
22247 funexp
= machopic_indirect_call_target (funexp
);
22250 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22251 generate sibcall RTL explicitly. */
22252 insn
= emit_call_insn (
22253 gen_rtx_PARALLEL (VOIDmode
,
22255 gen_rtx_CALL (VOIDmode
,
22256 funexp
, const0_rtx
),
22257 gen_rtx_USE (VOIDmode
, const0_rtx
),
22258 gen_rtx_USE (VOIDmode
,
22259 gen_rtx_REG (SImode
,
22262 SIBLING_CALL_P (insn
) = 1;
22265 /* Run just enough of rest_of_compilation to get the insns emitted.
22266 There's not really enough bulk here to make other passes such as
22267 instruction scheduling worth while. Note that use_thunk calls
22268 assemble_start_function and assemble_end_function. */
22269 insn
= get_insns ();
22270 insn_locators_alloc ();
22271 shorten_branches (insn
);
22272 final_start_function (insn
, file
, 1);
22273 final (insn
, file
, 1);
22274 final_end_function ();
22276 reload_completed
= 0;
22277 epilogue_completed
= 0;
22280 /* A quick summary of the various types of 'constant-pool tables'
22283 Target Flags Name One table per
22284 AIX (none) AIX TOC object file
22285 AIX -mfull-toc AIX TOC object file
22286 AIX -mminimal-toc AIX minimal TOC translation unit
22287 SVR4/EABI (none) SVR4 SDATA object file
22288 SVR4/EABI -fpic SVR4 pic object file
22289 SVR4/EABI -fPIC SVR4 PIC translation unit
22290 SVR4/EABI -mrelocatable EABI TOC function
22291 SVR4/EABI -maix AIX TOC object file
22292 SVR4/EABI -maix -mminimal-toc
22293 AIX minimal TOC translation unit
22295 Name Reg. Set by entries contains:
22296 made by addrs? fp? sum?
22298 AIX TOC 2 crt0 as Y option option
22299 AIX minimal TOC 30 prolog gcc Y Y option
22300 SVR4 SDATA 13 crt0 gcc N Y N
22301 SVR4 pic 30 prolog ld Y not yet N
22302 SVR4 PIC 30 prolog gcc Y option option
22303 EABI TOC 30 prolog gcc Y option option
22307 /* Hash functions for the hash table. */
22310 rs6000_hash_constant (rtx k
)
22312 enum rtx_code code
= GET_CODE (k
);
22313 enum machine_mode mode
= GET_MODE (k
);
22314 unsigned result
= (code
<< 3) ^ mode
;
22315 const char *format
;
22318 format
= GET_RTX_FORMAT (code
);
22319 flen
= strlen (format
);
22325 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
22328 if (mode
!= VOIDmode
)
22329 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
22341 for (; fidx
< flen
; fidx
++)
22342 switch (format
[fidx
])
22347 const char *str
= XSTR (k
, fidx
);
22348 len
= strlen (str
);
22349 result
= result
* 613 + len
;
22350 for (i
= 0; i
< len
; i
++)
22351 result
= result
* 613 + (unsigned) str
[i
];
22356 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
22360 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
22363 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
22364 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
22368 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
22369 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
22376 gcc_unreachable ();
22383 toc_hash_function (const void *hash_entry
)
22385 const struct toc_hash_struct
*thc
=
22386 (const struct toc_hash_struct
*) hash_entry
;
22387 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
22390 /* Compare H1 and H2 for equivalence. */
22393 toc_hash_eq (const void *h1
, const void *h2
)
22395 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
22396 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
22398 if (((const struct toc_hash_struct
*) h1
)->key_mode
22399 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
22402 return rtx_equal_p (r1
, r2
);
22405 /* These are the names given by the C++ front-end to vtables, and
22406 vtable-like objects. Ideally, this logic should not be here;
22407 instead, there should be some programmatic way of inquiring as
22408 to whether or not an object is a vtable. */
22410 #define VTABLE_NAME_P(NAME) \
22411 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22412 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22413 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22414 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22415 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22417 #ifdef NO_DOLLAR_IN_LABEL
22418 /* Return a GGC-allocated character string translating dollar signs in
22419 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22422 rs6000_xcoff_strip_dollar (const char *name
)
22427 p
= strchr (name
, '$');
22429 if (p
== 0 || p
== name
)
22432 len
= strlen (name
);
22433 strip
= (char *) alloca (len
+ 1);
22434 strcpy (strip
, name
);
22435 p
= strchr (strip
, '$');
22439 p
= strchr (p
+ 1, '$');
22442 return ggc_alloc_string (strip
, len
);
22447 rs6000_output_symbol_ref (FILE *file
, rtx x
)
22449 /* Currently C++ toc references to vtables can be emitted before it
22450 is decided whether the vtable is public or private. If this is
22451 the case, then the linker will eventually complain that there is
22452 a reference to an unknown section. Thus, for vtables only,
22453 we emit the TOC reference to reference the symbol and not the
22455 const char *name
= XSTR (x
, 0);
22457 if (VTABLE_NAME_P (name
))
22459 RS6000_OUTPUT_BASENAME (file
, name
);
22462 assemble_name (file
, name
);
22465 /* Output a TOC entry. We derive the entry name from what is being
22469 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
22472 const char *name
= buf
;
22474 HOST_WIDE_INT offset
= 0;
22476 gcc_assert (!TARGET_NO_TOC
);
22478 /* When the linker won't eliminate them, don't output duplicate
22479 TOC entries (this happens on AIX if there is any kind of TOC,
22480 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22482 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
22484 struct toc_hash_struct
*h
;
22487 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22488 time because GGC is not initialized at that point. */
22489 if (toc_hash_table
== NULL
)
22490 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
22491 toc_hash_eq
, NULL
);
22493 h
= ggc_alloc_toc_hash_struct ();
22495 h
->key_mode
= mode
;
22496 h
->labelno
= labelno
;
22498 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
22499 if (*found
== NULL
)
22501 else /* This is indeed a duplicate.
22502 Set this label equal to that label. */
22504 fputs ("\t.set ", file
);
22505 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22506 fprintf (file
, "%d,", labelno
);
22507 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22508 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
22514 /* If we're going to put a double constant in the TOC, make sure it's
22515 aligned properly when strict alignment is on. */
22516 if (GET_CODE (x
) == CONST_DOUBLE
22517 && STRICT_ALIGNMENT
22518 && GET_MODE_BITSIZE (mode
) >= 64
22519 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
22520 ASM_OUTPUT_ALIGN (file
, 3);
22523 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
22525 /* Handle FP constants specially. Note that if we have a minimal
22526 TOC, things we put here aren't actually in the TOC, so we can allow
22528 if (GET_CODE (x
) == CONST_DOUBLE
&&
22529 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
22531 REAL_VALUE_TYPE rv
;
22534 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22535 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22536 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
22538 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
22542 if (TARGET_MINIMAL_TOC
)
22543 fputs (DOUBLE_INT_ASM_OP
, file
);
22545 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22546 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22547 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22548 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
22549 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22550 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22555 if (TARGET_MINIMAL_TOC
)
22556 fputs ("\t.long ", file
);
22558 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22559 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22560 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22561 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22562 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22563 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22567 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22568 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
22570 REAL_VALUE_TYPE rv
;
22573 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22575 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22576 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
22578 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
22582 if (TARGET_MINIMAL_TOC
)
22583 fputs (DOUBLE_INT_ASM_OP
, file
);
22585 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22586 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22587 fprintf (file
, "0x%lx%08lx\n",
22588 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22593 if (TARGET_MINIMAL_TOC
)
22594 fputs ("\t.long ", file
);
22596 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22597 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22598 fprintf (file
, "0x%lx,0x%lx\n",
22599 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22603 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22604 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
22606 REAL_VALUE_TYPE rv
;
22609 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22610 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22611 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
22613 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
22617 if (TARGET_MINIMAL_TOC
)
22618 fputs (DOUBLE_INT_ASM_OP
, file
);
22620 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22621 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
22626 if (TARGET_MINIMAL_TOC
)
22627 fputs ("\t.long ", file
);
22629 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22630 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
22634 else if (GET_MODE (x
) == VOIDmode
22635 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
22637 unsigned HOST_WIDE_INT low
;
22638 HOST_WIDE_INT high
;
22640 if (GET_CODE (x
) == CONST_DOUBLE
)
22642 low
= CONST_DOUBLE_LOW (x
);
22643 high
= CONST_DOUBLE_HIGH (x
);
22646 #if HOST_BITS_PER_WIDE_INT == 32
22649 high
= (low
& 0x80000000) ? ~0 : 0;
22653 low
= INTVAL (x
) & 0xffffffff;
22654 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
22658 /* TOC entries are always Pmode-sized, but since this
22659 is a bigendian machine then if we're putting smaller
22660 integer constants in the TOC we have to pad them.
22661 (This is still a win over putting the constants in
22662 a separate constant pool, because then we'd have
22663 to have both a TOC entry _and_ the actual constant.)
22665 For a 32-bit target, CONST_INT values are loaded and shifted
22666 entirely within `low' and can be stored in one TOC entry. */
22668 /* It would be easy to make this work, but it doesn't now. */
22669 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
22671 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
22673 #if HOST_BITS_PER_WIDE_INT == 32
22674 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
22675 POINTER_SIZE
, &low
, &high
, 0);
22678 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
22679 high
= (HOST_WIDE_INT
) low
>> 32;
22686 if (TARGET_MINIMAL_TOC
)
22687 fputs (DOUBLE_INT_ASM_OP
, file
);
22689 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22690 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22691 fprintf (file
, "0x%lx%08lx\n",
22692 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22697 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
22699 if (TARGET_MINIMAL_TOC
)
22700 fputs ("\t.long ", file
);
22702 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22703 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22704 fprintf (file
, "0x%lx,0x%lx\n",
22705 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22709 if (TARGET_MINIMAL_TOC
)
22710 fputs ("\t.long ", file
);
22712 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
22713 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
22719 if (GET_CODE (x
) == CONST
)
22721 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
22722 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
22724 base
= XEXP (XEXP (x
, 0), 0);
22725 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
22728 switch (GET_CODE (base
))
22731 name
= XSTR (base
, 0);
22735 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
22736 CODE_LABEL_NUMBER (XEXP (base
, 0)));
22740 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
22744 gcc_unreachable ();
22747 if (TARGET_MINIMAL_TOC
)
22748 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
22751 fputs ("\t.tc ", file
);
22752 RS6000_OUTPUT_BASENAME (file
, name
);
22755 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
22757 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
22759 fputs ("[TC],", file
);
22762 /* Currently C++ toc references to vtables can be emitted before it
22763 is decided whether the vtable is public or private. If this is
22764 the case, then the linker will eventually complain that there is
22765 a TOC reference to an unknown section. Thus, for vtables only,
22766 we emit the TOC reference to reference the symbol and not the
22768 if (VTABLE_NAME_P (name
))
22770 RS6000_OUTPUT_BASENAME (file
, name
);
22772 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
22773 else if (offset
> 0)
22774 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
22777 output_addr_const (file
, x
);
22781 /* Output an assembler pseudo-op to write an ASCII string of N characters
22782 starting at P to FILE.
22784 On the RS/6000, we have to do this using the .byte operation and
22785 write out special characters outside the quoted string.
22786 Also, the assembler is broken; very long strings are truncated,
22787 so we must artificially break them up early. */
22790 output_ascii (FILE *file
, const char *p
, int n
)
22793 int i
, count_string
;
22794 const char *for_string
= "\t.byte \"";
22795 const char *for_decimal
= "\t.byte ";
22796 const char *to_close
= NULL
;
22799 for (i
= 0; i
< n
; i
++)
22802 if (c
>= ' ' && c
< 0177)
22805 fputs (for_string
, file
);
22808 /* Write two quotes to get one. */
22816 for_decimal
= "\"\n\t.byte ";
22820 if (count_string
>= 512)
22822 fputs (to_close
, file
);
22824 for_string
= "\t.byte \"";
22825 for_decimal
= "\t.byte ";
22833 fputs (for_decimal
, file
);
22834 fprintf (file
, "%d", c
);
22836 for_string
= "\n\t.byte \"";
22837 for_decimal
= ", ";
22843 /* Now close the string if we have written one. Then end the line. */
22845 fputs (to_close
, file
);
22848 /* Generate a unique section name for FILENAME for a section type
22849 represented by SECTION_DESC. Output goes into BUF.
22851 SECTION_DESC can be any string, as long as it is different for each
22852 possible section type.
22854 We name the section in the same manner as xlc. The name begins with an
22855 underscore followed by the filename (after stripping any leading directory
22856 names) with the last period replaced by the string SECTION_DESC. If
22857 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22861 rs6000_gen_section_name (char **buf
, const char *filename
,
22862 const char *section_desc
)
22864 const char *q
, *after_last_slash
, *last_period
= 0;
22868 after_last_slash
= filename
;
22869 for (q
= filename
; *q
; q
++)
22872 after_last_slash
= q
+ 1;
22873 else if (*q
== '.')
22877 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
22878 *buf
= (char *) xmalloc (len
);
22883 for (q
= after_last_slash
; *q
; q
++)
22885 if (q
== last_period
)
22887 strcpy (p
, section_desc
);
22888 p
+= strlen (section_desc
);
22892 else if (ISALNUM (*q
))
22896 if (last_period
== 0)
22897 strcpy (p
, section_desc
);
22902 /* Emit profile function. */
22905 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
22907 /* Non-standard profiling for kernels, which just saves LR then calls
22908 _mcount without worrying about arg saves. The idea is to change
22909 the function prologue as little as possible as it isn't easy to
22910 account for arg save/restore code added just for _mcount. */
22911 if (TARGET_PROFILE_KERNEL
)
22914 if (DEFAULT_ABI
== ABI_AIX
)
22916 #ifndef NO_PROFILE_COUNTERS
22917 # define NO_PROFILE_COUNTERS 0
22919 if (NO_PROFILE_COUNTERS
)
22920 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22921 LCT_NORMAL
, VOIDmode
, 0);
22925 const char *label_name
;
22928 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22929 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
22930 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
22932 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22933 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
22936 else if (DEFAULT_ABI
== ABI_DARWIN
)
22938 const char *mcount_name
= RS6000_MCOUNT
;
22939 int caller_addr_regno
= LR_REGNO
;
22941 /* Be conservative and always set this, at least for now. */
22942 crtl
->uses_pic_offset_table
= 1;
22945 /* For PIC code, set up a stub and collect the caller's address
22946 from r0, which is where the prologue puts it. */
22947 if (MACHOPIC_INDIRECT
22948 && crtl
->uses_pic_offset_table
)
22949 caller_addr_regno
= 0;
22951 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
22952 LCT_NORMAL
, VOIDmode
, 1,
22953 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
22957 /* Write function profiler code. */
22960 output_function_profiler (FILE *file
, int labelno
)
22964 switch (DEFAULT_ABI
)
22967 gcc_unreachable ();
22972 warning (0, "no profiling of 64-bit code for this ABI");
22975 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22976 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
22977 if (NO_PROFILE_COUNTERS
)
22979 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22980 reg_names
[0], reg_names
[1]);
22982 else if (TARGET_SECURE_PLT
&& flag_pic
)
22984 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22985 reg_names
[0], reg_names
[1]);
22986 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
22987 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
22988 reg_names
[12], reg_names
[12]);
22989 assemble_name (file
, buf
);
22990 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
22991 assemble_name (file
, buf
);
22992 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
22994 else if (flag_pic
== 1)
22996 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
22997 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22998 reg_names
[0], reg_names
[1]);
22999 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
23000 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
23001 assemble_name (file
, buf
);
23002 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
23004 else if (flag_pic
> 1)
23006 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23007 reg_names
[0], reg_names
[1]);
23008 /* Now, we need to get the address of the label. */
23009 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
23010 assemble_name (file
, buf
);
23011 fputs ("-.\n1:", file
);
23012 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
23013 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
23014 reg_names
[0], reg_names
[11]);
23015 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
23016 reg_names
[0], reg_names
[0], reg_names
[11]);
23020 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
23021 assemble_name (file
, buf
);
23022 fputs ("@ha\n", file
);
23023 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23024 reg_names
[0], reg_names
[1]);
23025 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
23026 assemble_name (file
, buf
);
23027 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
23030 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23031 fprintf (file
, "\tbl %s%s\n",
23032 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
23037 if (!TARGET_PROFILE_KERNEL
)
23039 /* Don't do anything, done in output_profile_hook (). */
23043 gcc_assert (!TARGET_32BIT
);
23045 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
23046 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
23048 if (cfun
->static_chain_decl
!= NULL
)
23050 asm_fprintf (file
, "\tstd %s,24(%s)\n",
23051 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
23052 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
23053 asm_fprintf (file
, "\tld %s,24(%s)\n",
23054 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
23057 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
23065 /* The following variable value is the last issued insn. */
23067 static rtx last_scheduled_insn
;
23069 /* The following variable helps to balance issuing of load and
23070 store instructions */
23072 static int load_store_pendulum
;
23074 /* Power4 load update and store update instructions are cracked into a
23075 load or store and an integer insn which are executed in the same cycle.
23076 Branches have their own dispatch slot which does not count against the
23077 GCC issue rate, but it changes the program flow so there are no other
23078 instructions to issue in this cycle. */
23081 rs6000_variable_issue_1 (rtx insn
, int more
)
23083 last_scheduled_insn
= insn
;
23084 if (GET_CODE (PATTERN (insn
)) == USE
23085 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23087 cached_can_issue_more
= more
;
23088 return cached_can_issue_more
;
23091 if (insn_terminates_group_p (insn
, current_group
))
23093 cached_can_issue_more
= 0;
23094 return cached_can_issue_more
;
23097 /* If no reservation, but reach here */
23098 if (recog_memoized (insn
) < 0)
23101 if (rs6000_sched_groups
)
23103 if (is_microcoded_insn (insn
))
23104 cached_can_issue_more
= 0;
23105 else if (is_cracked_insn (insn
))
23106 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
23108 cached_can_issue_more
= more
- 1;
23110 return cached_can_issue_more
;
23113 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
23116 cached_can_issue_more
= more
- 1;
23117 return cached_can_issue_more
;
23121 rs6000_variable_issue (FILE *stream
, int verbose
, rtx insn
, int more
)
23123 int r
= rs6000_variable_issue_1 (insn
, more
);
23125 fprintf (stream
, "// rs6000_variable_issue (more = %d) = %d\n", more
, r
);
23129 /* Adjust the cost of a scheduling dependency. Return the new cost of
23130 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23133 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
23135 enum attr_type attr_type
;
23137 if (! recog_memoized (insn
))
23140 switch (REG_NOTE_KIND (link
))
23144 /* Data dependency; DEP_INSN writes a register that INSN reads
23145 some cycles later. */
23147 /* Separate a load from a narrower, dependent store. */
23148 if (rs6000_sched_groups
23149 && GET_CODE (PATTERN (insn
)) == SET
23150 && GET_CODE (PATTERN (dep_insn
)) == SET
23151 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
23152 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
23153 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
23154 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
23157 attr_type
= get_attr_type (insn
);
23162 /* Tell the first scheduling pass about the latency between
23163 a mtctr and bctr (and mtlr and br/blr). The first
23164 scheduling pass will not know about this latency since
23165 the mtctr instruction, which has the latency associated
23166 to it, will be generated by reload. */
23167 return TARGET_POWER
? 5 : 4;
23169 /* Leave some extra cycles between a compare and its
23170 dependent branch, to inhibit expensive mispredicts. */
23171 if ((rs6000_cpu_attr
== CPU_PPC603
23172 || rs6000_cpu_attr
== CPU_PPC604
23173 || rs6000_cpu_attr
== CPU_PPC604E
23174 || rs6000_cpu_attr
== CPU_PPC620
23175 || rs6000_cpu_attr
== CPU_PPC630
23176 || rs6000_cpu_attr
== CPU_PPC750
23177 || rs6000_cpu_attr
== CPU_PPC7400
23178 || rs6000_cpu_attr
== CPU_PPC7450
23179 || rs6000_cpu_attr
== CPU_POWER4
23180 || rs6000_cpu_attr
== CPU_POWER5
23181 || rs6000_cpu_attr
== CPU_POWER7
23182 || rs6000_cpu_attr
== CPU_CELL
)
23183 && recog_memoized (dep_insn
)
23184 && (INSN_CODE (dep_insn
) >= 0))
23186 switch (get_attr_type (dep_insn
))
23190 case TYPE_DELAYED_COMPARE
:
23191 case TYPE_IMUL_COMPARE
:
23192 case TYPE_LMUL_COMPARE
:
23193 case TYPE_FPCOMPARE
:
23194 case TYPE_CR_LOGICAL
:
23195 case TYPE_DELAYED_CR
:
23204 case TYPE_STORE_UX
:
23206 case TYPE_FPSTORE_U
:
23207 case TYPE_FPSTORE_UX
:
23208 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23209 && recog_memoized (dep_insn
)
23210 && (INSN_CODE (dep_insn
) >= 0))
23213 if (GET_CODE (PATTERN (insn
)) != SET
)
23214 /* If this happens, we have to extend this to schedule
23215 optimally. Return default for now. */
23218 /* Adjust the cost for the case where the value written
23219 by a fixed point operation is used as the address
23220 gen value on a store. */
23221 switch (get_attr_type (dep_insn
))
23228 if (! store_data_bypass_p (dep_insn
, insn
))
23232 case TYPE_LOAD_EXT
:
23233 case TYPE_LOAD_EXT_U
:
23234 case TYPE_LOAD_EXT_UX
:
23235 case TYPE_VAR_SHIFT_ROTATE
:
23236 case TYPE_VAR_DELAYED_COMPARE
:
23238 if (! store_data_bypass_p (dep_insn
, insn
))
23244 case TYPE_FAST_COMPARE
:
23247 case TYPE_INSERT_WORD
:
23248 case TYPE_INSERT_DWORD
:
23249 case TYPE_FPLOAD_U
:
23250 case TYPE_FPLOAD_UX
:
23252 case TYPE_STORE_UX
:
23253 case TYPE_FPSTORE_U
:
23254 case TYPE_FPSTORE_UX
:
23256 if (! store_data_bypass_p (dep_insn
, insn
))
23264 case TYPE_IMUL_COMPARE
:
23265 case TYPE_LMUL_COMPARE
:
23267 if (! store_data_bypass_p (dep_insn
, insn
))
23273 if (! store_data_bypass_p (dep_insn
, insn
))
23279 if (! store_data_bypass_p (dep_insn
, insn
))
23292 case TYPE_LOAD_EXT
:
23293 case TYPE_LOAD_EXT_U
:
23294 case TYPE_LOAD_EXT_UX
:
23295 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23296 && recog_memoized (dep_insn
)
23297 && (INSN_CODE (dep_insn
) >= 0))
23300 /* Adjust the cost for the case where the value written
23301 by a fixed point instruction is used within the address
23302 gen portion of a subsequent load(u)(x) */
23303 switch (get_attr_type (dep_insn
))
23310 if (set_to_load_agen (dep_insn
, insn
))
23314 case TYPE_LOAD_EXT
:
23315 case TYPE_LOAD_EXT_U
:
23316 case TYPE_LOAD_EXT_UX
:
23317 case TYPE_VAR_SHIFT_ROTATE
:
23318 case TYPE_VAR_DELAYED_COMPARE
:
23320 if (set_to_load_agen (dep_insn
, insn
))
23326 case TYPE_FAST_COMPARE
:
23329 case TYPE_INSERT_WORD
:
23330 case TYPE_INSERT_DWORD
:
23331 case TYPE_FPLOAD_U
:
23332 case TYPE_FPLOAD_UX
:
23334 case TYPE_STORE_UX
:
23335 case TYPE_FPSTORE_U
:
23336 case TYPE_FPSTORE_UX
:
23338 if (set_to_load_agen (dep_insn
, insn
))
23346 case TYPE_IMUL_COMPARE
:
23347 case TYPE_LMUL_COMPARE
:
23349 if (set_to_load_agen (dep_insn
, insn
))
23355 if (set_to_load_agen (dep_insn
, insn
))
23361 if (set_to_load_agen (dep_insn
, insn
))
23372 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23373 && recog_memoized (dep_insn
)
23374 && (INSN_CODE (dep_insn
) >= 0)
23375 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
23382 /* Fall out to return default cost. */
23386 case REG_DEP_OUTPUT
:
23387 /* Output dependency; DEP_INSN writes a register that INSN writes some
23389 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23390 && recog_memoized (dep_insn
)
23391 && (INSN_CODE (dep_insn
) >= 0))
23393 attr_type
= get_attr_type (insn
);
23398 if (get_attr_type (dep_insn
) == TYPE_FP
)
23402 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
23410 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23415 gcc_unreachable ();
23421 /* Debug version of rs6000_adjust_cost. */
23424 rs6000_debug_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
23426 int ret
= rs6000_adjust_cost (insn
, link
, dep_insn
, cost
);
23432 switch (REG_NOTE_KIND (link
))
23434 default: dep
= "unknown depencency"; break;
23435 case REG_DEP_TRUE
: dep
= "data dependency"; break;
23436 case REG_DEP_OUTPUT
: dep
= "output dependency"; break;
23437 case REG_DEP_ANTI
: dep
= "anti depencency"; break;
23441 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23442 "%s, insn:\n", ret
, cost
, dep
);
23450 /* The function returns a true if INSN is microcoded.
23451 Return false otherwise. */
23454 is_microcoded_insn (rtx insn
)
23456 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23457 || GET_CODE (PATTERN (insn
)) == USE
23458 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23461 if (rs6000_cpu_attr
== CPU_CELL
)
23462 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
23464 if (rs6000_sched_groups
)
23466 enum attr_type type
= get_attr_type (insn
);
23467 if (type
== TYPE_LOAD_EXT_U
23468 || type
== TYPE_LOAD_EXT_UX
23469 || type
== TYPE_LOAD_UX
23470 || type
== TYPE_STORE_UX
23471 || type
== TYPE_MFCR
)
23478 /* The function returns true if INSN is cracked into 2 instructions
23479 by the processor (and therefore occupies 2 issue slots). */
23482 is_cracked_insn (rtx insn
)
23484 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23485 || GET_CODE (PATTERN (insn
)) == USE
23486 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23489 if (rs6000_sched_groups
)
23491 enum attr_type type
= get_attr_type (insn
);
23492 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
23493 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
23494 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
23495 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
23496 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
23497 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
23498 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
23499 || type
== TYPE_INSERT_WORD
)
23506 /* The function returns true if INSN can be issued only from
23507 the branch slot. */
23510 is_branch_slot_insn (rtx insn
)
23512 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23513 || GET_CODE (PATTERN (insn
)) == USE
23514 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23517 if (rs6000_sched_groups
)
23519 enum attr_type type
= get_attr_type (insn
);
23520 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
23528 /* The function returns true if out_inst sets a value that is
23529 used in the address generation computation of in_insn */
23531 set_to_load_agen (rtx out_insn
, rtx in_insn
)
23533 rtx out_set
, in_set
;
23535 /* For performance reasons, only handle the simple case where
23536 both loads are a single_set. */
23537 out_set
= single_set (out_insn
);
23540 in_set
= single_set (in_insn
);
23542 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
23548 /* The function returns true if the target storage location of
23549 out_insn is adjacent to the target storage location of in_insn */
23550 /* Return 1 if memory locations are adjacent. */
23553 adjacent_mem_locations (rtx insn1
, rtx insn2
)
23556 rtx a
= get_store_dest (PATTERN (insn1
));
23557 rtx b
= get_store_dest (PATTERN (insn2
));
23559 if ((GET_CODE (XEXP (a
, 0)) == REG
23560 || (GET_CODE (XEXP (a
, 0)) == PLUS
23561 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
23562 && (GET_CODE (XEXP (b
, 0)) == REG
23563 || (GET_CODE (XEXP (b
, 0)) == PLUS
23564 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
23566 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
23569 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
23571 reg0
= XEXP (XEXP (a
, 0), 0);
23572 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
23575 reg0
= XEXP (a
, 0);
23577 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
23579 reg1
= XEXP (XEXP (b
, 0), 0);
23580 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
23583 reg1
= XEXP (b
, 0);
23585 val_diff
= val1
- val0
;
23587 return ((REGNO (reg0
) == REGNO (reg1
))
23588 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
23589 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
23595 /* A C statement (sans semicolon) to update the integer scheduling
23596 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23597 INSN earlier, reduce the priority to execute INSN later. Do not
23598 define this macro if you do not need to adjust the scheduling
23599 priorities of insns. */
23602 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
23604 /* On machines (like the 750) which have asymmetric integer units,
23605 where one integer unit can do multiply and divides and the other
23606 can't, reduce the priority of multiply/divide so it is scheduled
23607 before other integer operations. */
23610 if (! INSN_P (insn
))
23613 if (GET_CODE (PATTERN (insn
)) == USE
)
23616 switch (rs6000_cpu_attr
) {
23618 switch (get_attr_type (insn
))
23625 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
23626 priority
, priority
);
23627 if (priority
>= 0 && priority
< 0x01000000)
23634 if (insn_must_be_first_in_group (insn
)
23635 && reload_completed
23636 && current_sched_info
->sched_max_insns_priority
23637 && rs6000_sched_restricted_insns_priority
)
23640 /* Prioritize insns that can be dispatched only in the first
23642 if (rs6000_sched_restricted_insns_priority
== 1)
23643 /* Attach highest priority to insn. This means that in
23644 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23645 precede 'priority' (critical path) considerations. */
23646 return current_sched_info
->sched_max_insns_priority
;
23647 else if (rs6000_sched_restricted_insns_priority
== 2)
23648 /* Increase priority of insn by a minimal amount. This means that in
23649 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23650 considerations precede dispatch-slot restriction considerations. */
23651 return (priority
+ 1);
23654 if (rs6000_cpu
== PROCESSOR_POWER6
23655 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
23656 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
23657 /* Attach highest priority to insn if the scheduler has just issued two
23658 stores and this instruction is a load, or two loads and this instruction
23659 is a store. Power6 wants loads and stores scheduled alternately
23661 return current_sched_info
->sched_max_insns_priority
;
23666 /* Return true if the instruction is nonpipelined on the Cell. */
23668 is_nonpipeline_insn (rtx insn
)
23670 enum attr_type type
;
23671 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23672 || GET_CODE (PATTERN (insn
)) == USE
23673 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23676 type
= get_attr_type (insn
);
23677 if (type
== TYPE_IMUL
23678 || type
== TYPE_IMUL2
23679 || type
== TYPE_IMUL3
23680 || type
== TYPE_LMUL
23681 || type
== TYPE_IDIV
23682 || type
== TYPE_LDIV
23683 || type
== TYPE_SDIV
23684 || type
== TYPE_DDIV
23685 || type
== TYPE_SSQRT
23686 || type
== TYPE_DSQRT
23687 || type
== TYPE_MFCR
23688 || type
== TYPE_MFCRF
23689 || type
== TYPE_MFJMPR
)
23697 /* Return how many instructions the machine can issue per cycle. */
23700 rs6000_issue_rate (void)
23702 /* Unless scheduling for register pressure, use issue rate of 1 for
23703 first scheduling pass to decrease degradation. */
23704 if (!reload_completed
&& !flag_sched_pressure
)
23707 switch (rs6000_cpu_attr
) {
23708 case CPU_RIOS1
: /* ? */
23710 case CPU_PPC601
: /* ? */
23719 case CPU_PPCE300C2
:
23720 case CPU_PPCE300C3
:
23721 case CPU_PPCE500MC
:
23722 case CPU_PPCE500MC64
:
23742 /* Return how many instructions to look ahead for better insn
23746 rs6000_use_sched_lookahead (void)
23748 if (rs6000_cpu_attr
== CPU_PPC8540
)
23750 if (rs6000_cpu_attr
== CPU_CELL
)
23751 return (reload_completed
? 8 : 0);
23755 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23757 rs6000_use_sched_lookahead_guard (rtx insn
)
23759 if (rs6000_cpu_attr
!= CPU_CELL
)
23762 if (insn
== NULL_RTX
|| !INSN_P (insn
))
23765 if (!reload_completed
23766 || is_nonpipeline_insn (insn
)
23767 || is_microcoded_insn (insn
))
23773 /* Determine is PAT refers to memory. */
23776 is_mem_ref (rtx pat
)
23782 /* stack_tie does not produce any real memory traffic. */
23783 if (GET_CODE (pat
) == UNSPEC
23784 && XINT (pat
, 1) == UNSPEC_TIE
)
23787 if (GET_CODE (pat
) == MEM
)
23790 /* Recursively process the pattern. */
23791 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
23793 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
23796 ret
|= is_mem_ref (XEXP (pat
, i
));
23797 else if (fmt
[i
] == 'E')
23798 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
23799 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
23805 /* Determine if PAT is a PATTERN of a load insn. */
23808 is_load_insn1 (rtx pat
)
23810 if (!pat
|| pat
== NULL_RTX
)
23813 if (GET_CODE (pat
) == SET
)
23814 return is_mem_ref (SET_SRC (pat
));
23816 if (GET_CODE (pat
) == PARALLEL
)
23820 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23821 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
23828 /* Determine if INSN loads from memory. */
23831 is_load_insn (rtx insn
)
23833 if (!insn
|| !INSN_P (insn
))
23836 if (GET_CODE (insn
) == CALL_INSN
)
23839 return is_load_insn1 (PATTERN (insn
));
23842 /* Determine if PAT is a PATTERN of a store insn. */
23845 is_store_insn1 (rtx pat
)
23847 if (!pat
|| pat
== NULL_RTX
)
23850 if (GET_CODE (pat
) == SET
)
23851 return is_mem_ref (SET_DEST (pat
));
23853 if (GET_CODE (pat
) == PARALLEL
)
23857 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23858 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
23865 /* Determine if INSN stores to memory. */
23868 is_store_insn (rtx insn
)
23870 if (!insn
|| !INSN_P (insn
))
23873 return is_store_insn1 (PATTERN (insn
));
23876 /* Return the dest of a store insn. */
23879 get_store_dest (rtx pat
)
23881 gcc_assert (is_store_insn1 (pat
));
23883 if (GET_CODE (pat
) == SET
)
23884 return SET_DEST (pat
);
23885 else if (GET_CODE (pat
) == PARALLEL
)
23889 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23891 rtx inner_pat
= XVECEXP (pat
, 0, i
);
23892 if (GET_CODE (inner_pat
) == SET
23893 && is_mem_ref (SET_DEST (inner_pat
)))
23897 /* We shouldn't get here, because we should have either a simple
23898 store insn or a store with update which are covered above. */
23902 /* Returns whether the dependence between INSN and NEXT is considered
23903 costly by the given target. */
23906 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
23911 /* If the flag is not enabled - no dependence is considered costly;
23912 allow all dependent insns in the same group.
23913 This is the most aggressive option. */
23914 if (rs6000_sched_costly_dep
== no_dep_costly
)
23917 /* If the flag is set to 1 - a dependence is always considered costly;
23918 do not allow dependent instructions in the same group.
23919 This is the most conservative option. */
23920 if (rs6000_sched_costly_dep
== all_deps_costly
)
23923 insn
= DEP_PRO (dep
);
23924 next
= DEP_CON (dep
);
23926 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
23927 && is_load_insn (next
)
23928 && is_store_insn (insn
))
23929 /* Prevent load after store in the same group. */
23932 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
23933 && is_load_insn (next
)
23934 && is_store_insn (insn
)
23935 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
23936 /* Prevent load after store in the same group if it is a true
23940 /* The flag is set to X; dependences with latency >= X are considered costly,
23941 and will not be scheduled in the same group. */
23942 if (rs6000_sched_costly_dep
<= max_dep_latency
23943 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
23949 /* Return the next insn after INSN that is found before TAIL is reached,
23950 skipping any "non-active" insns - insns that will not actually occupy
23951 an issue slot. Return NULL_RTX if such an insn is not found. */
23954 get_next_active_insn (rtx insn
, rtx tail
)
23956 if (insn
== NULL_RTX
|| insn
== tail
)
23961 insn
= NEXT_INSN (insn
);
23962 if (insn
== NULL_RTX
|| insn
== tail
)
23967 || (NONJUMP_INSN_P (insn
)
23968 && GET_CODE (PATTERN (insn
)) != USE
23969 && GET_CODE (PATTERN (insn
)) != CLOBBER
23970 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
23976 /* We are about to begin issuing insns for this clock cycle. */
23979 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
23980 rtx
*ready ATTRIBUTE_UNUSED
,
23981 int *pn_ready ATTRIBUTE_UNUSED
,
23982 int clock_var ATTRIBUTE_UNUSED
)
23984 int n_ready
= *pn_ready
;
23987 fprintf (dump
, "// rs6000_sched_reorder :\n");
23989 /* Reorder the ready list, if the second to last ready insn
23990 is a nonepipeline insn. */
23991 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
23993 if (is_nonpipeline_insn (ready
[n_ready
- 1])
23994 && (recog_memoized (ready
[n_ready
- 2]) > 0))
23995 /* Simply swap first two insns. */
23997 rtx tmp
= ready
[n_ready
- 1];
23998 ready
[n_ready
- 1] = ready
[n_ready
- 2];
23999 ready
[n_ready
- 2] = tmp
;
24003 if (rs6000_cpu
== PROCESSOR_POWER6
)
24004 load_store_pendulum
= 0;
24006 return rs6000_issue_rate ();
24009 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24012 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
24013 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
24016 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
24018 /* For Power6, we need to handle some special cases to try and keep the
24019 store queue from overflowing and triggering expensive flushes.
24021 This code monitors how load and store instructions are being issued
24022 and skews the ready list one way or the other to increase the likelihood
24023 that a desired instruction is issued at the proper time.
24025 A couple of things are done. First, we maintain a "load_store_pendulum"
24026 to track the current state of load/store issue.
24028 - If the pendulum is at zero, then no loads or stores have been
24029 issued in the current cycle so we do nothing.
24031 - If the pendulum is 1, then a single load has been issued in this
24032 cycle and we attempt to locate another load in the ready list to
24035 - If the pendulum is -2, then two stores have already been
24036 issued in this cycle, so we increase the priority of the first load
24037 in the ready list to increase it's likelihood of being chosen first
24040 - If the pendulum is -1, then a single store has been issued in this
24041 cycle and we attempt to locate another store in the ready list to
24042 issue with it, preferring a store to an adjacent memory location to
24043 facilitate store pairing in the store queue.
24045 - If the pendulum is 2, then two loads have already been
24046 issued in this cycle, so we increase the priority of the first store
24047 in the ready list to increase it's likelihood of being chosen first
24050 - If the pendulum < -2 or > 2, then do nothing.
24052 Note: This code covers the most common scenarios. There exist non
24053 load/store instructions which make use of the LSU and which
24054 would need to be accounted for to strictly model the behavior
24055 of the machine. Those instructions are currently unaccounted
24056 for to help minimize compile time overhead of this code.
24058 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
24064 if (is_store_insn (last_scheduled_insn
))
24065 /* Issuing a store, swing the load_store_pendulum to the left */
24066 load_store_pendulum
--;
24067 else if (is_load_insn (last_scheduled_insn
))
24068 /* Issuing a load, swing the load_store_pendulum to the right */
24069 load_store_pendulum
++;
24071 return cached_can_issue_more
;
24073 /* If the pendulum is balanced, or there is only one instruction on
24074 the ready list, then all is well, so return. */
24075 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
24076 return cached_can_issue_more
;
24078 if (load_store_pendulum
== 1)
24080 /* A load has been issued in this cycle. Scan the ready list
24081 for another load to issue with it */
24086 if (is_load_insn (ready
[pos
]))
24088 /* Found a load. Move it to the head of the ready list,
24089 and adjust it's priority so that it is more likely to
24092 for (i
=pos
; i
<*pn_ready
-1; i
++)
24093 ready
[i
] = ready
[i
+ 1];
24094 ready
[*pn_ready
-1] = tmp
;
24096 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24097 INSN_PRIORITY (tmp
)++;
24103 else if (load_store_pendulum
== -2)
24105 /* Two stores have been issued in this cycle. Increase the
24106 priority of the first load in the ready list to favor it for
24107 issuing in the next cycle. */
24112 if (is_load_insn (ready
[pos
])
24114 && INSN_PRIORITY_KNOWN (ready
[pos
]))
24116 INSN_PRIORITY (ready
[pos
])++;
24118 /* Adjust the pendulum to account for the fact that a load
24119 was found and increased in priority. This is to prevent
24120 increasing the priority of multiple loads */
24121 load_store_pendulum
--;
24128 else if (load_store_pendulum
== -1)
24130 /* A store has been issued in this cycle. Scan the ready list for
24131 another store to issue with it, preferring a store to an adjacent
24133 int first_store_pos
= -1;
24139 if (is_store_insn (ready
[pos
]))
24141 /* Maintain the index of the first store found on the
24143 if (first_store_pos
== -1)
24144 first_store_pos
= pos
;
24146 if (is_store_insn (last_scheduled_insn
)
24147 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
24149 /* Found an adjacent store. Move it to the head of the
24150 ready list, and adjust it's priority so that it is
24151 more likely to stay there */
24153 for (i
=pos
; i
<*pn_ready
-1; i
++)
24154 ready
[i
] = ready
[i
+ 1];
24155 ready
[*pn_ready
-1] = tmp
;
24157 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24158 INSN_PRIORITY (tmp
)++;
24160 first_store_pos
= -1;
24168 if (first_store_pos
>= 0)
24170 /* An adjacent store wasn't found, but a non-adjacent store was,
24171 so move the non-adjacent store to the front of the ready
24172 list, and adjust its priority so that it is more likely to
24174 tmp
= ready
[first_store_pos
];
24175 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
24176 ready
[i
] = ready
[i
+ 1];
24177 ready
[*pn_ready
-1] = tmp
;
24178 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24179 INSN_PRIORITY (tmp
)++;
24182 else if (load_store_pendulum
== 2)
24184 /* Two loads have been issued in this cycle. Increase the priority
24185 of the first store in the ready list to favor it for issuing in
24191 if (is_store_insn (ready
[pos
])
24193 && INSN_PRIORITY_KNOWN (ready
[pos
]))
24195 INSN_PRIORITY (ready
[pos
])++;
24197 /* Adjust the pendulum to account for the fact that a store
24198 was found and increased in priority. This is to prevent
24199 increasing the priority of multiple stores */
24200 load_store_pendulum
++;
24209 return cached_can_issue_more
;
24212 /* Return whether the presence of INSN causes a dispatch group termination
24213 of group WHICH_GROUP.
24215 If WHICH_GROUP == current_group, this function will return true if INSN
24216 causes the termination of the current group (i.e, the dispatch group to
24217 which INSN belongs). This means that INSN will be the last insn in the
24218 group it belongs to.
24220 If WHICH_GROUP == previous_group, this function will return true if INSN
24221 causes the termination of the previous group (i.e, the dispatch group that
24222 precedes the group to which INSN belongs). This means that INSN will be
24223 the first insn in the group it belongs to). */
24226 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
24233 first
= insn_must_be_first_in_group (insn
);
24234 last
= insn_must_be_last_in_group (insn
);
24239 if (which_group
== current_group
)
24241 else if (which_group
== previous_group
)
24249 insn_must_be_first_in_group (rtx insn
)
24251 enum attr_type type
;
24254 || GET_CODE (insn
) == NOTE
24255 || DEBUG_INSN_P (insn
)
24256 || GET_CODE (PATTERN (insn
)) == USE
24257 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
24260 switch (rs6000_cpu
)
24262 case PROCESSOR_POWER5
:
24263 if (is_cracked_insn (insn
))
24265 case PROCESSOR_POWER4
:
24266 if (is_microcoded_insn (insn
))
24269 if (!rs6000_sched_groups
)
24272 type
= get_attr_type (insn
);
24279 case TYPE_DELAYED_CR
:
24280 case TYPE_CR_LOGICAL
:
24294 case PROCESSOR_POWER6
:
24295 type
= get_attr_type (insn
);
24299 case TYPE_INSERT_DWORD
:
24303 case TYPE_VAR_SHIFT_ROTATE
:
24310 case TYPE_INSERT_WORD
:
24311 case TYPE_DELAYED_COMPARE
:
24312 case TYPE_IMUL_COMPARE
:
24313 case TYPE_LMUL_COMPARE
:
24314 case TYPE_FPCOMPARE
:
24325 case TYPE_LOAD_EXT_UX
:
24327 case TYPE_STORE_UX
:
24328 case TYPE_FPLOAD_U
:
24329 case TYPE_FPLOAD_UX
:
24330 case TYPE_FPSTORE_U
:
24331 case TYPE_FPSTORE_UX
:
24337 case PROCESSOR_POWER7
:
24338 type
= get_attr_type (insn
);
24342 case TYPE_CR_LOGICAL
:
24349 case TYPE_DELAYED_COMPARE
:
24350 case TYPE_VAR_DELAYED_COMPARE
:
24356 case TYPE_LOAD_EXT
:
24357 case TYPE_LOAD_EXT_U
:
24358 case TYPE_LOAD_EXT_UX
:
24360 case TYPE_STORE_UX
:
24361 case TYPE_FPLOAD_U
:
24362 case TYPE_FPLOAD_UX
:
24363 case TYPE_FPSTORE_U
:
24364 case TYPE_FPSTORE_UX
:
24380 insn_must_be_last_in_group (rtx insn
)
24382 enum attr_type type
;
24385 || GET_CODE (insn
) == NOTE
24386 || DEBUG_INSN_P (insn
)
24387 || GET_CODE (PATTERN (insn
)) == USE
24388 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
24391 switch (rs6000_cpu
) {
24392 case PROCESSOR_POWER4
:
24393 case PROCESSOR_POWER5
:
24394 if (is_microcoded_insn (insn
))
24397 if (is_branch_slot_insn (insn
))
24401 case PROCESSOR_POWER6
:
24402 type
= get_attr_type (insn
);
24409 case TYPE_VAR_SHIFT_ROTATE
:
24416 case TYPE_DELAYED_COMPARE
:
24417 case TYPE_IMUL_COMPARE
:
24418 case TYPE_LMUL_COMPARE
:
24419 case TYPE_FPCOMPARE
:
24433 case PROCESSOR_POWER7
:
24434 type
= get_attr_type (insn
);
24442 case TYPE_LOAD_EXT_U
:
24443 case TYPE_LOAD_EXT_UX
:
24444 case TYPE_STORE_UX
:
24457 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24458 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24461 is_costly_group (rtx
*group_insns
, rtx next_insn
)
24464 int issue_rate
= rs6000_issue_rate ();
24466 for (i
= 0; i
< issue_rate
; i
++)
24468 sd_iterator_def sd_it
;
24470 rtx insn
= group_insns
[i
];
24475 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
24477 rtx next
= DEP_CON (dep
);
24479 if (next
== next_insn
24480 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
24488 /* Utility of the function redefine_groups.
24489 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24490 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24491 to keep it "far" (in a separate group) from GROUP_INSNS, following
24492 one of the following schemes, depending on the value of the flag
24493 -minsert_sched_nops = X:
24494 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24495 in order to force NEXT_INSN into a separate group.
24496 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24497 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24498 insertion (has a group just ended, how many vacant issue slots remain in the
24499 last group, and how many dispatch groups were encountered so far). */
24502 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
24503 rtx next_insn
, bool *group_end
, int can_issue_more
,
24508 int issue_rate
= rs6000_issue_rate ();
24509 bool end
= *group_end
;
24512 if (next_insn
== NULL_RTX
|| DEBUG_INSN_P (next_insn
))
24513 return can_issue_more
;
24515 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
24516 return can_issue_more
;
24518 force
= is_costly_group (group_insns
, next_insn
);
24520 return can_issue_more
;
24522 if (sched_verbose
> 6)
24523 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
24524 *group_count
,can_issue_more
);
24526 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
24529 can_issue_more
= 0;
24531 /* Since only a branch can be issued in the last issue_slot, it is
24532 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24533 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24534 in this case the last nop will start a new group and the branch
24535 will be forced to the new group. */
24536 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
24539 while (can_issue_more
> 0)
24542 emit_insn_before (nop
, next_insn
);
24550 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
24552 int n_nops
= rs6000_sched_insert_nops
;
24554 /* Nops can't be issued from the branch slot, so the effective
24555 issue_rate for nops is 'issue_rate - 1'. */
24556 if (can_issue_more
== 0)
24557 can_issue_more
= issue_rate
;
24559 if (can_issue_more
== 0)
24561 can_issue_more
= issue_rate
- 1;
24564 for (i
= 0; i
< issue_rate
; i
++)
24566 group_insns
[i
] = 0;
24573 emit_insn_before (nop
, next_insn
);
24574 if (can_issue_more
== issue_rate
- 1) /* new group begins */
24577 if (can_issue_more
== 0)
24579 can_issue_more
= issue_rate
- 1;
24582 for (i
= 0; i
< issue_rate
; i
++)
24584 group_insns
[i
] = 0;
24590 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24593 /* Is next_insn going to start a new group? */
24596 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24597 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24598 || (can_issue_more
< issue_rate
&&
24599 insn_terminates_group_p (next_insn
, previous_group
)));
24600 if (*group_end
&& end
)
24603 if (sched_verbose
> 6)
24604 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
24605 *group_count
, can_issue_more
);
24606 return can_issue_more
;
24609 return can_issue_more
;
24612 /* This function tries to synch the dispatch groups that the compiler "sees"
24613 with the dispatch groups that the processor dispatcher is expected to
24614 form in practice. It tries to achieve this synchronization by forcing the
24615 estimated processor grouping on the compiler (as opposed to the function
24616 'pad_goups' which tries to force the scheduler's grouping on the processor).
24618 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24619 examines the (estimated) dispatch groups that will be formed by the processor
24620 dispatcher. It marks these group boundaries to reflect the estimated
24621 processor grouping, overriding the grouping that the scheduler had marked.
24622 Depending on the value of the flag '-minsert-sched-nops' this function can
24623 force certain insns into separate groups or force a certain distance between
24624 them by inserting nops, for example, if there exists a "costly dependence"
24627 The function estimates the group boundaries that the processor will form as
24628 follows: It keeps track of how many vacant issue slots are available after
24629 each insn. A subsequent insn will start a new group if one of the following
24631 - no more vacant issue slots remain in the current dispatch group.
24632 - only the last issue slot, which is the branch slot, is vacant, but the next
24633 insn is not a branch.
24634 - only the last 2 or less issue slots, including the branch slot, are vacant,
24635 which means that a cracked insn (which occupies two issue slots) can't be
24636 issued in this group.
24637 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24638 start a new group. */
24641 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24643 rtx insn
, next_insn
;
24645 int can_issue_more
;
24648 int group_count
= 0;
24652 issue_rate
= rs6000_issue_rate ();
24653 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
24654 for (i
= 0; i
< issue_rate
; i
++)
24656 group_insns
[i
] = 0;
24658 can_issue_more
= issue_rate
;
24660 insn
= get_next_active_insn (prev_head_insn
, tail
);
24663 while (insn
!= NULL_RTX
)
24665 slot
= (issue_rate
- can_issue_more
);
24666 group_insns
[slot
] = insn
;
24668 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24669 if (insn_terminates_group_p (insn
, current_group
))
24670 can_issue_more
= 0;
24672 next_insn
= get_next_active_insn (insn
, tail
);
24673 if (next_insn
== NULL_RTX
)
24674 return group_count
+ 1;
24676 /* Is next_insn going to start a new group? */
24678 = (can_issue_more
== 0
24679 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24680 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24681 || (can_issue_more
< issue_rate
&&
24682 insn_terminates_group_p (next_insn
, previous_group
)));
24684 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
24685 next_insn
, &group_end
, can_issue_more
,
24691 can_issue_more
= 0;
24692 for (i
= 0; i
< issue_rate
; i
++)
24694 group_insns
[i
] = 0;
24698 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
24699 PUT_MODE (next_insn
, VOIDmode
);
24700 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
24701 PUT_MODE (next_insn
, TImode
);
24704 if (can_issue_more
== 0)
24705 can_issue_more
= issue_rate
;
24708 return group_count
;
24711 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24712 dispatch group boundaries that the scheduler had marked. Pad with nops
24713 any dispatch groups which have vacant issue slots, in order to force the
24714 scheduler's grouping on the processor dispatcher. The function
24715 returns the number of dispatch groups found. */
24718 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24720 rtx insn
, next_insn
;
24723 int can_issue_more
;
24725 int group_count
= 0;
24727 /* Initialize issue_rate. */
24728 issue_rate
= rs6000_issue_rate ();
24729 can_issue_more
= issue_rate
;
24731 insn
= get_next_active_insn (prev_head_insn
, tail
);
24732 next_insn
= get_next_active_insn (insn
, tail
);
24734 while (insn
!= NULL_RTX
)
24737 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24739 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
24741 if (next_insn
== NULL_RTX
)
24746 /* If the scheduler had marked group termination at this location
24747 (between insn and next_insn), and neither insn nor next_insn will
24748 force group termination, pad the group with nops to force group
24751 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24752 && !insn_terminates_group_p (insn
, current_group
)
24753 && !insn_terminates_group_p (next_insn
, previous_group
))
24755 if (!is_branch_slot_insn (next_insn
))
24758 while (can_issue_more
)
24761 emit_insn_before (nop
, next_insn
);
24766 can_issue_more
= issue_rate
;
24771 next_insn
= get_next_active_insn (insn
, tail
);
24774 return group_count
;
24777 /* We're beginning a new block. Initialize data structures as necessary. */
24780 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
24781 int sched_verbose ATTRIBUTE_UNUSED
,
24782 int max_ready ATTRIBUTE_UNUSED
)
24784 last_scheduled_insn
= NULL_RTX
;
24785 load_store_pendulum
= 0;
24788 /* The following function is called at the end of scheduling BB.
24789 After reload, it inserts nops at insn group bundling. */
24792 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
24797 fprintf (dump
, "=== Finishing schedule.\n");
24799 if (reload_completed
&& rs6000_sched_groups
)
24801 /* Do not run sched_finish hook when selective scheduling enabled. */
24802 if (sel_sched_p ())
24805 if (rs6000_sched_insert_nops
== sched_finish_none
)
24808 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24809 n_groups
= pad_groups (dump
, sched_verbose
,
24810 current_sched_info
->prev_head
,
24811 current_sched_info
->next_tail
);
24813 n_groups
= redefine_groups (dump
, sched_verbose
,
24814 current_sched_info
->prev_head
,
24815 current_sched_info
->next_tail
);
24817 if (sched_verbose
>= 6)
24819 fprintf (dump
, "ngroups = %d\n", n_groups
);
24820 print_rtl (dump
, current_sched_info
->prev_head
);
24821 fprintf (dump
, "Done finish_sched\n");
24826 struct _rs6000_sched_context
24828 short cached_can_issue_more
;
24829 rtx last_scheduled_insn
;
24830 int load_store_pendulum
;
24833 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
24834 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
24836 /* Allocate store for new scheduling context. */
24838 rs6000_alloc_sched_context (void)
24840 return xmalloc (sizeof (rs6000_sched_context_def
));
24843 /* If CLEAN_P is true then initializes _SC with clean data,
24844 and from the global context otherwise. */
24846 rs6000_init_sched_context (void *_sc
, bool clean_p
)
24848 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24852 sc
->cached_can_issue_more
= 0;
24853 sc
->last_scheduled_insn
= NULL_RTX
;
24854 sc
->load_store_pendulum
= 0;
24858 sc
->cached_can_issue_more
= cached_can_issue_more
;
24859 sc
->last_scheduled_insn
= last_scheduled_insn
;
24860 sc
->load_store_pendulum
= load_store_pendulum
;
24864 /* Sets the global scheduling context to the one pointed to by _SC. */
24866 rs6000_set_sched_context (void *_sc
)
24868 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24870 gcc_assert (sc
!= NULL
);
24872 cached_can_issue_more
= sc
->cached_can_issue_more
;
24873 last_scheduled_insn
= sc
->last_scheduled_insn
;
24874 load_store_pendulum
= sc
->load_store_pendulum
;
24879 rs6000_free_sched_context (void *_sc
)
24881 gcc_assert (_sc
!= NULL
);
24887 /* Length in units of the trampoline for entering a nested function. */
24890 rs6000_trampoline_size (void)
24894 switch (DEFAULT_ABI
)
24897 gcc_unreachable ();
24900 ret
= (TARGET_32BIT
) ? 12 : 24;
24905 ret
= (TARGET_32BIT
) ? 40 : 48;
24912 /* Emit RTL insns to initialize the variable parts of a trampoline.
24913 FNADDR is an RTX for the address of the function's pure code.
24914 CXT is an RTX for the static chain value for the function. */
24917 rs6000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
24919 int regsize
= (TARGET_32BIT
) ? 4 : 8;
24920 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
24921 rtx ctx_reg
= force_reg (Pmode
, cxt
);
24922 rtx addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
24924 switch (DEFAULT_ABI
)
24927 gcc_unreachable ();
24929 /* Under AIX, just build the 3 word function descriptor */
24932 rtx fnmem
= gen_const_mem (Pmode
, force_reg (Pmode
, fnaddr
));
24933 rtx fn_reg
= gen_reg_rtx (Pmode
);
24934 rtx toc_reg
= gen_reg_rtx (Pmode
);
24936 /* Macro to shorten the code expansions below. */
24937 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24939 m_tramp
= replace_equiv_address (m_tramp
, addr
);
24941 emit_move_insn (fn_reg
, MEM_PLUS (fnmem
, 0));
24942 emit_move_insn (toc_reg
, MEM_PLUS (fnmem
, regsize
));
24943 emit_move_insn (MEM_PLUS (m_tramp
, 0), fn_reg
);
24944 emit_move_insn (MEM_PLUS (m_tramp
, regsize
), toc_reg
);
24945 emit_move_insn (MEM_PLUS (m_tramp
, 2*regsize
), ctx_reg
);
24951 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24954 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
24955 LCT_NORMAL
, VOIDmode
, 4,
24957 GEN_INT (rs6000_trampoline_size ()), SImode
,
24965 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24966 identifier as an argument, so the front end shouldn't look it up. */
24969 rs6000_attribute_takes_identifier_p (const_tree attr_id
)
24971 return is_attribute_p ("altivec", attr_id
);
24974 /* Handle the "altivec" attribute. The attribute may have
24975 arguments as follows:
24977 __attribute__((altivec(vector__)))
24978 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24979 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24981 and may appear more than once (e.g., 'vector bool char') in a
24982 given declaration. */
24985 rs6000_handle_altivec_attribute (tree
*node
,
24986 tree name ATTRIBUTE_UNUSED
,
24988 int flags ATTRIBUTE_UNUSED
,
24989 bool *no_add_attrs
)
24991 tree type
= *node
, result
= NULL_TREE
;
24992 enum machine_mode mode
;
24995 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
24996 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
24997 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
25000 while (POINTER_TYPE_P (type
)
25001 || TREE_CODE (type
) == FUNCTION_TYPE
25002 || TREE_CODE (type
) == METHOD_TYPE
25003 || TREE_CODE (type
) == ARRAY_TYPE
)
25004 type
= TREE_TYPE (type
);
25006 mode
= TYPE_MODE (type
);
25008 /* Check for invalid AltiVec type qualifiers. */
25009 if (type
== long_double_type_node
)
25010 error ("use of %<long double%> in AltiVec types is invalid");
25011 else if (type
== boolean_type_node
)
25012 error ("use of boolean types in AltiVec types is invalid");
25013 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
25014 error ("use of %<complex%> in AltiVec types is invalid");
25015 else if (DECIMAL_FLOAT_MODE_P (mode
))
25016 error ("use of decimal floating point types in AltiVec types is invalid");
25017 else if (!TARGET_VSX
)
25019 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
25022 error ("use of %<long%> in AltiVec types is invalid for "
25023 "64-bit code without -mvsx");
25024 else if (rs6000_warn_altivec_long
)
25025 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25028 else if (type
== long_long_unsigned_type_node
25029 || type
== long_long_integer_type_node
)
25030 error ("use of %<long long%> in AltiVec types is invalid without "
25032 else if (type
== double_type_node
)
25033 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25036 switch (altivec_type
)
25039 unsigned_p
= TYPE_UNSIGNED (type
);
25043 result
= (unsigned_p
? unsigned_V2DI_type_node
: V2DI_type_node
);
25046 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
25049 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
25052 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
25054 case SFmode
: result
= V4SF_type_node
; break;
25055 case DFmode
: result
= V2DF_type_node
; break;
25056 /* If the user says 'vector int bool', we may be handed the 'bool'
25057 attribute _before_ the 'vector' attribute, and so select the
25058 proper type in the 'b' case below. */
25059 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
25060 case V2DImode
: case V2DFmode
:
25068 case DImode
: case V2DImode
: result
= bool_V2DI_type_node
; break;
25069 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
25070 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
25071 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
25078 case V8HImode
: result
= pixel_V8HI_type_node
;
25084 /* Propagate qualifiers attached to the element type
25085 onto the vector type. */
25086 if (result
&& result
!= type
&& TYPE_QUALS (type
))
25087 result
= build_qualified_type (result
, TYPE_QUALS (type
));
25089 *no_add_attrs
= true; /* No need to hang on to the attribute. */
25092 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
25097 /* AltiVec defines four built-in scalar types that serve as vector
25098 elements; we must teach the compiler how to mangle them. */
25100 static const char *
25101 rs6000_mangle_type (const_tree type
)
25103 type
= TYPE_MAIN_VARIANT (type
);
25105 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
25106 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
25109 if (type
== bool_char_type_node
) return "U6__boolc";
25110 if (type
== bool_short_type_node
) return "U6__bools";
25111 if (type
== pixel_type_node
) return "u7__pixel";
25112 if (type
== bool_int_type_node
) return "U6__booli";
25113 if (type
== bool_long_type_node
) return "U6__booll";
25115 /* Mangle IBM extended float long double as `g' (__float128) on
25116 powerpc*-linux where long-double-64 previously was the default. */
25117 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
25119 && TARGET_LONG_DOUBLE_128
25120 && !TARGET_IEEEQUAD
)
25123 /* For all other types, use normal C++ mangling. */
25127 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25128 struct attribute_spec.handler. */
25131 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
25132 tree args ATTRIBUTE_UNUSED
,
25133 int flags ATTRIBUTE_UNUSED
,
25134 bool *no_add_attrs
)
25136 if (TREE_CODE (*node
) != FUNCTION_TYPE
25137 && TREE_CODE (*node
) != FIELD_DECL
25138 && TREE_CODE (*node
) != TYPE_DECL
)
25140 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
25142 *no_add_attrs
= true;
25148 /* Set longcall attributes on all functions declared when
25149 rs6000_default_long_calls is true. */
25151 rs6000_set_default_type_attributes (tree type
)
25153 if (rs6000_default_long_calls
25154 && (TREE_CODE (type
) == FUNCTION_TYPE
25155 || TREE_CODE (type
) == METHOD_TYPE
))
25156 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
25158 TYPE_ATTRIBUTES (type
));
25161 darwin_set_default_type_attributes (type
);
25165 /* Return a reference suitable for calling a function with the
25166 longcall attribute. */
25169 rs6000_longcall_ref (rtx call_ref
)
25171 const char *call_name
;
25174 if (GET_CODE (call_ref
) != SYMBOL_REF
)
25177 /* System V adds '.' to the internal name, so skip them. */
25178 call_name
= XSTR (call_ref
, 0);
25179 if (*call_name
== '.')
25181 while (*call_name
== '.')
25184 node
= get_identifier (call_name
);
25185 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
25188 return force_reg (Pmode
, call_ref
);
25191 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25192 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25195 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25196 struct attribute_spec.handler. */
25198 rs6000_handle_struct_attribute (tree
*node
, tree name
,
25199 tree args ATTRIBUTE_UNUSED
,
25200 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
25203 if (DECL_P (*node
))
25205 if (TREE_CODE (*node
) == TYPE_DECL
)
25206 type
= &TREE_TYPE (*node
);
25211 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
25212 || TREE_CODE (*type
) == UNION_TYPE
)))
25214 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
25215 *no_add_attrs
= true;
25218 else if ((is_attribute_p ("ms_struct", name
)
25219 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
25220 || ((is_attribute_p ("gcc_struct", name
)
25221 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
25223 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
25225 *no_add_attrs
= true;
25232 rs6000_ms_bitfield_layout_p (const_tree record_type
)
25234 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
25235 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
25236 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
25239 #ifdef USING_ELFOS_H
25241 /* A get_unnamed_section callback, used for switching to toc_section. */
25244 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
25246 if (DEFAULT_ABI
== ABI_AIX
25247 && TARGET_MINIMAL_TOC
25248 && !TARGET_RELOCATABLE
)
25250 if (!toc_initialized
)
25252 toc_initialized
= 1;
25253 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
25254 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
25255 fprintf (asm_out_file
, "\t.tc ");
25256 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
25257 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25258 fprintf (asm_out_file
, "\n");
25260 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25261 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25262 fprintf (asm_out_file
, " = .+32768\n");
25265 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25267 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
25268 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
25271 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25272 if (!toc_initialized
)
25274 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25275 fprintf (asm_out_file
, " = .+32768\n");
25276 toc_initialized
= 1;
25281 /* Implement TARGET_ASM_INIT_SECTIONS. */
25284 rs6000_elf_asm_init_sections (void)
25287 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
25290 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
25291 SDATA2_SECTION_ASM_OP
);
25294 /* Implement TARGET_SELECT_RTX_SECTION. */
25297 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
25298 unsigned HOST_WIDE_INT align
)
25300 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
25301 return toc_section
;
25303 return default_elf_select_rtx_section (mode
, x
, align
);
25306 /* For a SYMBOL_REF, set generic flags and then perform some
25307 target-specific processing.
25309 When the AIX ABI is requested on a non-AIX system, replace the
25310 function name with the real name (with a leading .) rather than the
25311 function descriptor name. This saves a lot of overriding code to
25312 read the prefixes. */
25315 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
25317 default_encode_section_info (decl
, rtl
, first
);
25320 && TREE_CODE (decl
) == FUNCTION_DECL
25322 && DEFAULT_ABI
== ABI_AIX
)
25324 rtx sym_ref
= XEXP (rtl
, 0);
25325 size_t len
= strlen (XSTR (sym_ref
, 0));
25326 char *str
= XALLOCAVEC (char, len
+ 2);
25328 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
25329 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
25334 compare_section_name (const char *section
, const char *templ
)
25338 len
= strlen (templ
);
25339 return (strncmp (section
, templ
, len
) == 0
25340 && (section
[len
] == 0 || section
[len
] == '.'));
25344 rs6000_elf_in_small_data_p (const_tree decl
)
25346 if (rs6000_sdata
== SDATA_NONE
)
25349 /* We want to merge strings, so we never consider them small data. */
25350 if (TREE_CODE (decl
) == STRING_CST
)
25353 /* Functions are never in the small data area. */
25354 if (TREE_CODE (decl
) == FUNCTION_DECL
)
25357 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
25359 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
25360 if (compare_section_name (section
, ".sdata")
25361 || compare_section_name (section
, ".sdata2")
25362 || compare_section_name (section
, ".gnu.linkonce.s")
25363 || compare_section_name (section
, ".sbss")
25364 || compare_section_name (section
, ".sbss2")
25365 || compare_section_name (section
, ".gnu.linkonce.sb")
25366 || strcmp (section
, ".PPC.EMB.sdata0") == 0
25367 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
25372 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
25375 && size
<= g_switch_value
25376 /* If it's not public, and we're not going to reference it there,
25377 there's no need to put it in the small data section. */
25378 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
25385 #endif /* USING_ELFOS_H */
25387 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25390 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
25392 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
25395 /* Return a REG that occurs in ADDR with coefficient 1.
25396 ADDR can be effectively incremented by incrementing REG.
25398 r0 is special and we must not select it as an address
25399 register by this routine since our caller will try to
25400 increment the returned register via an "la" instruction. */
25403 find_addr_reg (rtx addr
)
25405 while (GET_CODE (addr
) == PLUS
)
25407 if (GET_CODE (XEXP (addr
, 0)) == REG
25408 && REGNO (XEXP (addr
, 0)) != 0)
25409 addr
= XEXP (addr
, 0);
25410 else if (GET_CODE (XEXP (addr
, 1)) == REG
25411 && REGNO (XEXP (addr
, 1)) != 0)
25412 addr
= XEXP (addr
, 1);
25413 else if (CONSTANT_P (XEXP (addr
, 0)))
25414 addr
= XEXP (addr
, 1);
25415 else if (CONSTANT_P (XEXP (addr
, 1)))
25416 addr
= XEXP (addr
, 0);
25418 gcc_unreachable ();
25420 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
25425 rs6000_fatal_bad_address (rtx op
)
25427 fatal_insn ("bad address", op
);
25432 typedef struct branch_island_d
{
25433 tree function_name
;
25438 DEF_VEC_O(branch_island
);
25439 DEF_VEC_ALLOC_O(branch_island
,gc
);
25441 static VEC(branch_island
,gc
) *branch_islands
;
25443 /* Remember to generate a branch island for far calls to the given
25447 add_compiler_branch_island (tree label_name
, tree function_name
,
25450 branch_island
*bi
= VEC_safe_push (branch_island
, gc
, branch_islands
, NULL
);
25452 bi
->function_name
= function_name
;
25453 bi
->label_name
= label_name
;
25454 bi
->line_number
= line_number
;
25457 /* Generate far-jump branch islands for everything recorded in
25458 branch_islands. Invoked immediately after the last instruction of
25459 the epilogue has been emitted; the branch islands must be appended
25460 to, and contiguous with, the function body. Mach-O stubs are
25461 generated in machopic_output_stub(). */
25464 macho_branch_islands (void)
25468 while (!VEC_empty (branch_island
, branch_islands
))
25470 branch_island
*bi
= VEC_last (branch_island
, branch_islands
);
25471 const char *label
= IDENTIFIER_POINTER (bi
->label_name
);
25472 const char *name
= IDENTIFIER_POINTER (bi
->function_name
);
25473 char name_buf
[512];
25474 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25475 if (name
[0] == '*' || name
[0] == '&')
25476 strcpy (name_buf
, name
+1);
25480 strcpy (name_buf
+1, name
);
25482 strcpy (tmp_buf
, "\n");
25483 strcat (tmp_buf
, label
);
25484 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25485 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25486 dbxout_stabd (N_SLINE
, bi
->line_number
);
25487 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25490 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
25491 strcat (tmp_buf
, label
);
25492 strcat (tmp_buf
, "_pic\n");
25493 strcat (tmp_buf
, label
);
25494 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
25496 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
25497 strcat (tmp_buf
, name_buf
);
25498 strcat (tmp_buf
, " - ");
25499 strcat (tmp_buf
, label
);
25500 strcat (tmp_buf
, "_pic)\n");
25502 strcat (tmp_buf
, "\tmtlr r0\n");
25504 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
25505 strcat (tmp_buf
, name_buf
);
25506 strcat (tmp_buf
, " - ");
25507 strcat (tmp_buf
, label
);
25508 strcat (tmp_buf
, "_pic)\n");
25510 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
25514 strcat (tmp_buf
, ":\nlis r12,hi16(");
25515 strcat (tmp_buf
, name_buf
);
25516 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
25517 strcat (tmp_buf
, name_buf
);
25518 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
25520 output_asm_insn (tmp_buf
, 0);
25521 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25522 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25523 dbxout_stabd (N_SLINE
, bi
->line_number
);
25524 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25525 VEC_pop (branch_island
, branch_islands
);
25529 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25530 already there or not. */
25533 no_previous_def (tree function_name
)
25538 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25539 if (function_name
== bi
->function_name
)
25544 /* GET_PREV_LABEL gets the label name from the previous definition of
25548 get_prev_label (tree function_name
)
25553 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25554 if (function_name
== bi
->function_name
)
25555 return bi
->label_name
;
25559 /* INSN is either a function call or a millicode call. It may have an
25560 unconditional jump in its delay slot.
25562 CALL_DEST is the routine we are calling. */
25565 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
25566 int cookie_operand_number
)
25568 static char buf
[256];
25569 if (darwin_emit_branch_islands
25570 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
25571 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
25574 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
25576 if (no_previous_def (funname
))
25578 rtx label_rtx
= gen_label_rtx ();
25579 char *label_buf
, temp_buf
[256];
25580 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
25581 CODE_LABEL_NUMBER (label_rtx
));
25582 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
25583 labelname
= get_identifier (label_buf
);
25584 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
25587 labelname
= get_prev_label (funname
);
25589 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25590 instruction will reach 'foo', otherwise link as 'bl L42'".
25591 "L42" should be a 'branch island', that will do a far jump to
25592 'foo'. Branch islands are generated in
25593 macho_branch_islands(). */
25594 sprintf (buf
, "jbsr %%z%d,%.246s",
25595 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
25598 sprintf (buf
, "bl %%z%d", dest_operand_number
);
25602 /* Generate PIC and indirect symbol stubs. */
25605 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
25607 unsigned int length
;
25608 char *symbol_name
, *lazy_ptr_name
;
25609 char *local_label_0
;
25610 static int label
= 0;
25612 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25613 symb
= (*targetm
.strip_name_encoding
) (symb
);
25616 length
= strlen (symb
);
25617 symbol_name
= XALLOCAVEC (char, length
+ 32);
25618 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
25620 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
25621 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
25624 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
25626 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
25630 fprintf (file
, "\t.align 5\n");
25632 fprintf (file
, "%s:\n", stub
);
25633 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25636 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25637 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
25639 fprintf (file
, "\tmflr r0\n");
25640 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
25641 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
25642 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
25643 lazy_ptr_name
, local_label_0
);
25644 fprintf (file
, "\tmtlr r0\n");
25645 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
25646 (TARGET_64BIT
? "ldu" : "lwzu"),
25647 lazy_ptr_name
, local_label_0
);
25648 fprintf (file
, "\tmtctr r12\n");
25649 fprintf (file
, "\tbctr\n");
25653 fprintf (file
, "\t.align 4\n");
25655 fprintf (file
, "%s:\n", stub
);
25656 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25658 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
25659 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
25660 (TARGET_64BIT
? "ldu" : "lwzu"),
25662 fprintf (file
, "\tmtctr r12\n");
25663 fprintf (file
, "\tbctr\n");
25666 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
25667 fprintf (file
, "%s:\n", lazy_ptr_name
);
25668 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25669 fprintf (file
, "%sdyld_stub_binding_helper\n",
25670 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
25673 /* Legitimize PIC addresses. If the address is already
25674 position-independent, we return ORIG. Newly generated
25675 position-independent addresses go into a reg. This is REG if non
25676 zero, otherwise we allocate register(s) as necessary. */
25678 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25681 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
25686 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
25687 reg
= gen_reg_rtx (Pmode
);
25689 if (GET_CODE (orig
) == CONST
)
25693 if (GET_CODE (XEXP (orig
, 0)) == PLUS
25694 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
25697 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
25699 /* Use a different reg for the intermediate value, as
25700 it will be marked UNCHANGING. */
25701 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
25702 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
25705 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
25708 if (GET_CODE (offset
) == CONST_INT
)
25710 if (SMALL_INT (offset
))
25711 return plus_constant (base
, INTVAL (offset
));
25712 else if (! reload_in_progress
&& ! reload_completed
)
25713 offset
= force_reg (Pmode
, offset
);
25716 rtx mem
= force_const_mem (Pmode
, orig
);
25717 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
25720 return gen_rtx_PLUS (Pmode
, base
, offset
);
25723 /* Fall back on generic machopic code. */
25724 return machopic_legitimize_pic_address (orig
, mode
, reg
);
25727 /* Output a .machine directive for the Darwin assembler, and call
25728 the generic start_file routine. */
25731 rs6000_darwin_file_start (void)
25733 static const struct
25739 { "ppc64", "ppc64", MASK_64BIT
},
25740 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
25741 { "power4", "ppc970", 0 },
25742 { "G5", "ppc970", 0 },
25743 { "7450", "ppc7450", 0 },
25744 { "7400", "ppc7400", MASK_ALTIVEC
},
25745 { "G4", "ppc7400", 0 },
25746 { "750", "ppc750", 0 },
25747 { "740", "ppc750", 0 },
25748 { "G3", "ppc750", 0 },
25749 { "604e", "ppc604e", 0 },
25750 { "604", "ppc604", 0 },
25751 { "603e", "ppc603", 0 },
25752 { "603", "ppc603", 0 },
25753 { "601", "ppc601", 0 },
25754 { NULL
, "ppc", 0 } };
25755 const char *cpu_id
= "";
25758 rs6000_file_start ();
25759 darwin_file_start ();
25761 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25762 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
25763 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
25764 && rs6000_select
[i
].string
[0] != '\0')
25765 cpu_id
= rs6000_select
[i
].string
;
25767 /* Look through the mapping array. Pick the first name that either
25768 matches the argument, has a bit set in IF_SET that is also set
25769 in the target flags, or has a NULL name. */
25772 while (mapping
[i
].arg
!= NULL
25773 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
25774 && (mapping
[i
].if_set
& target_flags
) == 0)
25777 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
25780 #endif /* TARGET_MACHO */
25784 rs6000_elf_reloc_rw_mask (void)
25788 else if (DEFAULT_ABI
== ABI_AIX
)
25794 /* Record an element in the table of global constructors. SYMBOL is
25795 a SYMBOL_REF of the function to be called; PRIORITY is a number
25796 between 0 and MAX_INIT_PRIORITY.
25798 This differs from default_named_section_asm_out_constructor in
25799 that we have special handling for -mrelocatable. */
25802 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
25804 const char *section
= ".ctors";
25807 if (priority
!= DEFAULT_INIT_PRIORITY
)
25809 sprintf (buf
, ".ctors.%.5u",
25810 /* Invert the numbering so the linker puts us in the proper
25811 order; constructors are run from right to left, and the
25812 linker sorts in increasing order. */
25813 MAX_INIT_PRIORITY
- priority
);
25817 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25818 assemble_align (POINTER_SIZE
);
25820 if (TARGET_RELOCATABLE
)
25822 fputs ("\t.long (", asm_out_file
);
25823 output_addr_const (asm_out_file
, symbol
);
25824 fputs (")@fixup\n", asm_out_file
);
25827 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25831 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
25833 const char *section
= ".dtors";
25836 if (priority
!= DEFAULT_INIT_PRIORITY
)
25838 sprintf (buf
, ".dtors.%.5u",
25839 /* Invert the numbering so the linker puts us in the proper
25840 order; constructors are run from right to left, and the
25841 linker sorts in increasing order. */
25842 MAX_INIT_PRIORITY
- priority
);
25846 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25847 assemble_align (POINTER_SIZE
);
25849 if (TARGET_RELOCATABLE
)
25851 fputs ("\t.long (", asm_out_file
);
25852 output_addr_const (asm_out_file
, symbol
);
25853 fputs (")@fixup\n", asm_out_file
);
25856 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25860 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
25864 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
25865 ASM_OUTPUT_LABEL (file
, name
);
25866 fputs (DOUBLE_INT_ASM_OP
, file
);
25867 rs6000_output_function_entry (file
, name
);
25868 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
25871 fputs ("\t.size\t", file
);
25872 assemble_name (file
, name
);
25873 fputs (",24\n\t.type\t.", file
);
25874 assemble_name (file
, name
);
25875 fputs (",@function\n", file
);
25876 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
25878 fputs ("\t.globl\t.", file
);
25879 assemble_name (file
, name
);
25884 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25885 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25886 rs6000_output_function_entry (file
, name
);
25887 fputs (":\n", file
);
25891 if (TARGET_RELOCATABLE
25892 && !TARGET_SECURE_PLT
25893 && (get_pool_size () != 0 || crtl
->profile
)
25898 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
25900 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
25901 fprintf (file
, "\t.long ");
25902 assemble_name (file
, buf
);
25904 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
25905 assemble_name (file
, buf
);
25909 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25910 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25912 if (DEFAULT_ABI
== ABI_AIX
)
25914 const char *desc_name
, *orig_name
;
25916 orig_name
= (*targetm
.strip_name_encoding
) (name
);
25917 desc_name
= orig_name
;
25918 while (*desc_name
== '.')
25921 if (TREE_PUBLIC (decl
))
25922 fprintf (file
, "\t.globl %s\n", desc_name
);
25924 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25925 fprintf (file
, "%s:\n", desc_name
);
25926 fprintf (file
, "\t.long %s\n", orig_name
);
25927 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
25928 if (DEFAULT_ABI
== ABI_AIX
)
25929 fputs ("\t.long 0\n", file
);
25930 fprintf (file
, "\t.previous\n");
25932 ASM_OUTPUT_LABEL (file
, name
);
25936 rs6000_elf_file_end (void)
25938 #ifdef HAVE_AS_GNU_ATTRIBUTE
25939 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
25941 if (rs6000_passes_float
)
25942 fprintf (asm_out_file
, "\t.gnu_attribute 4, %d\n",
25943 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
25944 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
25946 if (rs6000_passes_vector
)
25947 fprintf (asm_out_file
, "\t.gnu_attribute 8, %d\n",
25948 (TARGET_ALTIVEC_ABI
? 2
25949 : TARGET_SPE_ABI
? 3
25951 if (rs6000_returns_struct
)
25952 fprintf (asm_out_file
, "\t.gnu_attribute 12, %d\n",
25953 aix_struct_return
? 2 : 1);
25956 #ifdef POWERPC_LINUX
25958 file_end_indicate_exec_stack ();
25965 rs6000_xcoff_asm_output_anchor (rtx symbol
)
25969 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
25970 SYMBOL_REF_BLOCK_OFFSET (symbol
));
25971 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
25975 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
25977 fputs (GLOBAL_ASM_OP
, stream
);
25978 RS6000_OUTPUT_BASENAME (stream
, name
);
25979 putc ('\n', stream
);
25982 /* A get_unnamed_decl callback, used for read-only sections. PTR
25983 points to the section string variable. */
25986 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
25988 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
25989 *(const char *const *) directive
,
25990 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
25993 /* Likewise for read-write sections. */
25996 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
25998 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
25999 *(const char *const *) directive
,
26000 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
26003 /* A get_unnamed_section callback, used for switching to toc_section. */
26006 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
26008 if (TARGET_MINIMAL_TOC
)
26010 /* toc_section is always selected at least once from
26011 rs6000_xcoff_file_start, so this is guaranteed to
26012 always be defined once and only once in each file. */
26013 if (!toc_initialized
)
26015 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
26016 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
26017 toc_initialized
= 1;
26019 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
26020 (TARGET_32BIT
? "" : ",3"));
26023 fputs ("\t.toc\n", asm_out_file
);
26026 /* Implement TARGET_ASM_INIT_SECTIONS. */
26029 rs6000_xcoff_asm_init_sections (void)
26031 read_only_data_section
26032 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
26033 &xcoff_read_only_section_name
);
26035 private_data_section
26036 = get_unnamed_section (SECTION_WRITE
,
26037 rs6000_xcoff_output_readwrite_section_asm_op
,
26038 &xcoff_private_data_section_name
);
26040 read_only_private_data_section
26041 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
26042 &xcoff_private_data_section_name
);
26045 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
26047 readonly_data_section
= read_only_data_section
;
26048 exception_section
= data_section
;
26052 rs6000_xcoff_reloc_rw_mask (void)
26058 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
26059 tree decl ATTRIBUTE_UNUSED
)
26062 static const char * const suffix
[3] = { "PR", "RO", "RW" };
26064 if (flags
& SECTION_CODE
)
26066 else if (flags
& SECTION_WRITE
)
26071 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
26072 (flags
& SECTION_CODE
) ? "." : "",
26073 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
26077 rs6000_xcoff_select_section (tree decl
, int reloc
,
26078 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
26080 if (decl_readonly_section (decl
, reloc
))
26082 if (TREE_PUBLIC (decl
))
26083 return read_only_data_section
;
26085 return read_only_private_data_section
;
26089 if (TREE_PUBLIC (decl
))
26090 return data_section
;
26092 return private_data_section
;
26097 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
26101 /* Use select_section for private and uninitialized data. */
26102 if (!TREE_PUBLIC (decl
)
26103 || DECL_COMMON (decl
)
26104 || DECL_INITIAL (decl
) == NULL_TREE
26105 || DECL_INITIAL (decl
) == error_mark_node
26106 || (flag_zero_initialized_in_bss
26107 && initializer_zerop (DECL_INITIAL (decl
))))
26110 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
26111 name
= (*targetm
.strip_name_encoding
) (name
);
26112 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
26115 /* Select section for constant in constant pool.
26117 On RS/6000, all constants are in the private read-only data area.
26118 However, if this is being placed in the TOC it must be output as a
26122 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
26123 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
26125 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
26126 return toc_section
;
26128 return read_only_private_data_section
;
26131 /* Remove any trailing [DS] or the like from the symbol name. */
26133 static const char *
26134 rs6000_xcoff_strip_name_encoding (const char *name
)
26139 len
= strlen (name
);
26140 if (name
[len
- 1] == ']')
26141 return ggc_alloc_string (name
, len
- 4);
26146 /* Section attributes. AIX is always PIC. */
26148 static unsigned int
26149 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
26151 unsigned int align
;
26152 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
26154 /* Align to at least UNIT size. */
26155 if (flags
& SECTION_CODE
)
26156 align
= MIN_UNITS_PER_WORD
;
26158 /* Increase alignment of large objects if not already stricter. */
26159 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
26160 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
26161 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
26163 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
26166 /* Output at beginning of assembler file.
26168 Initialize the section names for the RS/6000 at this point.
26170 Specify filename, including full path, to assembler.
26172 We want to go into the TOC section so at least one .toc will be emitted.
26173 Also, in order to output proper .bs/.es pairs, we need at least one static
26174 [RW] section emitted.
26176 Finally, declare mcount when profiling to make the assembler happy. */
26179 rs6000_xcoff_file_start (void)
26181 rs6000_gen_section_name (&xcoff_bss_section_name
,
26182 main_input_filename
, ".bss_");
26183 rs6000_gen_section_name (&xcoff_private_data_section_name
,
26184 main_input_filename
, ".rw_");
26185 rs6000_gen_section_name (&xcoff_read_only_section_name
,
26186 main_input_filename
, ".ro_");
26188 fputs ("\t.file\t", asm_out_file
);
26189 output_quoted_string (asm_out_file
, main_input_filename
);
26190 fputc ('\n', asm_out_file
);
26191 if (write_symbols
!= NO_DEBUG
)
26192 switch_to_section (private_data_section
);
26193 switch_to_section (text_section
);
26195 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
26196 rs6000_file_start ();
26199 /* Output at end of assembler file.
26200 On the RS/6000, referencing data should automatically pull in text. */
26203 rs6000_xcoff_file_end (void)
26205 switch_to_section (text_section
);
26206 fputs ("_section_.text:\n", asm_out_file
);
26207 switch_to_section (data_section
);
26208 fputs (TARGET_32BIT
26209 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26212 #endif /* TARGET_XCOFF */
26214 /* Compute a (partial) cost for rtx X. Return true if the complete
26215 cost has been computed, and false if subexpressions should be
26216 scanned. In either case, *TOTAL contains the cost result. */
26219 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
26222 enum machine_mode mode
= GET_MODE (x
);
26226 /* On the RS/6000, if it is valid in the insn, it is free. */
26228 if (((outer_code
== SET
26229 || outer_code
== PLUS
26230 || outer_code
== MINUS
)
26231 && (satisfies_constraint_I (x
)
26232 || satisfies_constraint_L (x
)))
26233 || (outer_code
== AND
26234 && (satisfies_constraint_K (x
)
26236 ? satisfies_constraint_L (x
)
26237 : satisfies_constraint_J (x
))
26238 || mask_operand (x
, mode
)
26240 && mask64_operand (x
, DImode
))))
26241 || ((outer_code
== IOR
|| outer_code
== XOR
)
26242 && (satisfies_constraint_K (x
)
26244 ? satisfies_constraint_L (x
)
26245 : satisfies_constraint_J (x
))))
26246 || outer_code
== ASHIFT
26247 || outer_code
== ASHIFTRT
26248 || outer_code
== LSHIFTRT
26249 || outer_code
== ROTATE
26250 || outer_code
== ROTATERT
26251 || outer_code
== ZERO_EXTRACT
26252 || (outer_code
== MULT
26253 && satisfies_constraint_I (x
))
26254 || ((outer_code
== DIV
|| outer_code
== UDIV
26255 || outer_code
== MOD
|| outer_code
== UMOD
)
26256 && exact_log2 (INTVAL (x
)) >= 0)
26257 || (outer_code
== COMPARE
26258 && (satisfies_constraint_I (x
)
26259 || satisfies_constraint_K (x
)))
26260 || ((outer_code
== EQ
|| outer_code
== NE
)
26261 && (satisfies_constraint_I (x
)
26262 || satisfies_constraint_K (x
)
26264 ? satisfies_constraint_L (x
)
26265 : satisfies_constraint_J (x
))))
26266 || (outer_code
== GTU
26267 && satisfies_constraint_I (x
))
26268 || (outer_code
== LTU
26269 && satisfies_constraint_P (x
)))
26274 else if ((outer_code
== PLUS
26275 && reg_or_add_cint_operand (x
, VOIDmode
))
26276 || (outer_code
== MINUS
26277 && reg_or_sub_cint_operand (x
, VOIDmode
))
26278 || ((outer_code
== SET
26279 || outer_code
== IOR
26280 || outer_code
== XOR
)
26282 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
26284 *total
= COSTS_N_INSNS (1);
26290 if (mode
== DImode
&& code
== CONST_DOUBLE
)
26292 if ((outer_code
== IOR
|| outer_code
== XOR
)
26293 && CONST_DOUBLE_HIGH (x
) == 0
26294 && (CONST_DOUBLE_LOW (x
)
26295 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
26300 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
26301 || ((outer_code
== SET
26302 || outer_code
== IOR
26303 || outer_code
== XOR
)
26304 && CONST_DOUBLE_HIGH (x
) == 0))
26306 *total
= COSTS_N_INSNS (1);
26316 /* When optimizing for size, MEM should be slightly more expensive
26317 than generating address, e.g., (plus (reg) (const)).
26318 L1 cache latency is about two instructions. */
26319 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26328 if (FLOAT_MODE_P (mode
))
26329 *total
= rs6000_cost
->fp
;
26331 *total
= COSTS_N_INSNS (1);
26335 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
26336 && satisfies_constraint_I (XEXP (x
, 1)))
26338 if (INTVAL (XEXP (x
, 1)) >= -256
26339 && INTVAL (XEXP (x
, 1)) <= 255)
26340 *total
= rs6000_cost
->mulsi_const9
;
26342 *total
= rs6000_cost
->mulsi_const
;
26344 else if (mode
== SFmode
)
26345 *total
= rs6000_cost
->fp
;
26346 else if (FLOAT_MODE_P (mode
))
26347 *total
= rs6000_cost
->dmul
;
26348 else if (mode
== DImode
)
26349 *total
= rs6000_cost
->muldi
;
26351 *total
= rs6000_cost
->mulsi
;
26355 if (mode
== SFmode
)
26356 *total
= rs6000_cost
->fp
;
26358 *total
= rs6000_cost
->dmul
;
26363 if (FLOAT_MODE_P (mode
))
26365 *total
= mode
== DFmode
? rs6000_cost
->ddiv
26366 : rs6000_cost
->sdiv
;
26373 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
26374 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
26376 if (code
== DIV
|| code
== MOD
)
26378 *total
= COSTS_N_INSNS (2);
26381 *total
= COSTS_N_INSNS (1);
26385 if (GET_MODE (XEXP (x
, 1)) == DImode
)
26386 *total
= rs6000_cost
->divdi
;
26388 *total
= rs6000_cost
->divsi
;
26390 /* Add in shift and subtract for MOD. */
26391 if (code
== MOD
|| code
== UMOD
)
26392 *total
+= COSTS_N_INSNS (2);
26397 *total
= COSTS_N_INSNS (4);
26401 *total
= COSTS_N_INSNS (TARGET_POPCNTD
? 1 : 6);
26405 *total
= COSTS_N_INSNS (TARGET_CMPB
? 2 : 6);
26409 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
26421 *total
= COSTS_N_INSNS (1);
26429 /* Handle mul_highpart. */
26430 if (outer_code
== TRUNCATE
26431 && GET_CODE (XEXP (x
, 0)) == MULT
)
26433 if (mode
== DImode
)
26434 *total
= rs6000_cost
->muldi
;
26436 *total
= rs6000_cost
->mulsi
;
26439 else if (outer_code
== AND
)
26442 *total
= COSTS_N_INSNS (1);
26447 if (GET_CODE (XEXP (x
, 0)) == MEM
)
26450 *total
= COSTS_N_INSNS (1);
26456 if (!FLOAT_MODE_P (mode
))
26458 *total
= COSTS_N_INSNS (1);
26464 case UNSIGNED_FLOAT
:
26467 case FLOAT_TRUNCATE
:
26468 *total
= rs6000_cost
->fp
;
26472 if (mode
== DFmode
)
26475 *total
= rs6000_cost
->fp
;
26479 switch (XINT (x
, 1))
26482 *total
= rs6000_cost
->fp
;
26494 *total
= COSTS_N_INSNS (1);
26497 else if (FLOAT_MODE_P (mode
)
26498 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26500 *total
= rs6000_cost
->fp
;
26508 /* Carry bit requires mode == Pmode.
26509 NEG or PLUS already counted so only add one. */
26511 && (outer_code
== NEG
|| outer_code
== PLUS
))
26513 *total
= COSTS_N_INSNS (1);
26516 if (outer_code
== SET
)
26518 if (XEXP (x
, 1) == const0_rtx
)
26520 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26521 *total
= COSTS_N_INSNS (8);
26523 *total
= COSTS_N_INSNS (2);
26526 else if (mode
== Pmode
)
26528 *total
= COSTS_N_INSNS (3);
26537 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
26539 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26540 *total
= COSTS_N_INSNS (8);
26542 *total
= COSTS_N_INSNS (2);
26546 if (outer_code
== COMPARE
)
26560 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26563 rs6000_debug_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
26566 bool ret
= rs6000_rtx_costs (x
, code
, outer_code
, total
, speed
);
26569 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26570 "total = %d, speed = %s, x:\n",
26571 ret
? "complete" : "scan inner",
26572 GET_RTX_NAME (code
),
26573 GET_RTX_NAME (outer_code
),
26575 speed
? "true" : "false");
26582 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26585 rs6000_debug_address_cost (rtx x
, bool speed
)
26587 int ret
= TARGET_ADDRESS_COST (x
, speed
);
26589 fprintf (stderr
, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26590 ret
, speed
? "true" : "false");
26597 /* A C expression returning the cost of moving data from a register of class
26598 CLASS1 to one of CLASS2. */
26601 rs6000_register_move_cost (enum machine_mode mode
,
26602 reg_class_t from
, reg_class_t to
)
26606 /* Moves from/to GENERAL_REGS. */
26607 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
26608 || reg_classes_intersect_p (from
, GENERAL_REGS
))
26610 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
26613 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
|| from
== VSX_REGS
)
26614 ret
= (rs6000_memory_move_cost (mode
, from
, false)
26615 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, false));
26617 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26619 else if (from
== CR_REGS
)
26622 /* Power6 has slower LR/CTR moves so make them more expensive than
26623 memory in order to bias spills to memory .*/
26624 else if (rs6000_cpu
== PROCESSOR_POWER6
26625 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
26626 ret
= 6 * hard_regno_nregs
[0][mode
];
26629 /* A move will cost one instruction per GPR moved. */
26630 ret
= 2 * hard_regno_nregs
[0][mode
];
26633 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26634 else if (VECTOR_UNIT_VSX_P (mode
)
26635 && reg_classes_intersect_p (to
, VSX_REGS
)
26636 && reg_classes_intersect_p (from
, VSX_REGS
))
26637 ret
= 2 * hard_regno_nregs
[32][mode
];
26639 /* Moving between two similar registers is just one instruction. */
26640 else if (reg_classes_intersect_p (to
, from
))
26641 ret
= (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
26643 /* Everything else has to go through GENERAL_REGS. */
26645 ret
= (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
26646 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
26648 if (TARGET_DEBUG_COST
)
26650 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26651 ret
, GET_MODE_NAME (mode
), reg_class_names
[from
],
26652 reg_class_names
[to
]);
26657 /* A C expressions returning the cost of moving data of MODE from a register to
26661 rs6000_memory_move_cost (enum machine_mode mode
, reg_class_t rclass
,
26662 bool in ATTRIBUTE_UNUSED
)
26666 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
26667 ret
= 4 * hard_regno_nregs
[0][mode
];
26668 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
26669 ret
= 4 * hard_regno_nregs
[32][mode
];
26670 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
26671 ret
= 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
26673 ret
= 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
26675 if (TARGET_DEBUG_COST
)
26677 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26678 ret
, GET_MODE_NAME (mode
), reg_class_names
[rclass
], in
);
26683 /* Returns a code for a target-specific builtin that implements
26684 reciprocal of the function, or NULL_TREE if not available. */
26687 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
26688 bool sqrt ATTRIBUTE_UNUSED
)
26690 if (optimize_insn_for_size_p ())
26696 case VSX_BUILTIN_XVSQRTDP
:
26697 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode
))
26700 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
26702 case VSX_BUILTIN_XVSQRTSP
:
26703 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode
))
26706 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V4SF
];
26715 case BUILT_IN_SQRT
:
26716 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode
))
26719 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRT
];
26721 case BUILT_IN_SQRTF
:
26722 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode
))
26725 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
26732 /* Load up a constant. If the mode is a vector mode, splat the value across
26733 all of the vector elements. */
26736 rs6000_load_constant_and_splat (enum machine_mode mode
, REAL_VALUE_TYPE dconst
)
26740 if (mode
== SFmode
|| mode
== DFmode
)
26742 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, mode
);
26743 reg
= force_reg (mode
, d
);
26745 else if (mode
== V4SFmode
)
26747 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, SFmode
);
26748 rtvec v
= gen_rtvec (4, d
, d
, d
, d
);
26749 reg
= gen_reg_rtx (mode
);
26750 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26752 else if (mode
== V2DFmode
)
26754 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, DFmode
);
26755 rtvec v
= gen_rtvec (2, d
, d
);
26756 reg
= gen_reg_rtx (mode
);
26757 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26760 gcc_unreachable ();
26765 /* Generate an FMA instruction. */
26768 rs6000_emit_madd (rtx target
, rtx m1
, rtx m2
, rtx a
)
26770 enum machine_mode mode
= GET_MODE (target
);
26773 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26774 gcc_assert (dst
!= NULL
);
26777 emit_move_insn (target
, dst
);
26780 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26783 rs6000_emit_msub (rtx target
, rtx m1
, rtx m2
, rtx a
)
26785 enum machine_mode mode
= GET_MODE (target
);
26788 /* Altivec does not support fms directly;
26789 generate in terms of fma in that case. */
26790 if (optab_handler (fms_optab
, mode
) != CODE_FOR_nothing
)
26791 dst
= expand_ternary_op (mode
, fms_optab
, m1
, m2
, a
, target
, 0);
26794 a
= expand_unop (mode
, neg_optab
, a
, NULL_RTX
, 0);
26795 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26797 gcc_assert (dst
!= NULL
);
26800 emit_move_insn (target
, dst
);
26803 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26806 rs6000_emit_nmsub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26808 enum machine_mode mode
= GET_MODE (dst
);
26811 /* This is a tad more complicated, since the fnma_optab is for
26812 a different expression: fma(-m1, m2, a), which is the same
26813 thing except in the case of signed zeros.
26815 Fortunately we know that if FMA is supported that FNMSUB is
26816 also supported in the ISA. Just expand it directly. */
26818 gcc_assert (optab_handler (fma_optab
, mode
) != CODE_FOR_nothing
);
26820 r
= gen_rtx_NEG (mode
, a
);
26821 r
= gen_rtx_FMA (mode
, m1
, m2
, r
);
26822 r
= gen_rtx_NEG (mode
, r
);
26823 emit_insn (gen_rtx_SET (VOIDmode
, dst
, r
));
26826 /* Newton-Raphson approximation of floating point divide with just 2 passes
26827 (either single precision floating point, or newer machines with higher
26828 accuracy estimates). Support both scalar and vector divide. Assumes no
26829 trapping math and finite arguments. */
26832 rs6000_emit_swdiv_high_precision (rtx dst
, rtx n
, rtx d
)
26834 enum machine_mode mode
= GET_MODE (dst
);
26835 rtx x0
, e0
, e1
, y1
, u0
, v0
;
26836 enum insn_code code
= optab_handler (smul_optab
, mode
);
26837 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26838 rtx one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26840 gcc_assert (code
!= CODE_FOR_nothing
);
26842 /* x0 = 1./d estimate */
26843 x0
= gen_reg_rtx (mode
);
26844 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26845 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26848 e0
= gen_reg_rtx (mode
);
26849 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - (d * x0) */
26851 e1
= gen_reg_rtx (mode
);
26852 rs6000_emit_madd (e1
, e0
, e0
, e0
); /* e1 = (e0 * e0) + e0 */
26854 y1
= gen_reg_rtx (mode
);
26855 rs6000_emit_madd (y1
, e1
, x0
, x0
); /* y1 = (e1 * x0) + x0 */
26857 u0
= gen_reg_rtx (mode
);
26858 emit_insn (gen_mul (u0
, n
, y1
)); /* u0 = n * y1 */
26860 v0
= gen_reg_rtx (mode
);
26861 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - (d * u0) */
26863 rs6000_emit_madd (dst
, v0
, y1
, u0
); /* dst = (v0 * y1) + u0 */
26866 /* Newton-Raphson approximation of floating point divide that has a low
26867 precision estimate. Assumes no trapping math and finite arguments. */
26870 rs6000_emit_swdiv_low_precision (rtx dst
, rtx n
, rtx d
)
26872 enum machine_mode mode
= GET_MODE (dst
);
26873 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
26874 enum insn_code code
= optab_handler (smul_optab
, mode
);
26875 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26877 gcc_assert (code
!= CODE_FOR_nothing
);
26879 one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26881 /* x0 = 1./d estimate */
26882 x0
= gen_reg_rtx (mode
);
26883 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26884 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26887 e0
= gen_reg_rtx (mode
);
26888 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - d * x0 */
26890 y1
= gen_reg_rtx (mode
);
26891 rs6000_emit_madd (y1
, e0
, x0
, x0
); /* y1 = x0 + e0 * x0 */
26893 e1
= gen_reg_rtx (mode
);
26894 emit_insn (gen_mul (e1
, e0
, e0
)); /* e1 = e0 * e0 */
26896 y2
= gen_reg_rtx (mode
);
26897 rs6000_emit_madd (y2
, e1
, y1
, y1
); /* y2 = y1 + e1 * y1 */
26899 e2
= gen_reg_rtx (mode
);
26900 emit_insn (gen_mul (e2
, e1
, e1
)); /* e2 = e1 * e1 */
26902 y3
= gen_reg_rtx (mode
);
26903 rs6000_emit_madd (y3
, e2
, y2
, y2
); /* y3 = y2 + e2 * y2 */
26905 u0
= gen_reg_rtx (mode
);
26906 emit_insn (gen_mul (u0
, n
, y3
)); /* u0 = n * y3 */
26908 v0
= gen_reg_rtx (mode
);
26909 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - d * u0 */
26911 rs6000_emit_madd (dst
, v0
, y3
, u0
); /* dst = u0 + v0 * y3 */
26914 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26915 add a reg_note saying that this was a division. Support both scalar and
26916 vector divide. Assumes no trapping math and finite arguments. */
26919 rs6000_emit_swdiv (rtx dst
, rtx n
, rtx d
, bool note_p
)
26921 enum machine_mode mode
= GET_MODE (dst
);
26923 if (RS6000_RECIP_HIGH_PRECISION_P (mode
))
26924 rs6000_emit_swdiv_high_precision (dst
, n
, d
);
26926 rs6000_emit_swdiv_low_precision (dst
, n
, d
);
26929 add_reg_note (get_last_insn (), REG_EQUAL
, gen_rtx_DIV (mode
, n
, d
));
26932 /* Newton-Raphson approximation of single/double-precision floating point
26933 rsqrt. Assumes no trapping math and finite arguments. */
26936 rs6000_emit_swrsqrt (rtx dst
, rtx src
)
26938 enum machine_mode mode
= GET_MODE (src
);
26939 rtx x0
= gen_reg_rtx (mode
);
26940 rtx y
= gen_reg_rtx (mode
);
26941 int passes
= (TARGET_RECIP_PRECISION
) ? 2 : 3;
26942 REAL_VALUE_TYPE dconst3_2
;
26945 enum insn_code code
= optab_handler (smul_optab
, mode
);
26946 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26948 gcc_assert (code
!= CODE_FOR_nothing
);
26950 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26951 real_from_integer (&dconst3_2
, VOIDmode
, 3, 0, 0);
26952 SET_REAL_EXP (&dconst3_2
, REAL_EXP (&dconst3_2
) - 1);
26954 halfthree
= rs6000_load_constant_and_splat (mode
, dconst3_2
);
26956 /* x0 = rsqrt estimate */
26957 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26958 gen_rtx_UNSPEC (mode
, gen_rtvec (1, src
),
26961 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26962 rs6000_emit_msub (y
, src
, halfthree
, src
);
26964 for (i
= 0; i
< passes
; i
++)
26966 rtx x1
= gen_reg_rtx (mode
);
26967 rtx u
= gen_reg_rtx (mode
);
26968 rtx v
= gen_reg_rtx (mode
);
26970 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26971 emit_insn (gen_mul (u
, x0
, x0
));
26972 rs6000_emit_nmsub (v
, y
, u
, halfthree
);
26973 emit_insn (gen_mul (x1
, x0
, v
));
26977 emit_move_insn (dst
, x0
);
26981 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26982 (Power7) targets. DST is the target, and SRC is the argument operand. */
26985 rs6000_emit_popcount (rtx dst
, rtx src
)
26987 enum machine_mode mode
= GET_MODE (dst
);
26990 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26991 if (TARGET_POPCNTD
)
26993 if (mode
== SImode
)
26994 emit_insn (gen_popcntdsi2 (dst
, src
));
26996 emit_insn (gen_popcntddi2 (dst
, src
));
27000 tmp1
= gen_reg_rtx (mode
);
27002 if (mode
== SImode
)
27004 emit_insn (gen_popcntbsi2 (tmp1
, src
));
27005 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
27007 tmp2
= force_reg (SImode
, tmp2
);
27008 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
27012 emit_insn (gen_popcntbdi2 (tmp1
, src
));
27013 tmp2
= expand_mult (DImode
, tmp1
,
27014 GEN_INT ((HOST_WIDE_INT
)
27015 0x01010101 << 32 | 0x01010101),
27017 tmp2
= force_reg (DImode
, tmp2
);
27018 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
27023 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27024 target, and SRC is the argument operand. */
27027 rs6000_emit_parity (rtx dst
, rtx src
)
27029 enum machine_mode mode
= GET_MODE (dst
);
27032 tmp
= gen_reg_rtx (mode
);
27034 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27037 if (mode
== SImode
)
27039 emit_insn (gen_popcntbsi2 (tmp
, src
));
27040 emit_insn (gen_paritysi2_cmpb (dst
, tmp
));
27044 emit_insn (gen_popcntbdi2 (tmp
, src
));
27045 emit_insn (gen_paritydi2_cmpb (dst
, tmp
));
27050 if (mode
== SImode
)
27052 /* Is mult+shift >= shift+xor+shift+xor? */
27053 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
27055 rtx tmp1
, tmp2
, tmp3
, tmp4
;
27057 tmp1
= gen_reg_rtx (SImode
);
27058 emit_insn (gen_popcntbsi2 (tmp1
, src
));
27060 tmp2
= gen_reg_rtx (SImode
);
27061 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
27062 tmp3
= gen_reg_rtx (SImode
);
27063 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
27065 tmp4
= gen_reg_rtx (SImode
);
27066 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
27067 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
27070 rs6000_emit_popcount (tmp
, src
);
27071 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
27075 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27076 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
27078 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
27080 tmp1
= gen_reg_rtx (DImode
);
27081 emit_insn (gen_popcntbdi2 (tmp1
, src
));
27083 tmp2
= gen_reg_rtx (DImode
);
27084 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
27085 tmp3
= gen_reg_rtx (DImode
);
27086 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
27088 tmp4
= gen_reg_rtx (DImode
);
27089 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
27090 tmp5
= gen_reg_rtx (DImode
);
27091 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
27093 tmp6
= gen_reg_rtx (DImode
);
27094 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
27095 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
27098 rs6000_emit_popcount (tmp
, src
);
27099 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
27103 /* Return an RTX representing where to find the function value of a
27104 function returning MODE. */
27106 rs6000_complex_function_value (enum machine_mode mode
)
27108 unsigned int regno
;
27110 enum machine_mode inner
= GET_MODE_INNER (mode
);
27111 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
27113 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27114 regno
= FP_ARG_RETURN
;
27117 regno
= GP_ARG_RETURN
;
27119 /* 32-bit is OK since it'll go in r3/r4. */
27120 if (TARGET_32BIT
&& inner_bytes
>= 4)
27121 return gen_rtx_REG (mode
, regno
);
27124 if (inner_bytes
>= 8)
27125 return gen_rtx_REG (mode
, regno
);
27127 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
27129 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
27130 GEN_INT (inner_bytes
));
27131 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
27134 /* Target hook for TARGET_FUNCTION_VALUE.
27136 On the SPE, both FPs and vectors are returned in r3.
27138 On RS/6000 an integer value is in r3 and a floating-point value is in
27139 fp1, unless -msoft-float. */
27142 rs6000_function_value (const_tree valtype
,
27143 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
27144 bool outgoing ATTRIBUTE_UNUSED
)
27146 enum machine_mode mode
;
27147 unsigned int regno
;
27149 /* Special handling for structs in darwin64. */
27151 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype
), valtype
))
27153 CUMULATIVE_ARGS valcum
;
27157 valcum
.fregno
= FP_ARG_MIN_REG
;
27158 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
27159 /* Do a trial code generation as if this were going to be passed as
27160 an argument; if any part goes in memory, we return NULL. */
27161 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, true, /* retval= */ true);
27164 /* Otherwise fall through to standard ABI rules. */
27167 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
27169 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27170 return gen_rtx_PARALLEL (DImode
,
27172 gen_rtx_EXPR_LIST (VOIDmode
,
27173 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27175 gen_rtx_EXPR_LIST (VOIDmode
,
27176 gen_rtx_REG (SImode
,
27177 GP_ARG_RETURN
+ 1),
27180 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
27182 return gen_rtx_PARALLEL (DCmode
,
27184 gen_rtx_EXPR_LIST (VOIDmode
,
27185 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27187 gen_rtx_EXPR_LIST (VOIDmode
,
27188 gen_rtx_REG (SImode
,
27189 GP_ARG_RETURN
+ 1),
27191 gen_rtx_EXPR_LIST (VOIDmode
,
27192 gen_rtx_REG (SImode
,
27193 GP_ARG_RETURN
+ 2),
27195 gen_rtx_EXPR_LIST (VOIDmode
,
27196 gen_rtx_REG (SImode
,
27197 GP_ARG_RETURN
+ 3),
27201 mode
= TYPE_MODE (valtype
);
27202 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
27203 || POINTER_TYPE_P (valtype
))
27204 mode
= TARGET_32BIT
? SImode
: DImode
;
27206 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27207 /* _Decimal128 must use an even/odd register pair. */
27208 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
27209 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
27210 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
27211 regno
= FP_ARG_RETURN
;
27212 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
27213 && targetm
.calls
.split_complex_arg
)
27214 return rs6000_complex_function_value (mode
);
27215 else if (TREE_CODE (valtype
) == VECTOR_TYPE
27216 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
27217 && ALTIVEC_VECTOR_MODE (mode
))
27218 regno
= ALTIVEC_ARG_RETURN
;
27219 else if (TREE_CODE (valtype
) == VECTOR_TYPE
27220 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
27221 && VSX_VECTOR_MODE (mode
))
27222 regno
= ALTIVEC_ARG_RETURN
;
27223 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
27224 && (mode
== DFmode
|| mode
== DCmode
27225 || mode
== TFmode
|| mode
== TCmode
))
27226 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
27228 regno
= GP_ARG_RETURN
;
27230 return gen_rtx_REG (mode
, regno
);
27233 /* Define how to find the value returned by a library function
27234 assuming the value has mode MODE. */
27236 rs6000_libcall_value (enum machine_mode mode
)
27238 unsigned int regno
;
27240 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
27242 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27243 return gen_rtx_PARALLEL (DImode
,
27245 gen_rtx_EXPR_LIST (VOIDmode
,
27246 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27248 gen_rtx_EXPR_LIST (VOIDmode
,
27249 gen_rtx_REG (SImode
,
27250 GP_ARG_RETURN
+ 1),
27254 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27255 /* _Decimal128 must use an even/odd register pair. */
27256 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
27257 else if (SCALAR_FLOAT_MODE_P (mode
)
27258 && TARGET_HARD_FLOAT
&& TARGET_FPRS
27259 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
27260 regno
= FP_ARG_RETURN
;
27261 else if (ALTIVEC_VECTOR_MODE (mode
)
27262 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
27263 regno
= ALTIVEC_ARG_RETURN
;
27264 else if (VSX_VECTOR_MODE (mode
)
27265 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
)
27266 regno
= ALTIVEC_ARG_RETURN
;
27267 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
27268 return rs6000_complex_function_value (mode
);
27269 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
27270 && (mode
== DFmode
|| mode
== DCmode
27271 || mode
== TFmode
|| mode
== TCmode
))
27272 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
27274 regno
= GP_ARG_RETURN
;
27276 return gen_rtx_REG (mode
, regno
);
27280 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27281 Frame pointer elimination is automatically handled.
27283 For the RS/6000, if frame pointer elimination is being done, we would like
27284 to convert ap into fp, not sp.
27286 We need r30 if -mminimal-toc was specified, and there are constant pool
27290 rs6000_can_eliminate (const int from
, const int to
)
27292 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
27293 ? ! frame_pointer_needed
27294 : from
== RS6000_PIC_OFFSET_TABLE_REGNUM
27295 ? ! TARGET_MINIMAL_TOC
|| TARGET_NO_TOC
|| get_pool_size () == 0
27299 /* Define the offset between two registers, FROM to be eliminated and its
27300 replacement TO, at the start of a routine. */
27302 rs6000_initial_elimination_offset (int from
, int to
)
27304 rs6000_stack_t
*info
= rs6000_stack_info ();
27305 HOST_WIDE_INT offset
;
27307 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27308 offset
= info
->push_p
? 0 : -info
->total_size
;
27309 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27311 offset
= info
->push_p
? 0 : -info
->total_size
;
27312 if (FRAME_GROWS_DOWNWARD
)
27313 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
27315 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
27316 offset
= FRAME_GROWS_DOWNWARD
27317 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
27319 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
27320 offset
= info
->total_size
;
27321 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27322 offset
= info
->push_p
? info
->total_size
: 0;
27323 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
27326 gcc_unreachable ();
27332 rs6000_dwarf_register_span (rtx reg
)
27336 unsigned regno
= REGNO (reg
);
27337 enum machine_mode mode
= GET_MODE (reg
);
27341 && (SPE_VECTOR_MODE (GET_MODE (reg
))
27342 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
27343 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
27348 regno
= REGNO (reg
);
27350 /* The duality of the SPE register size wreaks all kinds of havoc.
27351 This is a way of distinguishing r0 in 32-bits from r0 in
27353 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
27354 gcc_assert (words
<= 4);
27355 for (i
= 0; i
< words
; i
++, regno
++)
27357 if (BYTES_BIG_ENDIAN
)
27359 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
27360 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
27364 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
27365 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
27369 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
27372 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27375 rs6000_init_dwarf_reg_sizes_extra (tree address
)
27380 enum machine_mode mode
= TYPE_MODE (char_type_node
);
27381 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
27382 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
27383 rtx value
= gen_int_mode (4, mode
);
27385 for (i
= 1201; i
< 1232; i
++)
27387 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
27388 HOST_WIDE_INT offset
27389 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
27391 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
27396 /* Map internal gcc register numbers to DWARF2 register numbers. */
27399 rs6000_dbx_register_number (unsigned int regno
)
27401 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
27403 if (regno
== MQ_REGNO
)
27405 if (regno
== LR_REGNO
)
27407 if (regno
== CTR_REGNO
)
27409 if (CR_REGNO_P (regno
))
27410 return regno
- CR0_REGNO
+ 86;
27411 if (regno
== CA_REGNO
)
27412 return 101; /* XER */
27413 if (ALTIVEC_REGNO_P (regno
))
27414 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
27415 if (regno
== VRSAVE_REGNO
)
27417 if (regno
== VSCR_REGNO
)
27419 if (regno
== SPE_ACC_REGNO
)
27421 if (regno
== SPEFSCR_REGNO
)
27423 /* SPE high reg number. We get these values of regno from
27424 rs6000_dwarf_register_span. */
27425 gcc_assert (regno
>= 1200 && regno
< 1232);
27429 /* target hook eh_return_filter_mode */
27430 static enum machine_mode
27431 rs6000_eh_return_filter_mode (void)
27433 return TARGET_32BIT
? SImode
: word_mode
;
27436 /* Target hook for scalar_mode_supported_p. */
27438 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
27440 if (DECIMAL_FLOAT_MODE_P (mode
))
27441 return default_decimal_float_supported_p ();
27443 return default_scalar_mode_supported_p (mode
);
27446 /* Target hook for vector_mode_supported_p. */
27448 rs6000_vector_mode_supported_p (enum machine_mode mode
)
27451 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
27454 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
27457 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
27464 /* Target hook for invalid_arg_for_unprototyped_fn. */
27465 static const char *
27466 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
27468 return (!rs6000_darwin64_abi
27470 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
27471 && (funcdecl
== NULL_TREE
27472 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
27473 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
27474 ? N_("AltiVec argument passed to unprototyped function")
27478 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27479 setup by using __stack_chk_fail_local hidden function instead of
27480 calling __stack_chk_fail directly. Otherwise it is better to call
27481 __stack_chk_fail directly. */
27484 rs6000_stack_protect_fail (void)
27486 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
27487 ? default_hidden_stack_protect_fail ()
27488 : default_external_stack_protect_fail ();
27492 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
27493 int num_operands ATTRIBUTE_UNUSED
)
27495 if (rs6000_warn_cell_microcode
)
27498 int insn_code_number
= recog_memoized (insn
);
27499 location_t location
= locator_location (INSN_LOCATOR (insn
));
27501 /* Punt on insns we cannot recognize. */
27502 if (insn_code_number
< 0)
27505 temp
= get_insn_template (insn_code_number
, insn
);
27507 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
27508 warning_at (location
, OPT_mwarn_cell_microcode
,
27509 "emitting microcode insn %s\t[%s] #%d",
27510 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27511 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
27512 warning_at (location
, OPT_mwarn_cell_microcode
,
27513 "emitting conditional microcode insn %s\t[%s] #%d",
27514 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27519 /* Mask options that we want to support inside of attribute((target)) and
27520 #pragma GCC target operations. Note, we do not include things like
27521 64/32-bit, endianess, hard/soft floating point, etc. that would have
27522 different calling sequences. */
27524 struct rs6000_opt_mask
{
27525 const char *name
; /* option name */
27526 int mask
; /* mask to set */
27527 bool invert
; /* invert sense of mask */
27528 bool valid_target
; /* option is a target option */
27531 static struct rs6000_opt_mask
const rs6000_opt_masks
[] =
27533 { "altivec", MASK_ALTIVEC
, false, true },
27534 { "cmpb", MASK_CMPB
, false, true },
27535 { "dlmzb", MASK_DLMZB
, false, true },
27536 { "fprnd", MASK_FPRND
, false, true },
27537 { "hard-dfp", MASK_DFP
, false, true },
27538 { "isel", MASK_ISEL
, false, true },
27539 { "mfcrf", MASK_MFCRF
, false, true },
27540 { "mfpgpr", MASK_MFPGPR
, false, true },
27541 { "mulhw", MASK_MULHW
, false, true },
27542 { "multiple", MASK_MULTIPLE
, false, true },
27543 { "update", MASK_NO_UPDATE
, true , true },
27544 { "popcntb", MASK_POPCNTB
, false, true },
27545 { "popcntd", MASK_POPCNTD
, false, true },
27546 { "powerpc-gfxopt", MASK_PPC_GFXOPT
, false, true },
27547 { "powerpc-gpopt", MASK_PPC_GPOPT
, false, true },
27548 { "recip-precision", MASK_RECIP_PRECISION
, false, true },
27549 { "string", MASK_STRING
, false, true },
27550 { "vsx", MASK_VSX
, false, true },
27553 { "aix64", MASK_64BIT
, false, false },
27554 { "aix32", MASK_64BIT
, true, false },
27556 { "64", MASK_64BIT
, false, false },
27557 { "32", MASK_64BIT
, true, false },
27561 { "eabi", MASK_EABI
, false, false },
27563 #ifdef MASK_LITTLE_ENDIAN
27564 { "little", MASK_LITTLE_ENDIAN
, false, false },
27565 { "big", MASK_LITTLE_ENDIAN
, true, false },
27567 #ifdef MASK_RELOCATABLE
27568 { "relocatable", MASK_RELOCATABLE
, false, false },
27570 #ifdef MASK_STRICT_ALIGN
27571 { "strict-align", MASK_STRICT_ALIGN
, false, false },
27573 { "power", MASK_POWER
, false, false },
27574 { "power2", MASK_POWER2
, false, false },
27575 { "powerpc", MASK_POWERPC
, false, false },
27576 { "soft-float", MASK_SOFT_FLOAT
, false, false },
27577 { "string", MASK_STRING
, false, false },
27580 /* Option variables that we want to support inside attribute((target)) and
27581 #pragma GCC target operations. */
27583 struct rs6000_opt_var
{
27584 const char *name
; /* option name */
27585 size_t global_offset
; /* offset of the option in global_options. */
27586 size_t target_offset
; /* offset of the option in target optiosn. */
27589 static struct rs6000_opt_var
const rs6000_opt_vars
[] =
27592 offsetof (struct gcc_options
, x_TARGET_FRIZ
),
27593 offsetof (struct cl_target_option
, x_TARGET_FRIZ
), },
27594 { "avoid-indexed-addresses",
27595 offsetof (struct gcc_options
, x_TARGET_AVOID_XFORM
),
27596 offsetof (struct cl_target_option
, x_TARGET_AVOID_XFORM
) },
27598 offsetof (struct gcc_options
, x_rs6000_paired_float
),
27599 offsetof (struct cl_target_option
, x_rs6000_paired_float
), },
27601 offsetof (struct gcc_options
, x_rs6000_default_long_calls
),
27602 offsetof (struct cl_target_option
, x_rs6000_default_long_calls
), },
27605 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27606 parsing. Return true if there were no errors. */
27609 rs6000_inner_target_options (tree args
, bool attr_p
)
27613 if (args
== NULL_TREE
)
27616 else if (TREE_CODE (args
) == STRING_CST
)
27618 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27621 while ((q
= strtok (p
, ",")) != NULL
)
27623 bool error_p
= false;
27624 bool not_valid_p
= false;
27625 const char *cpu_opt
= NULL
;
27628 if (strncmp (q
, "cpu=", 4) == 0)
27630 int cpu_index
= rs6000_cpu_name_lookup (q
+4);
27631 if (cpu_index
>= 0)
27632 rs6000_cpu_index
= cpu_index
;
27639 else if (strncmp (q
, "tune=", 5) == 0)
27641 int tune_index
= rs6000_cpu_name_lookup (q
+5);
27642 if (tune_index
>= 0)
27643 rs6000_tune_index
= tune_index
;
27653 bool invert
= false;
27657 if (strncmp (r
, "no-", 3) == 0)
27663 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
27664 if (strcmp (r
, rs6000_opt_masks
[i
].name
) == 0)
27666 int mask
= rs6000_opt_masks
[i
].mask
;
27668 if (!rs6000_opt_masks
[i
].valid_target
)
27669 not_valid_p
= true;
27673 target_flags_explicit
|= mask
;
27675 if (rs6000_opt_masks
[i
].invert
)
27679 target_flags
&= ~mask
;
27681 target_flags
|= mask
;
27686 if (error_p
&& !not_valid_p
)
27688 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
27689 if (strcmp (r
, rs6000_opt_vars
[i
].name
) == 0)
27691 size_t j
= rs6000_opt_vars
[i
].global_offset
;
27692 ((int *) &global_options
)[j
] = !invert
;
27701 const char *eprefix
, *esuffix
;
27706 eprefix
= "__attribute__((__target__(";
27711 eprefix
= "#pragma GCC target ";
27716 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt
, eprefix
,
27718 else if (not_valid_p
)
27719 error ("%s\"%s\"%s is not allowed", eprefix
, q
, esuffix
);
27721 error ("%s\"%s\"%s is invalid", eprefix
, q
, esuffix
);
27726 else if (TREE_CODE (args
) == TREE_LIST
)
27730 tree value
= TREE_VALUE (args
);
27733 bool ret2
= rs6000_inner_target_options (value
, attr_p
);
27737 args
= TREE_CHAIN (args
);
27739 while (args
!= NULL_TREE
);
27743 gcc_unreachable ();
27748 /* Print out the target options as a list for -mdebug=target. */
27751 rs6000_debug_target_options (tree args
, const char *prefix
)
27753 if (args
== NULL_TREE
)
27754 fprintf (stderr
, "%s<NULL>", prefix
);
27756 else if (TREE_CODE (args
) == STRING_CST
)
27758 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27761 while ((q
= strtok (p
, ",")) != NULL
)
27764 fprintf (stderr
, "%s\"%s\"", prefix
, q
);
27769 else if (TREE_CODE (args
) == TREE_LIST
)
27773 tree value
= TREE_VALUE (args
);
27776 rs6000_debug_target_options (value
, prefix
);
27779 args
= TREE_CHAIN (args
);
27781 while (args
!= NULL_TREE
);
27785 gcc_unreachable ();
27791 /* Hook to validate attribute((target("..."))). */
27794 rs6000_valid_attribute_p (tree fndecl
,
27795 tree
ARG_UNUSED (name
),
27799 struct cl_target_option cur_target
;
27801 tree old_optimize
= build_optimization_node ();
27802 tree new_target
, new_optimize
;
27803 tree func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27805 gcc_assert ((fndecl
!= NULL_TREE
) && (args
!= NULL_TREE
));
27807 if (TARGET_DEBUG_TARGET
)
27809 tree tname
= DECL_NAME (fndecl
);
27810 fprintf (stderr
, "\n==================== rs6000_valid_attribute_p:\n");
27812 fprintf (stderr
, "function: %.*s\n",
27813 (int) IDENTIFIER_LENGTH (tname
),
27814 IDENTIFIER_POINTER (tname
));
27816 fprintf (stderr
, "function: unknown\n");
27818 fprintf (stderr
, "args:");
27819 rs6000_debug_target_options (args
, " ");
27820 fprintf (stderr
, "\n");
27823 fprintf (stderr
, "flags: 0x%x\n", flags
);
27825 fprintf (stderr
, "--------------------\n");
27828 old_optimize
= build_optimization_node ();
27829 func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27831 /* If the function changed the optimization levels as well as setting target
27832 options, start with the optimizations specified. */
27833 if (func_optimize
&& func_optimize
!= old_optimize
)
27834 cl_optimization_restore (&global_options
,
27835 TREE_OPTIMIZATION (func_optimize
));
27837 /* The target attributes may also change some optimization flags, so update
27838 the optimization options if necessary. */
27839 cl_target_option_save (&cur_target
, &global_options
);
27840 rs6000_cpu_index
= rs6000_tune_index
= -1;
27841 ret
= rs6000_inner_target_options (args
, true);
27843 /* Set up any additional state. */
27846 ret
= rs6000_option_override_internal (false);
27847 new_target
= build_target_option_node ();
27852 new_optimize
= build_optimization_node ();
27859 DECL_FUNCTION_SPECIFIC_TARGET (fndecl
) = new_target
;
27861 if (old_optimize
!= new_optimize
)
27862 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
) = new_optimize
;
27865 cl_target_option_restore (&global_options
, &cur_target
);
27867 if (old_optimize
!= new_optimize
)
27868 cl_optimization_restore (&global_options
,
27869 TREE_OPTIMIZATION (old_optimize
));
27875 /* Hook to validate the current #pragma GCC target and set the state, and
27876 update the macros based on what was changed. If ARGS is NULL, then
27877 POP_TARGET is used to reset the options. */
27880 rs6000_pragma_target_parse (tree args
, tree pop_target
)
27885 if (TARGET_DEBUG_TARGET
)
27887 fprintf (stderr
, "\n==================== rs6000_pragma_target_parse\n");
27888 fprintf (stderr
, "args:");
27889 rs6000_debug_target_options (args
, " ");
27890 fprintf (stderr
, "\n");
27894 fprintf (stderr
, "pop_target:\n");
27895 debug_tree (pop_target
);
27898 fprintf (stderr
, "pop_target: <NULL>\n");
27900 fprintf (stderr
, "--------------------\n");
27906 cur_tree
= ((pop_target
)
27908 : target_option_default_node
);
27909 cl_target_option_restore (&global_options
,
27910 TREE_TARGET_OPTION (cur_tree
));
27914 rs6000_cpu_index
= rs6000_tune_index
= -1;
27915 ret
= rs6000_inner_target_options (args
, false);
27916 cur_tree
= build_target_option_node ();
27923 target_option_current_node
= cur_tree
;
27929 /* Remember the last target of rs6000_set_current_function. */
27930 static GTY(()) tree rs6000_previous_fndecl
;
27932 /* Establish appropriate back-end context for processing the function
27933 FNDECL. The argument might be NULL to indicate processing at top
27934 level, outside of any function scope. */
27936 rs6000_set_current_function (tree fndecl
)
27938 tree old_tree
= (rs6000_previous_fndecl
27939 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl
)
27942 tree new_tree
= (fndecl
27943 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl
)
27946 if (TARGET_DEBUG_TARGET
)
27948 bool print_final
= false;
27949 fprintf (stderr
, "\n==================== rs6000_set_current_function");
27952 fprintf (stderr
, ", fndecl %s (%p)",
27953 (DECL_NAME (fndecl
)
27954 ? IDENTIFIER_POINTER (DECL_NAME (fndecl
))
27955 : "<unknown>"), (void *)fndecl
);
27957 if (rs6000_previous_fndecl
)
27958 fprintf (stderr
, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl
);
27960 fprintf (stderr
, "\n");
27963 fprintf (stderr
, "\nnew fndecl target specific options:\n");
27964 debug_tree (new_tree
);
27965 print_final
= true;
27970 fprintf (stderr
, "\nold fndecl target specific options:\n");
27971 debug_tree (old_tree
);
27972 print_final
= true;
27976 fprintf (stderr
, "--------------------\n");
27979 /* Only change the context if the function changes. This hook is called
27980 several times in the course of compiling a function, and we don't want to
27981 slow things down too much or call target_reinit when it isn't safe. */
27982 if (fndecl
&& fndecl
!= rs6000_previous_fndecl
)
27984 rs6000_previous_fndecl
= fndecl
;
27985 if (old_tree
== new_tree
)
27990 cl_target_option_restore (&global_options
,
27991 TREE_TARGET_OPTION (new_tree
));
27997 struct cl_target_option
*def
27998 = TREE_TARGET_OPTION (target_option_current_node
);
28000 cl_target_option_restore (&global_options
, def
);
28007 /* Save the current options */
28010 rs6000_function_specific_save (struct cl_target_option
*ptr
)
28012 ptr
->rs6000_target_flags_explicit
= target_flags_explicit
;
28015 /* Restore the current options */
28018 rs6000_function_specific_restore (struct cl_target_option
*ptr
)
28020 target_flags_explicit
= ptr
->rs6000_target_flags_explicit
;
28021 (void) rs6000_option_override_internal (false);
28024 /* Print the current options */
28027 rs6000_function_specific_print (FILE *file
, int indent
,
28028 struct cl_target_option
*ptr
)
28031 int flags
= ptr
->x_target_flags
;
28033 /* Print the various mask options. */
28034 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
28035 if ((flags
& rs6000_opt_masks
[i
].mask
) != 0)
28037 flags
&= ~ rs6000_opt_masks
[i
].mask
;
28038 fprintf (file
, "%*s-m%s%s\n", indent
, "",
28039 rs6000_opt_masks
[i
].invert
? "no-" : "",
28040 rs6000_opt_masks
[i
].name
);
28043 /* Print the various options that are variables. */
28044 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
28046 size_t j
= rs6000_opt_vars
[i
].target_offset
;
28047 if (((signed char *) ptr
)[j
])
28048 fprintf (file
, "%*s-m%s\n", indent
, "",
28049 rs6000_opt_vars
[i
].name
);
28054 /* Hook to determine if one function can safely inline another. */
28057 rs6000_can_inline_p (tree caller
, tree callee
)
28060 tree caller_tree
= DECL_FUNCTION_SPECIFIC_TARGET (caller
);
28061 tree callee_tree
= DECL_FUNCTION_SPECIFIC_TARGET (callee
);
28063 /* If callee has no option attributes, then it is ok to inline. */
28067 /* If caller has no option attributes, but callee does then it is not ok to
28069 else if (!caller_tree
)
28074 struct cl_target_option
*caller_opts
= TREE_TARGET_OPTION (caller_tree
);
28075 struct cl_target_option
*callee_opts
= TREE_TARGET_OPTION (callee_tree
);
28077 /* Callee's options should a subset of the caller's, i.e. a vsx function
28078 can inline an altivec function but a non-vsx function can't inline a
28080 if ((caller_opts
->x_target_flags
& callee_opts
->x_target_flags
)
28081 == callee_opts
->x_target_flags
)
28085 if (TARGET_DEBUG_TARGET
)
28086 fprintf (stderr
, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28087 (DECL_NAME (caller
)
28088 ? IDENTIFIER_POINTER (DECL_NAME (caller
))
28090 (DECL_NAME (callee
)
28091 ? IDENTIFIER_POINTER (DECL_NAME (callee
))
28093 (ret
? "can" : "cannot"));
28098 /* Allocate a stack temp and fixup the address so it meets the particular
28099 memory requirements (either offetable or REG+REG addressing). */
28102 rs6000_allocate_stack_temp (enum machine_mode mode
,
28103 bool offsettable_p
,
28106 rtx stack
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
28107 rtx addr
= XEXP (stack
, 0);
28108 int strict_p
= (reload_in_progress
|| reload_completed
);
28110 if (!legitimate_indirect_address_p (addr
, strict_p
))
28113 && !rs6000_legitimate_offset_address_p (mode
, addr
, strict_p
))
28114 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
28116 else if (reg_reg_p
&& !legitimate_indexed_address_p (addr
, strict_p
))
28117 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
28123 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28124 to such a form to deal with memory reference instructions like STFIWX that
28125 only take reg+reg addressing. */
28128 rs6000_address_for_fpconvert (rtx x
)
28130 int strict_p
= (reload_in_progress
|| reload_completed
);
28133 gcc_assert (MEM_P (x
));
28134 addr
= XEXP (x
, 0);
28135 if (! legitimate_indirect_address_p (addr
, strict_p
)
28136 && ! legitimate_indexed_address_p (addr
, strict_p
))
28138 if (GET_CODE (addr
) == PRE_INC
|| GET_CODE (addr
) == PRE_DEC
)
28140 rtx reg
= XEXP (addr
, 0);
28141 HOST_WIDE_INT size
= GET_MODE_SIZE (GET_MODE (x
));
28142 rtx size_rtx
= GEN_INT ((GET_CODE (addr
) == PRE_DEC
) ? -size
: size
);
28143 gcc_assert (REG_P (reg
));
28144 emit_insn (gen_add3_insn (reg
, reg
, size_rtx
));
28147 else if (GET_CODE (addr
) == PRE_MODIFY
)
28149 rtx reg
= XEXP (addr
, 0);
28150 rtx expr
= XEXP (addr
, 1);
28151 gcc_assert (REG_P (reg
));
28152 gcc_assert (GET_CODE (expr
) == PLUS
);
28153 emit_insn (gen_add3_insn (reg
, XEXP (expr
, 0), XEXP (expr
, 1)));
28157 x
= replace_equiv_address (x
, copy_addr_to_reg (addr
));
28163 /* Given a memory reference, if it is not in the form for altivec memory
28164 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28165 convert to the altivec format. */
28168 rs6000_address_for_altivec (rtx x
)
28170 gcc_assert (MEM_P (x
));
28171 if (!altivec_indexed_or_indirect_operand (x
, GET_MODE (x
)))
28173 rtx addr
= XEXP (x
, 0);
28174 int strict_p
= (reload_in_progress
|| reload_completed
);
28176 if (!legitimate_indexed_address_p (addr
, strict_p
)
28177 && !legitimate_indirect_address_p (addr
, strict_p
))
28178 addr
= copy_to_mode_reg (Pmode
, addr
);
28180 addr
= gen_rtx_AND (Pmode
, addr
, GEN_INT (-16));
28181 x
= change_address (x
, GET_MODE (x
), addr
);
28187 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
28189 On the RS/6000, all integer constants are acceptable, most won't be valid
28190 for particular insns, though. Only easy FP constants are acceptable. */
28193 rs6000_legitimate_constant_p (enum machine_mode mode
, rtx x
)
28195 if (rs6000_tls_referenced_p (x
))
28198 return ((GET_CODE (x
) != CONST_DOUBLE
&& GET_CODE (x
) != CONST_VECTOR
)
28199 || GET_MODE (x
) == VOIDmode
28200 || (TARGET_POWERPC64
&& mode
== DImode
)
28201 || easy_fp_constant (x
, mode
)
28202 || easy_vector_constant (x
, mode
));
28205 #include "gt-rs6000.h"