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 /* String variables to hold the various options. */
152 static const char *rs6000_sched_insert_nops_str
;
153 static const char *rs6000_sched_costly_dep_str
;
154 static const char *rs6000_recip_name
;
157 static const char *rs6000_abi_name
;
158 static const char *rs6000_sdata_name
;
161 /* Support targetm.vectorize.builtin_mask_for_load. */
162 static GTY(()) tree altivec_builtin_mask_for_load
;
164 /* Set to nonzero once AIX common-mode calls have been defined. */
165 static GTY(()) int common_mode_defined
;
167 /* Label number of label created for -mrelocatable, to call to so we can
168 get the address of the GOT section */
169 static int rs6000_pic_labelno
;
172 /* Counter for labels which are to be placed in .fixup. */
173 int fixuplabelno
= 0;
176 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
179 /* Specify the machine mode that pointers have. After generation of rtl, the
180 compiler makes no further distinction between pointers and any other objects
181 of this machine mode. The type is unsigned since not all things that
182 include rs6000.h also include machmode.h. */
183 unsigned rs6000_pmode
;
185 /* Width in bits of a pointer. */
186 unsigned rs6000_pointer_size
;
188 #ifdef HAVE_AS_GNU_ATTRIBUTE
189 /* Flag whether floating point values have been passed/returned. */
190 static bool rs6000_passes_float
;
191 /* Flag whether vector values have been passed/returned. */
192 static bool rs6000_passes_vector
;
193 /* Flag whether small (<= 8 byte) structures have been returned. */
194 static bool rs6000_returns_struct
;
197 /* Value is TRUE if register/mode pair is acceptable. */
198 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
200 /* Maximum number of registers needed for a given register class and mode. */
201 unsigned char rs6000_class_max_nregs
[NUM_MACHINE_MODES
][LIM_REG_CLASSES
];
203 /* How many registers are needed for a given register and mode. */
204 unsigned char rs6000_hard_regno_nregs
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
206 /* Map register number to register class. */
207 enum reg_class rs6000_regno_regclass
[FIRST_PSEUDO_REGISTER
];
209 /* Reload functions based on the type and the vector unit. */
210 static enum insn_code rs6000_vector_reload
[NUM_MACHINE_MODES
][2];
212 /* Built in types. */
213 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
214 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
216 /* Flag to say the TOC is initialized */
218 char toc_label_name
[10];
220 /* Cached value of rs6000_variable_issue. This is cached in
221 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
222 static short cached_can_issue_more
;
224 static GTY(()) section
*read_only_data_section
;
225 static GTY(()) section
*private_data_section
;
226 static GTY(()) section
*read_only_private_data_section
;
227 static GTY(()) section
*sdata2_section
;
228 static GTY(()) section
*toc_section
;
230 /* True for any options that were explicitly set. */
232 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
233 bool alignment
; /* True if -malign- was used. */
234 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
235 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
236 bool spe
; /* True if -mspe= was used. */
237 bool float_gprs
; /* True if -mfloat-gprs= was used. */
238 bool long_double
; /* True if -mlong-double- was used. */
239 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
240 bool vrsave
; /* True if -mvrsave was used. */
241 bool cmodel
; /* True if -mcmodel was used. */
242 } rs6000_explicit_options
;
244 struct builtin_description
246 /* mask is not const because we're going to alter it below. This
247 nonsense will go away when we rewrite the -march infrastructure
248 to give us more target flag bits. */
250 const enum insn_code icode
;
251 const char *const name
;
252 const enum rs6000_builtins code
;
255 /* Describe the vector unit used for modes. */
256 enum rs6000_vector rs6000_vector_unit
[NUM_MACHINE_MODES
];
257 enum rs6000_vector rs6000_vector_mem
[NUM_MACHINE_MODES
];
259 /* Register classes for various constraints that are based on the target
261 enum reg_class rs6000_constraints
[RS6000_CONSTRAINT_MAX
];
263 /* Describe the alignment of a vector. */
264 int rs6000_vector_align
[NUM_MACHINE_MODES
];
266 /* Map selected modes to types for builtins. */
267 static GTY(()) tree builtin_mode_to_type
[MAX_MACHINE_MODE
][2];
269 /* What modes to automatically generate reciprocal divide estimate (fre) and
270 reciprocal sqrt (frsqrte) for. */
271 unsigned char rs6000_recip_bits
[MAX_MACHINE_MODE
];
273 /* Masks to determine which reciprocal esitmate instructions to generate
275 enum rs6000_recip_mask
{
276 RECIP_SF_DIV
= 0x001, /* Use divide estimate */
277 RECIP_DF_DIV
= 0x002,
278 RECIP_V4SF_DIV
= 0x004,
279 RECIP_V2DF_DIV
= 0x008,
281 RECIP_SF_RSQRT
= 0x010, /* Use reciprocal sqrt estimate. */
282 RECIP_DF_RSQRT
= 0x020,
283 RECIP_V4SF_RSQRT
= 0x040,
284 RECIP_V2DF_RSQRT
= 0x080,
286 /* Various combination of flags for -mrecip=xxx. */
288 RECIP_ALL
= (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
289 | RECIP_V2DF_DIV
| RECIP_SF_RSQRT
| RECIP_DF_RSQRT
290 | RECIP_V4SF_RSQRT
| RECIP_V2DF_RSQRT
),
292 RECIP_HIGH_PRECISION
= RECIP_ALL
,
294 /* On low precision machines like the power5, don't enable double precision
295 reciprocal square root estimate, since it isn't accurate enough. */
296 RECIP_LOW_PRECISION
= (RECIP_ALL
& ~(RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
))
299 /* -mrecip options. */
302 const char *string
; /* option name */
303 unsigned int mask
; /* mask bits to set */
304 } recip_options
[] = {
305 { "all", RECIP_ALL
},
306 { "none", RECIP_NONE
},
307 { "div", (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
309 { "divf", (RECIP_SF_DIV
| RECIP_V4SF_DIV
) },
310 { "divd", (RECIP_DF_DIV
| RECIP_V2DF_DIV
) },
311 { "rsqrt", (RECIP_SF_RSQRT
| RECIP_DF_RSQRT
| RECIP_V4SF_RSQRT
312 | RECIP_V2DF_RSQRT
) },
313 { "rsqrtf", (RECIP_SF_RSQRT
| RECIP_V4SF_RSQRT
) },
314 { "rsqrtd", (RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
) },
317 /* 2 argument gen function typedef. */
318 typedef rtx (*gen_2arg_fn_t
) (rtx
, rtx
, rtx
);
321 /* Target cpu costs. */
323 struct processor_costs
{
324 const int mulsi
; /* cost of SImode multiplication. */
325 const int mulsi_const
; /* cost of SImode multiplication by constant. */
326 const int mulsi_const9
; /* cost of SImode mult by short constant. */
327 const int muldi
; /* cost of DImode multiplication. */
328 const int divsi
; /* cost of SImode division. */
329 const int divdi
; /* cost of DImode division. */
330 const int fp
; /* cost of simple SFmode and DFmode insns. */
331 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
332 const int sdiv
; /* cost of SFmode division (fdivs). */
333 const int ddiv
; /* cost of DFmode division (fdiv). */
334 const int cache_line_size
; /* cache line size in bytes. */
335 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
336 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
337 const int simultaneous_prefetches
; /* number of parallel prefetch
341 const struct processor_costs
*rs6000_cost
;
343 /* Processor costs (relative to an add) */
345 /* Instruction size costs on 32bit processors. */
347 struct processor_costs size32_cost
= {
348 COSTS_N_INSNS (1), /* mulsi */
349 COSTS_N_INSNS (1), /* mulsi_const */
350 COSTS_N_INSNS (1), /* mulsi_const9 */
351 COSTS_N_INSNS (1), /* muldi */
352 COSTS_N_INSNS (1), /* divsi */
353 COSTS_N_INSNS (1), /* divdi */
354 COSTS_N_INSNS (1), /* fp */
355 COSTS_N_INSNS (1), /* dmul */
356 COSTS_N_INSNS (1), /* sdiv */
357 COSTS_N_INSNS (1), /* ddiv */
364 /* Instruction size costs on 64bit processors. */
366 struct processor_costs size64_cost
= {
367 COSTS_N_INSNS (1), /* mulsi */
368 COSTS_N_INSNS (1), /* mulsi_const */
369 COSTS_N_INSNS (1), /* mulsi_const9 */
370 COSTS_N_INSNS (1), /* muldi */
371 COSTS_N_INSNS (1), /* divsi */
372 COSTS_N_INSNS (1), /* divdi */
373 COSTS_N_INSNS (1), /* fp */
374 COSTS_N_INSNS (1), /* dmul */
375 COSTS_N_INSNS (1), /* sdiv */
376 COSTS_N_INSNS (1), /* ddiv */
383 /* Instruction costs on RIOS1 processors. */
385 struct processor_costs rios1_cost
= {
386 COSTS_N_INSNS (5), /* mulsi */
387 COSTS_N_INSNS (4), /* mulsi_const */
388 COSTS_N_INSNS (3), /* mulsi_const9 */
389 COSTS_N_INSNS (5), /* muldi */
390 COSTS_N_INSNS (19), /* divsi */
391 COSTS_N_INSNS (19), /* divdi */
392 COSTS_N_INSNS (2), /* fp */
393 COSTS_N_INSNS (2), /* dmul */
394 COSTS_N_INSNS (19), /* sdiv */
395 COSTS_N_INSNS (19), /* ddiv */
396 128, /* cache line size */
402 /* Instruction costs on RIOS2 processors. */
404 struct processor_costs rios2_cost
= {
405 COSTS_N_INSNS (2), /* mulsi */
406 COSTS_N_INSNS (2), /* mulsi_const */
407 COSTS_N_INSNS (2), /* mulsi_const9 */
408 COSTS_N_INSNS (2), /* muldi */
409 COSTS_N_INSNS (13), /* divsi */
410 COSTS_N_INSNS (13), /* divdi */
411 COSTS_N_INSNS (2), /* fp */
412 COSTS_N_INSNS (2), /* dmul */
413 COSTS_N_INSNS (17), /* sdiv */
414 COSTS_N_INSNS (17), /* ddiv */
415 256, /* cache line size */
421 /* Instruction costs on RS64A processors. */
423 struct processor_costs rs64a_cost
= {
424 COSTS_N_INSNS (20), /* mulsi */
425 COSTS_N_INSNS (12), /* mulsi_const */
426 COSTS_N_INSNS (8), /* mulsi_const9 */
427 COSTS_N_INSNS (34), /* muldi */
428 COSTS_N_INSNS (65), /* divsi */
429 COSTS_N_INSNS (67), /* divdi */
430 COSTS_N_INSNS (4), /* fp */
431 COSTS_N_INSNS (4), /* dmul */
432 COSTS_N_INSNS (31), /* sdiv */
433 COSTS_N_INSNS (31), /* ddiv */
434 128, /* cache line size */
440 /* Instruction costs on MPCCORE processors. */
442 struct processor_costs mpccore_cost
= {
443 COSTS_N_INSNS (2), /* mulsi */
444 COSTS_N_INSNS (2), /* mulsi_const */
445 COSTS_N_INSNS (2), /* mulsi_const9 */
446 COSTS_N_INSNS (2), /* muldi */
447 COSTS_N_INSNS (6), /* divsi */
448 COSTS_N_INSNS (6), /* divdi */
449 COSTS_N_INSNS (4), /* fp */
450 COSTS_N_INSNS (5), /* dmul */
451 COSTS_N_INSNS (10), /* sdiv */
452 COSTS_N_INSNS (17), /* ddiv */
453 32, /* cache line size */
459 /* Instruction costs on PPC403 processors. */
461 struct processor_costs ppc403_cost
= {
462 COSTS_N_INSNS (4), /* mulsi */
463 COSTS_N_INSNS (4), /* mulsi_const */
464 COSTS_N_INSNS (4), /* mulsi_const9 */
465 COSTS_N_INSNS (4), /* muldi */
466 COSTS_N_INSNS (33), /* divsi */
467 COSTS_N_INSNS (33), /* divdi */
468 COSTS_N_INSNS (11), /* fp */
469 COSTS_N_INSNS (11), /* dmul */
470 COSTS_N_INSNS (11), /* sdiv */
471 COSTS_N_INSNS (11), /* ddiv */
472 32, /* cache line size */
478 /* Instruction costs on PPC405 processors. */
480 struct processor_costs ppc405_cost
= {
481 COSTS_N_INSNS (5), /* mulsi */
482 COSTS_N_INSNS (4), /* mulsi_const */
483 COSTS_N_INSNS (3), /* mulsi_const9 */
484 COSTS_N_INSNS (5), /* muldi */
485 COSTS_N_INSNS (35), /* divsi */
486 COSTS_N_INSNS (35), /* divdi */
487 COSTS_N_INSNS (11), /* fp */
488 COSTS_N_INSNS (11), /* dmul */
489 COSTS_N_INSNS (11), /* sdiv */
490 COSTS_N_INSNS (11), /* ddiv */
491 32, /* cache line size */
497 /* Instruction costs on PPC440 processors. */
499 struct processor_costs ppc440_cost
= {
500 COSTS_N_INSNS (3), /* mulsi */
501 COSTS_N_INSNS (2), /* mulsi_const */
502 COSTS_N_INSNS (2), /* mulsi_const9 */
503 COSTS_N_INSNS (3), /* muldi */
504 COSTS_N_INSNS (34), /* divsi */
505 COSTS_N_INSNS (34), /* divdi */
506 COSTS_N_INSNS (5), /* fp */
507 COSTS_N_INSNS (5), /* dmul */
508 COSTS_N_INSNS (19), /* sdiv */
509 COSTS_N_INSNS (33), /* ddiv */
510 32, /* cache line size */
516 /* Instruction costs on PPC476 processors. */
518 struct processor_costs ppc476_cost
= {
519 COSTS_N_INSNS (4), /* mulsi */
520 COSTS_N_INSNS (4), /* mulsi_const */
521 COSTS_N_INSNS (4), /* mulsi_const9 */
522 COSTS_N_INSNS (4), /* muldi */
523 COSTS_N_INSNS (11), /* divsi */
524 COSTS_N_INSNS (11), /* divdi */
525 COSTS_N_INSNS (6), /* fp */
526 COSTS_N_INSNS (6), /* dmul */
527 COSTS_N_INSNS (19), /* sdiv */
528 COSTS_N_INSNS (33), /* ddiv */
529 32, /* l1 cache line size */
535 /* Instruction costs on PPC601 processors. */
537 struct processor_costs ppc601_cost
= {
538 COSTS_N_INSNS (5), /* mulsi */
539 COSTS_N_INSNS (5), /* mulsi_const */
540 COSTS_N_INSNS (5), /* mulsi_const9 */
541 COSTS_N_INSNS (5), /* muldi */
542 COSTS_N_INSNS (36), /* divsi */
543 COSTS_N_INSNS (36), /* divdi */
544 COSTS_N_INSNS (4), /* fp */
545 COSTS_N_INSNS (5), /* dmul */
546 COSTS_N_INSNS (17), /* sdiv */
547 COSTS_N_INSNS (31), /* ddiv */
548 32, /* cache line size */
554 /* Instruction costs on PPC603 processors. */
556 struct processor_costs ppc603_cost
= {
557 COSTS_N_INSNS (5), /* mulsi */
558 COSTS_N_INSNS (3), /* mulsi_const */
559 COSTS_N_INSNS (2), /* mulsi_const9 */
560 COSTS_N_INSNS (5), /* muldi */
561 COSTS_N_INSNS (37), /* divsi */
562 COSTS_N_INSNS (37), /* divdi */
563 COSTS_N_INSNS (3), /* fp */
564 COSTS_N_INSNS (4), /* dmul */
565 COSTS_N_INSNS (18), /* sdiv */
566 COSTS_N_INSNS (33), /* ddiv */
567 32, /* cache line size */
573 /* Instruction costs on PPC604 processors. */
575 struct processor_costs ppc604_cost
= {
576 COSTS_N_INSNS (4), /* mulsi */
577 COSTS_N_INSNS (4), /* mulsi_const */
578 COSTS_N_INSNS (4), /* mulsi_const9 */
579 COSTS_N_INSNS (4), /* muldi */
580 COSTS_N_INSNS (20), /* divsi */
581 COSTS_N_INSNS (20), /* divdi */
582 COSTS_N_INSNS (3), /* fp */
583 COSTS_N_INSNS (3), /* dmul */
584 COSTS_N_INSNS (18), /* sdiv */
585 COSTS_N_INSNS (32), /* ddiv */
586 32, /* cache line size */
592 /* Instruction costs on PPC604e processors. */
594 struct processor_costs ppc604e_cost
= {
595 COSTS_N_INSNS (2), /* mulsi */
596 COSTS_N_INSNS (2), /* mulsi_const */
597 COSTS_N_INSNS (2), /* mulsi_const9 */
598 COSTS_N_INSNS (2), /* muldi */
599 COSTS_N_INSNS (20), /* divsi */
600 COSTS_N_INSNS (20), /* divdi */
601 COSTS_N_INSNS (3), /* fp */
602 COSTS_N_INSNS (3), /* dmul */
603 COSTS_N_INSNS (18), /* sdiv */
604 COSTS_N_INSNS (32), /* ddiv */
605 32, /* cache line size */
611 /* Instruction costs on PPC620 processors. */
613 struct processor_costs ppc620_cost
= {
614 COSTS_N_INSNS (5), /* mulsi */
615 COSTS_N_INSNS (4), /* mulsi_const */
616 COSTS_N_INSNS (3), /* mulsi_const9 */
617 COSTS_N_INSNS (7), /* muldi */
618 COSTS_N_INSNS (21), /* divsi */
619 COSTS_N_INSNS (37), /* divdi */
620 COSTS_N_INSNS (3), /* fp */
621 COSTS_N_INSNS (3), /* dmul */
622 COSTS_N_INSNS (18), /* sdiv */
623 COSTS_N_INSNS (32), /* ddiv */
624 128, /* cache line size */
630 /* Instruction costs on PPC630 processors. */
632 struct processor_costs ppc630_cost
= {
633 COSTS_N_INSNS (5), /* mulsi */
634 COSTS_N_INSNS (4), /* mulsi_const */
635 COSTS_N_INSNS (3), /* mulsi_const9 */
636 COSTS_N_INSNS (7), /* muldi */
637 COSTS_N_INSNS (21), /* divsi */
638 COSTS_N_INSNS (37), /* divdi */
639 COSTS_N_INSNS (3), /* fp */
640 COSTS_N_INSNS (3), /* dmul */
641 COSTS_N_INSNS (17), /* sdiv */
642 COSTS_N_INSNS (21), /* ddiv */
643 128, /* cache line size */
649 /* Instruction costs on Cell processor. */
650 /* COSTS_N_INSNS (1) ~ one add. */
652 struct processor_costs ppccell_cost
= {
653 COSTS_N_INSNS (9/2)+2, /* mulsi */
654 COSTS_N_INSNS (6/2), /* mulsi_const */
655 COSTS_N_INSNS (6/2), /* mulsi_const9 */
656 COSTS_N_INSNS (15/2)+2, /* muldi */
657 COSTS_N_INSNS (38/2), /* divsi */
658 COSTS_N_INSNS (70/2), /* divdi */
659 COSTS_N_INSNS (10/2), /* fp */
660 COSTS_N_INSNS (10/2), /* dmul */
661 COSTS_N_INSNS (74/2), /* sdiv */
662 COSTS_N_INSNS (74/2), /* ddiv */
663 128, /* cache line size */
669 /* Instruction costs on PPC750 and PPC7400 processors. */
671 struct processor_costs ppc750_cost
= {
672 COSTS_N_INSNS (5), /* mulsi */
673 COSTS_N_INSNS (3), /* mulsi_const */
674 COSTS_N_INSNS (2), /* mulsi_const9 */
675 COSTS_N_INSNS (5), /* muldi */
676 COSTS_N_INSNS (17), /* divsi */
677 COSTS_N_INSNS (17), /* divdi */
678 COSTS_N_INSNS (3), /* fp */
679 COSTS_N_INSNS (3), /* dmul */
680 COSTS_N_INSNS (17), /* sdiv */
681 COSTS_N_INSNS (31), /* ddiv */
682 32, /* cache line size */
688 /* Instruction costs on PPC7450 processors. */
690 struct processor_costs ppc7450_cost
= {
691 COSTS_N_INSNS (4), /* mulsi */
692 COSTS_N_INSNS (3), /* mulsi_const */
693 COSTS_N_INSNS (3), /* mulsi_const9 */
694 COSTS_N_INSNS (4), /* muldi */
695 COSTS_N_INSNS (23), /* divsi */
696 COSTS_N_INSNS (23), /* divdi */
697 COSTS_N_INSNS (5), /* fp */
698 COSTS_N_INSNS (5), /* dmul */
699 COSTS_N_INSNS (21), /* sdiv */
700 COSTS_N_INSNS (35), /* ddiv */
701 32, /* cache line size */
707 /* Instruction costs on PPC8540 processors. */
709 struct processor_costs ppc8540_cost
= {
710 COSTS_N_INSNS (4), /* mulsi */
711 COSTS_N_INSNS (4), /* mulsi_const */
712 COSTS_N_INSNS (4), /* mulsi_const9 */
713 COSTS_N_INSNS (4), /* muldi */
714 COSTS_N_INSNS (19), /* divsi */
715 COSTS_N_INSNS (19), /* divdi */
716 COSTS_N_INSNS (4), /* fp */
717 COSTS_N_INSNS (4), /* dmul */
718 COSTS_N_INSNS (29), /* sdiv */
719 COSTS_N_INSNS (29), /* ddiv */
720 32, /* cache line size */
723 1, /* prefetch streams /*/
726 /* Instruction costs on E300C2 and E300C3 cores. */
728 struct processor_costs ppce300c2c3_cost
= {
729 COSTS_N_INSNS (4), /* mulsi */
730 COSTS_N_INSNS (4), /* mulsi_const */
731 COSTS_N_INSNS (4), /* mulsi_const9 */
732 COSTS_N_INSNS (4), /* muldi */
733 COSTS_N_INSNS (19), /* divsi */
734 COSTS_N_INSNS (19), /* divdi */
735 COSTS_N_INSNS (3), /* fp */
736 COSTS_N_INSNS (4), /* dmul */
737 COSTS_N_INSNS (18), /* sdiv */
738 COSTS_N_INSNS (33), /* ddiv */
742 1, /* prefetch streams /*/
745 /* Instruction costs on PPCE500MC processors. */
747 struct processor_costs ppce500mc_cost
= {
748 COSTS_N_INSNS (4), /* mulsi */
749 COSTS_N_INSNS (4), /* mulsi_const */
750 COSTS_N_INSNS (4), /* mulsi_const9 */
751 COSTS_N_INSNS (4), /* muldi */
752 COSTS_N_INSNS (14), /* divsi */
753 COSTS_N_INSNS (14), /* divdi */
754 COSTS_N_INSNS (8), /* fp */
755 COSTS_N_INSNS (10), /* dmul */
756 COSTS_N_INSNS (36), /* sdiv */
757 COSTS_N_INSNS (66), /* ddiv */
758 64, /* cache line size */
761 1, /* prefetch streams /*/
764 /* Instruction costs on PPCE500MC64 processors. */
766 struct processor_costs ppce500mc64_cost
= {
767 COSTS_N_INSNS (4), /* mulsi */
768 COSTS_N_INSNS (4), /* mulsi_const */
769 COSTS_N_INSNS (4), /* mulsi_const9 */
770 COSTS_N_INSNS (4), /* muldi */
771 COSTS_N_INSNS (14), /* divsi */
772 COSTS_N_INSNS (14), /* divdi */
773 COSTS_N_INSNS (4), /* fp */
774 COSTS_N_INSNS (10), /* dmul */
775 COSTS_N_INSNS (36), /* sdiv */
776 COSTS_N_INSNS (66), /* ddiv */
777 64, /* cache line size */
780 1, /* prefetch streams /*/
783 /* Instruction costs on AppliedMicro Titan processors. */
785 struct processor_costs titan_cost
= {
786 COSTS_N_INSNS (5), /* mulsi */
787 COSTS_N_INSNS (5), /* mulsi_const */
788 COSTS_N_INSNS (5), /* mulsi_const9 */
789 COSTS_N_INSNS (5), /* muldi */
790 COSTS_N_INSNS (18), /* divsi */
791 COSTS_N_INSNS (18), /* divdi */
792 COSTS_N_INSNS (10), /* fp */
793 COSTS_N_INSNS (10), /* dmul */
794 COSTS_N_INSNS (46), /* sdiv */
795 COSTS_N_INSNS (72), /* ddiv */
796 32, /* cache line size */
799 1, /* prefetch streams /*/
802 /* Instruction costs on POWER4 and POWER5 processors. */
804 struct processor_costs power4_cost
= {
805 COSTS_N_INSNS (3), /* mulsi */
806 COSTS_N_INSNS (2), /* mulsi_const */
807 COSTS_N_INSNS (2), /* mulsi_const9 */
808 COSTS_N_INSNS (4), /* muldi */
809 COSTS_N_INSNS (18), /* divsi */
810 COSTS_N_INSNS (34), /* divdi */
811 COSTS_N_INSNS (3), /* fp */
812 COSTS_N_INSNS (3), /* dmul */
813 COSTS_N_INSNS (17), /* sdiv */
814 COSTS_N_INSNS (17), /* ddiv */
815 128, /* cache line size */
818 8, /* prefetch streams /*/
821 /* Instruction costs on POWER6 processors. */
823 struct processor_costs power6_cost
= {
824 COSTS_N_INSNS (8), /* mulsi */
825 COSTS_N_INSNS (8), /* mulsi_const */
826 COSTS_N_INSNS (8), /* mulsi_const9 */
827 COSTS_N_INSNS (8), /* muldi */
828 COSTS_N_INSNS (22), /* divsi */
829 COSTS_N_INSNS (28), /* divdi */
830 COSTS_N_INSNS (3), /* fp */
831 COSTS_N_INSNS (3), /* dmul */
832 COSTS_N_INSNS (13), /* sdiv */
833 COSTS_N_INSNS (16), /* ddiv */
834 128, /* cache line size */
837 16, /* prefetch streams */
840 /* Instruction costs on POWER7 processors. */
842 struct processor_costs power7_cost
= {
843 COSTS_N_INSNS (2), /* mulsi */
844 COSTS_N_INSNS (2), /* mulsi_const */
845 COSTS_N_INSNS (2), /* mulsi_const9 */
846 COSTS_N_INSNS (2), /* muldi */
847 COSTS_N_INSNS (18), /* divsi */
848 COSTS_N_INSNS (34), /* divdi */
849 COSTS_N_INSNS (3), /* fp */
850 COSTS_N_INSNS (3), /* dmul */
851 COSTS_N_INSNS (13), /* sdiv */
852 COSTS_N_INSNS (16), /* ddiv */
853 128, /* cache line size */
856 12, /* prefetch streams */
859 /* Instruction costs on POWER A2 processors. */
861 struct processor_costs ppca2_cost
= {
862 COSTS_N_INSNS (16), /* mulsi */
863 COSTS_N_INSNS (16), /* mulsi_const */
864 COSTS_N_INSNS (16), /* mulsi_const9 */
865 COSTS_N_INSNS (16), /* muldi */
866 COSTS_N_INSNS (22), /* divsi */
867 COSTS_N_INSNS (28), /* divdi */
868 COSTS_N_INSNS (3), /* fp */
869 COSTS_N_INSNS (3), /* dmul */
870 COSTS_N_INSNS (59), /* sdiv */
871 COSTS_N_INSNS (72), /* ddiv */
875 16, /* prefetch streams */
879 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
880 #undef RS6000_BUILTIN
881 #undef RS6000_BUILTIN_EQUATE
882 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
883 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
885 static const enum rs6000_btc builtin_classify
[(int)RS6000_BUILTIN_COUNT
] =
887 #include "rs6000-builtin.def"
890 #undef RS6000_BUILTIN
891 #undef RS6000_BUILTIN_EQUATE
893 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
894 static tree (*rs6000_veclib_handler
) (tree
, tree
, tree
);
897 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
898 static const char *rs6000_invalid_within_doloop (const_rtx
);
899 static bool rs6000_legitimate_address_p (enum machine_mode
, rtx
, bool);
900 static bool rs6000_debug_legitimate_address_p (enum machine_mode
, rtx
, bool);
901 static rtx
rs6000_generate_compare (rtx
, enum machine_mode
);
902 static void rs6000_emit_stack_tie (void);
903 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
904 static bool spe_func_has_64bit_regs_p (void);
905 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
907 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
908 static unsigned rs6000_hash_constant (rtx
);
909 static unsigned toc_hash_function (const void *);
910 static int toc_hash_eq (const void *, const void *);
911 static bool reg_offset_addressing_ok_p (enum machine_mode
);
912 static bool virtual_stack_registers_memory_p (rtx
);
913 static bool constant_pool_expr_p (rtx
);
914 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
915 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
916 static struct machine_function
* rs6000_init_machine_status (void);
917 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
918 static bool no_global_regs_above (int, bool);
919 #ifdef HAVE_GAS_HIDDEN
920 static void rs6000_assemble_visibility (tree
, int);
922 static int rs6000_ra_ever_killed (void);
923 static bool rs6000_attribute_takes_identifier_p (const_tree
);
924 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
925 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
926 static bool rs6000_ms_bitfield_layout_p (const_tree
);
927 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
928 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
929 static const char *rs6000_mangle_type (const_tree
);
930 static void rs6000_set_default_type_attributes (tree
);
931 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
932 static rtx
rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
933 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
934 enum machine_mode
, bool, bool, bool);
935 static bool rs6000_reg_live_or_pic_offset_p (int);
936 static tree
rs6000_builtin_vectorized_libmass (tree
, tree
, tree
);
937 static tree
rs6000_builtin_vectorized_function (tree
, tree
, tree
);
938 static void rs6000_restore_saved_cr (rtx
, int);
939 static bool rs6000_output_addr_const_extra (FILE *, rtx
);
940 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
941 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
942 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
944 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
945 static bool rs6000_return_in_memory (const_tree
, const_tree
);
946 static rtx
rs6000_function_value (const_tree
, const_tree
, bool);
947 static void rs6000_file_start (void);
949 static int rs6000_elf_reloc_rw_mask (void);
950 static void rs6000_elf_asm_out_constructor (rtx
, int) ATTRIBUTE_UNUSED
;
951 static void rs6000_elf_asm_out_destructor (rtx
, int) ATTRIBUTE_UNUSED
;
952 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED
;
953 static void rs6000_elf_asm_init_sections (void);
954 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
955 unsigned HOST_WIDE_INT
);
956 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
959 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
960 static void rs6000_alloc_sdmode_stack_slot (void);
961 static void rs6000_instantiate_decls (void);
963 static void rs6000_xcoff_asm_output_anchor (rtx
);
964 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
965 static void rs6000_xcoff_asm_init_sections (void);
966 static int rs6000_xcoff_reloc_rw_mask (void);
967 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
968 static section
*rs6000_xcoff_select_section (tree
, int,
969 unsigned HOST_WIDE_INT
);
970 static void rs6000_xcoff_unique_section (tree
, int);
971 static section
*rs6000_xcoff_select_rtx_section
972 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
973 static const char * rs6000_xcoff_strip_name_encoding (const char *);
974 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
975 static void rs6000_xcoff_file_start (void);
976 static void rs6000_xcoff_file_end (void);
978 static int rs6000_variable_issue (FILE *, int, rtx
, int);
979 static int rs6000_register_move_cost (enum machine_mode
,
980 reg_class_t
, reg_class_t
);
981 static int rs6000_memory_move_cost (enum machine_mode
, reg_class_t
, bool);
982 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
983 static bool rs6000_debug_rtx_costs (rtx
, int, int, int *, bool);
984 static int rs6000_debug_address_cost (rtx
, bool);
985 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
986 static int rs6000_debug_adjust_cost (rtx
, rtx
, rtx
, int);
987 static void rs6000_sched_init (FILE *, int, int);
988 static bool is_microcoded_insn (rtx
);
989 static bool is_nonpipeline_insn (rtx
);
990 static bool is_cracked_insn (rtx
);
991 static bool is_branch_slot_insn (rtx
);
992 static bool is_load_insn (rtx
);
993 static rtx
get_store_dest (rtx pat
);
994 static bool is_store_insn (rtx
);
995 static bool set_to_load_agen (rtx
,rtx
);
996 static bool adjacent_mem_locations (rtx
,rtx
);
997 static int rs6000_adjust_priority (rtx
, int);
998 static int rs6000_issue_rate (void);
999 static bool rs6000_is_costly_dependence (dep_t
, int, int);
1000 static rtx
get_next_active_insn (rtx
, rtx
);
1001 static bool insn_terminates_group_p (rtx
, enum group_termination
);
1002 static bool insn_must_be_first_in_group (rtx
);
1003 static bool insn_must_be_last_in_group (rtx
);
1004 static bool is_costly_group (rtx
*, rtx
);
1005 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
1006 static int redefine_groups (FILE *, int, rtx
, rtx
);
1007 static int pad_groups (FILE *, int, rtx
, rtx
);
1008 static void rs6000_sched_finish (FILE *, int);
1009 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
1010 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
1011 static int rs6000_use_sched_lookahead (void);
1012 static int rs6000_use_sched_lookahead_guard (rtx
);
1013 static void * rs6000_alloc_sched_context (void);
1014 static void rs6000_init_sched_context (void *, bool);
1015 static void rs6000_set_sched_context (void *);
1016 static void rs6000_free_sched_context (void *);
1017 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
1018 static tree
rs6000_builtin_mask_for_load (void);
1019 static tree
rs6000_builtin_mul_widen_even (tree
);
1020 static tree
rs6000_builtin_mul_widen_odd (tree
);
1021 static tree
rs6000_builtin_conversion (unsigned int, tree
, tree
);
1022 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
1023 static bool rs6000_builtin_support_vector_misalignment (enum
1027 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt
,
1029 static enum machine_mode
rs6000_preferred_simd_mode (enum machine_mode
);
1031 static void def_builtin (int, const char *, tree
, int);
1032 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
1033 static void rs6000_init_builtins (void);
1034 static tree
rs6000_builtin_decl (unsigned, bool);
1036 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
1037 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
1038 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
1039 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
1040 static void altivec_init_builtins (void);
1041 static unsigned builtin_hash_function (const void *);
1042 static int builtin_hash_eq (const void *, const void *);
1043 static tree
builtin_function_type (enum machine_mode
, enum machine_mode
,
1044 enum machine_mode
, enum machine_mode
,
1045 enum rs6000_builtins
, const char *name
);
1046 static void rs6000_common_init_builtins (void);
1047 static void rs6000_init_libfuncs (void);
1049 static void paired_init_builtins (void);
1050 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
1051 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
1052 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
1053 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1055 static void enable_mask_for_builtins (struct builtin_description
*, int,
1056 enum rs6000_builtins
,
1057 enum rs6000_builtins
);
1058 static void spe_init_builtins (void);
1059 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
1060 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
1061 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1062 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
1063 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
1064 static rs6000_stack_t
*rs6000_stack_info (void);
1065 static void debug_stack_info (rs6000_stack_t
*);
1067 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
1068 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
1069 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
1070 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
1071 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
1072 static rtx
altivec_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1073 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
1074 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
1075 static rtx
altivec_expand_vec_set_builtin (tree
);
1076 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
1077 static int get_element_number (tree
, tree
);
1078 static void rs6000_option_override (void);
1079 static void rs6000_option_init_struct (struct gcc_options
*);
1080 static void rs6000_option_default_params (void);
1081 static bool rs6000_handle_option (struct gcc_options
*, struct gcc_options
*,
1082 const struct cl_decoded_option
*,
1084 static int rs6000_loop_align_max_skip (rtx
);
1085 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1086 static int first_altivec_reg_to_save (void);
1087 static unsigned int compute_vrsave_mask (void);
1088 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
1089 static void is_altivec_return_reg (rtx
, void *);
1090 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
1091 int easy_vector_constant (rtx
, enum machine_mode
);
1092 static rtx
rs6000_dwarf_register_span (rtx
);
1093 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
1094 static rtx
rs6000_legitimize_address (rtx
, rtx
, enum machine_mode
);
1095 static rtx
rs6000_debug_legitimize_address (rtx
, rtx
, enum machine_mode
);
1096 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
1097 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
1098 static rtx
rs6000_delegitimize_address (rtx
);
1099 static rtx
rs6000_tls_get_addr (void);
1100 static rtx
rs6000_got_sym (void);
1101 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
1102 static const char *rs6000_get_some_local_dynamic_name (void);
1103 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
1104 static rtx
rs6000_complex_function_value (enum machine_mode
);
1105 static rtx
rs6000_spe_function_arg (const CUMULATIVE_ARGS
*,
1106 enum machine_mode
, const_tree
);
1107 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
1108 HOST_WIDE_INT
, int);
1109 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
1112 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
1115 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
1116 const_tree
, HOST_WIDE_INT
,
1118 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, bool, bool);
1119 static rtx
rs6000_mixed_function_arg (enum machine_mode
, const_tree
, int);
1120 static void rs6000_function_arg_advance (CUMULATIVE_ARGS
*, enum machine_mode
,
1122 static rtx
rs6000_function_arg (CUMULATIVE_ARGS
*, enum machine_mode
,
1124 static unsigned int rs6000_function_arg_boundary (enum machine_mode
,
1126 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
1127 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
1128 enum machine_mode
, tree
,
1130 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
1132 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
1134 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
1136 static void macho_branch_islands (void);
1137 static int no_previous_def (tree function_name
);
1138 static tree
get_prev_label (tree function_name
);
1139 static void rs6000_darwin_file_start (void);
1142 static tree
rs6000_build_builtin_va_list (void);
1143 static void rs6000_va_start (tree
, rtx
);
1144 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
1145 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
1146 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
1147 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
1148 static rtx
rs6000_emit_vector_compare_inner (enum rtx_code
, rtx
, rtx
);
1149 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
1151 static tree
rs6000_stack_protect_fail (void);
1153 static rtx
rs6000_legitimize_reload_address (rtx
, enum machine_mode
, int, int,
1156 static rtx
rs6000_debug_legitimize_reload_address (rtx
, enum machine_mode
, int,
1159 rtx (*rs6000_legitimize_reload_address_ptr
) (rtx
, enum machine_mode
, int, int,
1161 = rs6000_legitimize_reload_address
;
1163 static bool rs6000_mode_dependent_address_p (const_rtx
);
1164 static bool rs6000_mode_dependent_address (const_rtx
);
1165 static bool rs6000_debug_mode_dependent_address (const_rtx
);
1166 static bool (*rs6000_mode_dependent_address_ptr
) (const_rtx
)
1167 = rs6000_mode_dependent_address
;
1169 static enum reg_class
rs6000_secondary_reload_class (enum reg_class
,
1170 enum machine_mode
, rtx
);
1171 static enum reg_class
rs6000_debug_secondary_reload_class (enum reg_class
,
1174 enum reg_class (*rs6000_secondary_reload_class_ptr
) (enum reg_class
,
1175 enum machine_mode
, rtx
)
1176 = rs6000_secondary_reload_class
;
1178 static enum reg_class
rs6000_preferred_reload_class (rtx
, enum reg_class
);
1179 static enum reg_class
rs6000_debug_preferred_reload_class (rtx
,
1181 enum reg_class (*rs6000_preferred_reload_class_ptr
) (rtx
, enum reg_class
)
1182 = rs6000_preferred_reload_class
;
1184 static bool rs6000_secondary_memory_needed (enum reg_class
, enum reg_class
,
1187 static bool rs6000_debug_secondary_memory_needed (enum reg_class
,
1191 bool (*rs6000_secondary_memory_needed_ptr
) (enum reg_class
, enum reg_class
,
1193 = rs6000_secondary_memory_needed
;
1195 static bool rs6000_cannot_change_mode_class (enum machine_mode
,
1198 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode
,
1202 bool (*rs6000_cannot_change_mode_class_ptr
) (enum machine_mode
,
1205 = rs6000_cannot_change_mode_class
;
1207 static reg_class_t
rs6000_secondary_reload (bool, rtx
, reg_class_t
,
1209 struct secondary_reload_info
*);
1211 static const reg_class_t
*rs6000_ira_cover_classes (void);
1213 const int INSN_NOT_AVAILABLE
= -1;
1214 static enum machine_mode
rs6000_eh_return_filter_mode (void);
1215 static bool rs6000_can_eliminate (const int, const int);
1216 static void rs6000_conditional_register_usage (void);
1217 static void rs6000_trampoline_init (rtx
, tree
, rtx
);
1219 /* Hash table stuff for keeping track of TOC entries. */
1221 struct GTY(()) toc_hash_struct
1223 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1224 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1226 enum machine_mode key_mode
;
1230 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
1232 /* Hash table to keep track of the argument types for builtin functions. */
1234 struct GTY(()) builtin_hash_struct
1237 enum machine_mode mode
[4]; /* return value + 3 arguments. */
1238 unsigned char uns_p
[4]; /* and whether the types are unsigned. */
1241 static GTY ((param_is (struct builtin_hash_struct
))) htab_t builtin_hash_table
;
1243 static bool rs6000_valid_attribute_p (tree
, tree
, tree
, int);
1244 static void rs6000_function_specific_save (struct cl_target_option
*);
1245 static void rs6000_function_specific_restore (struct cl_target_option
*);
1246 static void rs6000_function_specific_print (FILE *, int,
1247 struct cl_target_option
*);
1248 static bool rs6000_can_inline_p (tree
, tree
);
1249 static void rs6000_set_current_function (tree
);
1252 /* Default register names. */
1253 char rs6000_reg_names
[][8] =
1255 "0", "1", "2", "3", "4", "5", "6", "7",
1256 "8", "9", "10", "11", "12", "13", "14", "15",
1257 "16", "17", "18", "19", "20", "21", "22", "23",
1258 "24", "25", "26", "27", "28", "29", "30", "31",
1259 "0", "1", "2", "3", "4", "5", "6", "7",
1260 "8", "9", "10", "11", "12", "13", "14", "15",
1261 "16", "17", "18", "19", "20", "21", "22", "23",
1262 "24", "25", "26", "27", "28", "29", "30", "31",
1263 "mq", "lr", "ctr","ap",
1264 "0", "1", "2", "3", "4", "5", "6", "7",
1266 /* AltiVec registers. */
1267 "0", "1", "2", "3", "4", "5", "6", "7",
1268 "8", "9", "10", "11", "12", "13", "14", "15",
1269 "16", "17", "18", "19", "20", "21", "22", "23",
1270 "24", "25", "26", "27", "28", "29", "30", "31",
1272 /* SPE registers. */
1273 "spe_acc", "spefscr",
1274 /* Soft frame pointer. */
1278 #ifdef TARGET_REGNAMES
1279 static const char alt_reg_names
[][8] =
1281 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1282 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1283 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1284 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1285 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1286 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1287 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1288 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1289 "mq", "lr", "ctr", "ap",
1290 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1292 /* AltiVec registers. */
1293 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1294 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1295 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1296 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1298 /* SPE registers. */
1299 "spe_acc", "spefscr",
1300 /* Soft frame pointer. */
1305 /* Table of valid machine attributes. */
1307 static const struct attribute_spec rs6000_attribute_table
[] =
1309 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1310 affects_type_identity } */
1311 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
,
1313 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
,
1315 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
,
1317 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
,
1319 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
,
1321 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1322 SUBTARGET_ATTRIBUTE_TABLE
,
1324 { NULL
, 0, 0, false, false, false, NULL
, false }
1327 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1328 static const struct default_options rs6000_option_optimization_table
[] =
1330 { OPT_LEVELS_1_PLUS
, OPT_fomit_frame_pointer
, NULL
, 1 },
1331 { OPT_LEVELS_NONE
, 0, NULL
, 0 }
1334 #ifndef MASK_STRICT_ALIGN
1335 #define MASK_STRICT_ALIGN 0
1337 #ifndef TARGET_PROFILE_KERNEL
1338 #define TARGET_PROFILE_KERNEL 0
1341 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1342 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1344 /* Initialize the GCC target structure. */
1345 #undef TARGET_ATTRIBUTE_TABLE
1346 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1347 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1348 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1349 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1350 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1352 #undef TARGET_ASM_ALIGNED_DI_OP
1353 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1355 /* Default unaligned ops are only provided for ELF. Find the ops needed
1356 for non-ELF systems. */
1357 #ifndef OBJECT_FORMAT_ELF
1359 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1361 #undef TARGET_ASM_UNALIGNED_HI_OP
1362 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1363 #undef TARGET_ASM_UNALIGNED_SI_OP
1364 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1365 #undef TARGET_ASM_UNALIGNED_DI_OP
1366 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1369 #undef TARGET_ASM_UNALIGNED_HI_OP
1370 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1371 #undef TARGET_ASM_UNALIGNED_SI_OP
1372 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1373 #undef TARGET_ASM_UNALIGNED_DI_OP
1374 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1375 #undef TARGET_ASM_ALIGNED_DI_OP
1376 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1380 /* This hook deals with fixups for relocatable code and DI-mode objects
1382 #undef TARGET_ASM_INTEGER
1383 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1385 #ifdef HAVE_GAS_HIDDEN
1386 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1387 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1390 #undef TARGET_HAVE_TLS
1391 #define TARGET_HAVE_TLS HAVE_AS_TLS
1393 #undef TARGET_CANNOT_FORCE_CONST_MEM
1394 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1396 #undef TARGET_DELEGITIMIZE_ADDRESS
1397 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1399 #undef TARGET_ASM_FUNCTION_PROLOGUE
1400 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1401 #undef TARGET_ASM_FUNCTION_EPILOGUE
1402 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1404 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1405 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1407 #undef TARGET_LEGITIMIZE_ADDRESS
1408 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1410 #undef TARGET_SCHED_VARIABLE_ISSUE
1411 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1413 #undef TARGET_SCHED_ISSUE_RATE
1414 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1415 #undef TARGET_SCHED_ADJUST_COST
1416 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1417 #undef TARGET_SCHED_ADJUST_PRIORITY
1418 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1419 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1420 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1421 #undef TARGET_SCHED_INIT
1422 #define TARGET_SCHED_INIT rs6000_sched_init
1423 #undef TARGET_SCHED_FINISH
1424 #define TARGET_SCHED_FINISH rs6000_sched_finish
1425 #undef TARGET_SCHED_REORDER
1426 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1427 #undef TARGET_SCHED_REORDER2
1428 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1430 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1431 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1433 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1434 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1436 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1437 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1438 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1439 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1440 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1441 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1442 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1443 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1445 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1446 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1447 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1448 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1449 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1450 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1451 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1452 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1453 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1454 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1455 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1456 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1457 rs6000_builtin_support_vector_misalignment
1458 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1459 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1460 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1461 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1462 rs6000_builtin_vectorization_cost
1463 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1464 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1465 rs6000_preferred_simd_mode
1467 #undef TARGET_INIT_BUILTINS
1468 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1469 #undef TARGET_BUILTIN_DECL
1470 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1472 #undef TARGET_EXPAND_BUILTIN
1473 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1475 #undef TARGET_MANGLE_TYPE
1476 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1478 #undef TARGET_INIT_LIBFUNCS
1479 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1482 #undef TARGET_BINDS_LOCAL_P
1483 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1486 #undef TARGET_MS_BITFIELD_LAYOUT_P
1487 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1489 #undef TARGET_ASM_OUTPUT_MI_THUNK
1490 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1492 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1493 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1495 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1496 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1498 #undef TARGET_INVALID_WITHIN_DOLOOP
1499 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1501 #undef TARGET_REGISTER_MOVE_COST
1502 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1503 #undef TARGET_MEMORY_MOVE_COST
1504 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1505 #undef TARGET_RTX_COSTS
1506 #define TARGET_RTX_COSTS rs6000_rtx_costs
1507 #undef TARGET_ADDRESS_COST
1508 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1510 #undef TARGET_DWARF_REGISTER_SPAN
1511 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1513 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1514 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1516 /* On rs6000, function arguments are promoted, as are function return
1518 #undef TARGET_PROMOTE_FUNCTION_MODE
1519 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1521 #undef TARGET_RETURN_IN_MEMORY
1522 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1524 #undef TARGET_SETUP_INCOMING_VARARGS
1525 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1527 /* Always strict argument naming on rs6000. */
1528 #undef TARGET_STRICT_ARGUMENT_NAMING
1529 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1530 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1531 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1532 #undef TARGET_SPLIT_COMPLEX_ARG
1533 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1534 #undef TARGET_MUST_PASS_IN_STACK
1535 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1536 #undef TARGET_PASS_BY_REFERENCE
1537 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1538 #undef TARGET_ARG_PARTIAL_BYTES
1539 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1540 #undef TARGET_FUNCTION_ARG_ADVANCE
1541 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1542 #undef TARGET_FUNCTION_ARG
1543 #define TARGET_FUNCTION_ARG rs6000_function_arg
1544 #undef TARGET_FUNCTION_ARG_BOUNDARY
1545 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1547 #undef TARGET_BUILD_BUILTIN_VA_LIST
1548 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1550 #undef TARGET_EXPAND_BUILTIN_VA_START
1551 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1553 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1554 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1556 #undef TARGET_EH_RETURN_FILTER_MODE
1557 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1559 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1560 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1562 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1563 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1565 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1566 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1568 #undef TARGET_HANDLE_OPTION
1569 #define TARGET_HANDLE_OPTION rs6000_handle_option
1571 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1572 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1574 #undef TARGET_OPTION_OVERRIDE
1575 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1577 #undef TARGET_OPTION_INIT_STRUCT
1578 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1580 #undef TARGET_OPTION_DEFAULT_PARAMS
1581 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1583 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1584 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1586 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1587 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1588 rs6000_builtin_vectorized_function
1590 #undef TARGET_DEFAULT_TARGET_FLAGS
1591 #define TARGET_DEFAULT_TARGET_FLAGS \
1594 #undef TARGET_STACK_PROTECT_FAIL
1595 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1597 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1598 The PowerPC architecture requires only weak consistency among
1599 processors--that is, memory accesses between processors need not be
1600 sequentially consistent and memory accesses among processors can occur
1601 in any order. The ability to order memory accesses weakly provides
1602 opportunities for more efficient use of the system bus. Unless a
1603 dependency exists, the 604e allows read operations to precede store
1605 #undef TARGET_RELAXED_ORDERING
1606 #define TARGET_RELAXED_ORDERING true
1609 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1610 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1613 /* Use a 32-bit anchor range. This leads to sequences like:
1615 addis tmp,anchor,high
1618 where tmp itself acts as an anchor, and can be shared between
1619 accesses to the same 64k page. */
1620 #undef TARGET_MIN_ANCHOR_OFFSET
1621 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1622 #undef TARGET_MAX_ANCHOR_OFFSET
1623 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1624 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1625 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1627 #undef TARGET_BUILTIN_RECIPROCAL
1628 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1630 #undef TARGET_EXPAND_TO_RTL_HOOK
1631 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1633 #undef TARGET_INSTANTIATE_DECLS
1634 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1636 #undef TARGET_SECONDARY_RELOAD
1637 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1639 #undef TARGET_IRA_COVER_CLASSES
1640 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1642 #undef TARGET_LEGITIMATE_ADDRESS_P
1643 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1645 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1646 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1648 #undef TARGET_CAN_ELIMINATE
1649 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1651 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1652 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1654 #undef TARGET_TRAMPOLINE_INIT
1655 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1657 #undef TARGET_FUNCTION_VALUE
1658 #define TARGET_FUNCTION_VALUE rs6000_function_value
1660 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1661 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1663 #undef TARGET_OPTION_SAVE
1664 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1666 #undef TARGET_OPTION_RESTORE
1667 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1669 #undef TARGET_OPTION_PRINT
1670 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1672 #undef TARGET_CAN_INLINE_P
1673 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1675 #undef TARGET_SET_CURRENT_FUNCTION
1676 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1678 struct gcc_target targetm
= TARGET_INITIALIZER
;
1681 /* Simplifications for entries below. */
1684 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1685 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1688 /* Some OSs don't support saving the high part of 64-bit registers on context
1689 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1690 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1691 either, the user must explicitly specify them and we won't interfere with
1692 the user's specification. */
1695 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1696 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1697 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1698 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1699 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
1700 | MASK_POPCNTD
| MASK_VSX
| MASK_ISEL
| MASK_NO_UPDATE
1701 | MASK_RECIP_PRECISION
)
1704 /* Masks for instructions set at various powerpc ISAs. */
1706 ISA_2_1_MASKS
= MASK_MFCRF
,
1707 ISA_2_2_MASKS
= (ISA_2_1_MASKS
| MASK_POPCNTB
),
1708 ISA_2_4_MASKS
= (ISA_2_2_MASKS
| MASK_FPRND
),
1710 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1711 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1712 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1713 server and embedded. */
1714 ISA_2_5_MASKS_EMBEDDED
= (ISA_2_2_MASKS
| MASK_CMPB
| MASK_RECIP_PRECISION
1715 | MASK_PPC_GFXOPT
| MASK_PPC_GPOPT
),
1716 ISA_2_5_MASKS_SERVER
= (ISA_2_5_MASKS_EMBEDDED
| MASK_DFP
),
1718 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1719 altivec is a win so enable it. */
1720 ISA_2_6_MASKS_EMBEDDED
= (ISA_2_5_MASKS_EMBEDDED
| MASK_POPCNTD
),
1721 ISA_2_6_MASKS_SERVER
= (ISA_2_5_MASKS_SERVER
| MASK_POPCNTD
| MASK_ALTIVEC
1725 /* This table occasionally claims that a processor does not support a
1726 particular feature even though it does, but the feature is slower than the
1727 alternative. Thus, it shouldn't be relied on as a complete description of
1728 the processor's support.
1730 Please keep this list in order, and don't forget to update the documentation
1731 in invoke.texi when adding a new processor or flag. */
1735 const char *const name
; /* Canonical processor name. */
1736 const enum processor_type processor
; /* Processor type enum value. */
1737 const int target_enable
; /* Target flags to enable. */
1740 static struct rs6000_ptt
const processor_target_table
[] =
1742 {"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1743 {"403", PROCESSOR_PPC403
,
1744 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1745 {"405", PROCESSOR_PPC405
,
1746 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1747 {"405fp", PROCESSOR_PPC405
,
1748 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1749 {"440", PROCESSOR_PPC440
,
1750 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1751 {"440fp", PROCESSOR_PPC440
,
1752 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1753 {"464", PROCESSOR_PPC440
,
1754 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1755 {"464fp", PROCESSOR_PPC440
,
1756 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1757 {"476", PROCESSOR_PPC476
,
1758 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_PPC_GFXOPT
| MASK_MFCRF
1759 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
1760 {"476fp", PROCESSOR_PPC476
,
1761 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POPCNTB
1762 | MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
1763 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1764 {"601", PROCESSOR_PPC601
,
1765 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1766 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1767 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1768 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1769 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1770 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1771 {"620", PROCESSOR_PPC620
,
1772 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1773 {"630", PROCESSOR_PPC630
,
1774 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1775 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1776 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1777 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1778 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1779 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1780 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1781 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1782 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
1784 /* 8548 has a dummy entry for now. */
1785 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
1787 {"a2", PROCESSOR_PPCA2
,
1788 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_POPCNTB
1789 | MASK_CMPB
| MASK_NO_UPDATE
},
1790 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1791 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
1792 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
1794 {"e500mc64", PROCESSOR_PPCE500MC64
, POWERPC_BASE_MASK
| MASK_POWERPC64
1795 | MASK_PPC_GFXOPT
| MASK_ISEL
},
1796 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1797 {"970", PROCESSOR_POWER4
,
1798 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1799 {"cell", PROCESSOR_CELL
,
1800 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1801 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1802 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1803 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1804 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1805 {"G5", PROCESSOR_POWER4
,
1806 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1807 {"titan", PROCESSOR_TITAN
,
1808 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1809 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1810 {"power2", PROCESSOR_POWER
,
1811 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1812 {"power3", PROCESSOR_PPC630
,
1813 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1814 {"power4", PROCESSOR_POWER4
,
1815 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1817 {"power5", PROCESSOR_POWER5
,
1818 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1819 | MASK_MFCRF
| MASK_POPCNTB
},
1820 {"power5+", PROCESSOR_POWER5
,
1821 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1822 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1823 {"power6", PROCESSOR_POWER6
,
1824 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1825 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
1826 | MASK_RECIP_PRECISION
},
1827 {"power6x", PROCESSOR_POWER6
,
1828 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1829 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
1830 | MASK_MFPGPR
| MASK_RECIP_PRECISION
},
1831 {"power7", PROCESSOR_POWER7
, /* Don't add MASK_ISEL by default */
1832 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
1833 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
| MASK_POPCNTD
1834 | MASK_VSX
| MASK_RECIP_PRECISION
},
1835 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1836 {"powerpc64", PROCESSOR_POWERPC64
,
1837 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1838 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1839 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1840 {"rios2", PROCESSOR_RIOS2
,
1841 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1842 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1843 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1844 {"rs64", PROCESSOR_RS64A
,
1845 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1848 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1852 rs6000_cpu_name_lookup (const char *name
)
1858 for (i
= 0; i
< ARRAY_SIZE (processor_target_table
); i
++)
1859 if (! strcmp (name
, processor_target_table
[i
].name
))
1867 /* Return number of consecutive hard regs needed starting at reg REGNO
1868 to hold something of mode MODE.
1869 This is ordinarily the length in words of a value of mode MODE
1870 but can be less for certain modes in special long registers.
1872 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1873 scalar instructions. The upper 32 bits are only available to the
1876 POWER and PowerPC GPRs hold 32 bits worth;
1877 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1880 rs6000_hard_regno_nregs_internal (int regno
, enum machine_mode mode
)
1882 unsigned HOST_WIDE_INT reg_size
;
1884 if (FP_REGNO_P (regno
))
1885 reg_size
= (VECTOR_MEM_VSX_P (mode
)
1886 ? UNITS_PER_VSX_WORD
1887 : UNITS_PER_FP_WORD
);
1889 else if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1890 reg_size
= UNITS_PER_SPE_WORD
;
1892 else if (ALTIVEC_REGNO_P (regno
))
1893 reg_size
= UNITS_PER_ALTIVEC_WORD
;
1895 /* The value returned for SCmode in the E500 double case is 2 for
1896 ABI compatibility; storing an SCmode value in a single register
1897 would require function_arg and rs6000_spe_function_arg to handle
1898 SCmode so as to pass the value correctly in a pair of
1900 else if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
1901 && !DECIMAL_FLOAT_MODE_P (mode
))
1902 reg_size
= UNITS_PER_FP_WORD
;
1905 reg_size
= UNITS_PER_WORD
;
1907 return (GET_MODE_SIZE (mode
) + reg_size
- 1) / reg_size
;
1910 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1913 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1915 int last_regno
= regno
+ rs6000_hard_regno_nregs
[mode
][regno
] - 1;
1917 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1918 implementations. Don't allow an item to be split between a FP register
1919 and an Altivec register. */
1920 if (VECTOR_MEM_VSX_P (mode
))
1922 if (FP_REGNO_P (regno
))
1923 return FP_REGNO_P (last_regno
);
1925 if (ALTIVEC_REGNO_P (regno
))
1926 return ALTIVEC_REGNO_P (last_regno
);
1929 /* The GPRs can hold any mode, but values bigger than one register
1930 cannot go past R31. */
1931 if (INT_REGNO_P (regno
))
1932 return INT_REGNO_P (last_regno
);
1934 /* The float registers (except for VSX vector modes) can only hold floating
1935 modes and DImode. This excludes the 32-bit decimal float mode for
1937 if (FP_REGNO_P (regno
))
1939 if (SCALAR_FLOAT_MODE_P (mode
)
1940 && (mode
!= TDmode
|| (regno
% 2) == 0)
1941 && FP_REGNO_P (last_regno
))
1944 if (GET_MODE_CLASS (mode
) == MODE_INT
1945 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1948 if (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1949 && PAIRED_VECTOR_MODE (mode
))
1955 /* The CR register can only hold CC modes. */
1956 if (CR_REGNO_P (regno
))
1957 return GET_MODE_CLASS (mode
) == MODE_CC
;
1959 if (CA_REGNO_P (regno
))
1960 return mode
== BImode
;
1962 /* AltiVec only in AldyVec registers. */
1963 if (ALTIVEC_REGNO_P (regno
))
1964 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
);
1966 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1967 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1970 /* We cannot put TImode anywhere except general register and it must be able
1971 to fit within the register set. In the future, allow TImode in the
1972 Altivec or VSX registers. */
1974 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1977 /* Print interesting facts about registers. */
1979 rs6000_debug_reg_print (int first_regno
, int last_regno
, const char *reg_name
)
1983 for (r
= first_regno
; r
<= last_regno
; ++r
)
1985 const char *comma
= "";
1988 if (first_regno
== last_regno
)
1989 fprintf (stderr
, "%s:\t", reg_name
);
1991 fprintf (stderr
, "%s%d:\t", reg_name
, r
- first_regno
);
1994 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1995 if (rs6000_hard_regno_mode_ok_p
[m
][r
] && rs6000_hard_regno_nregs
[m
][r
])
1999 fprintf (stderr
, ",\n\t");
2004 if (rs6000_hard_regno_nregs
[m
][r
] > 1)
2005 len
+= fprintf (stderr
, "%s%s/%d", comma
, GET_MODE_NAME (m
),
2006 rs6000_hard_regno_nregs
[m
][r
]);
2008 len
+= fprintf (stderr
, "%s%s", comma
, GET_MODE_NAME (m
));
2013 if (call_used_regs
[r
])
2017 fprintf (stderr
, ",\n\t");
2022 len
+= fprintf (stderr
, "%s%s", comma
, "call-used");
2030 fprintf (stderr
, ",\n\t");
2035 len
+= fprintf (stderr
, "%s%s", comma
, "fixed");
2041 fprintf (stderr
, ",\n\t");
2045 fprintf (stderr
, "%sregno = %d\n", comma
, r
);
2049 #define DEBUG_FMT_D "%-32s= %d\n"
2050 #define DEBUG_FMT_S "%-32s= %s\n"
2052 /* Print various interesting information with -mdebug=reg. */
2054 rs6000_debug_reg_global (void)
2056 static const char *const tf
[2] = { "false", "true" };
2057 const char *nl
= (const char *)0;
2059 char costly_num
[20];
2061 const char *costly_str
;
2062 const char *nop_str
;
2063 const char *trace_str
;
2064 const char *abi_str
;
2065 const char *cmodel_str
;
2067 /* Map enum rs6000_vector to string. */
2068 static const char *rs6000_debug_vector_unit
[] = {
2077 fprintf (stderr
, "Register information: (last virtual reg = %d)\n",
2078 LAST_VIRTUAL_REGISTER
);
2079 rs6000_debug_reg_print (0, 31, "gr");
2080 rs6000_debug_reg_print (32, 63, "fp");
2081 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO
,
2084 rs6000_debug_reg_print (LR_REGNO
, LR_REGNO
, "lr");
2085 rs6000_debug_reg_print (CTR_REGNO
, CTR_REGNO
, "ctr");
2086 rs6000_debug_reg_print (CR0_REGNO
, CR7_REGNO
, "cr");
2087 rs6000_debug_reg_print (MQ_REGNO
, MQ_REGNO
, "mq");
2088 rs6000_debug_reg_print (CA_REGNO
, CA_REGNO
, "ca");
2089 rs6000_debug_reg_print (VRSAVE_REGNO
, VRSAVE_REGNO
, "vrsave");
2090 rs6000_debug_reg_print (VSCR_REGNO
, VSCR_REGNO
, "vscr");
2091 rs6000_debug_reg_print (SPE_ACC_REGNO
, SPE_ACC_REGNO
, "spe_a");
2092 rs6000_debug_reg_print (SPEFSCR_REGNO
, SPEFSCR_REGNO
, "spe_f");
2096 "d reg_class = %s\n"
2097 "f reg_class = %s\n"
2098 "v reg_class = %s\n"
2099 "wa reg_class = %s\n"
2100 "wd reg_class = %s\n"
2101 "wf reg_class = %s\n"
2102 "ws reg_class = %s\n\n",
2103 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_d
]],
2104 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_f
]],
2105 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_v
]],
2106 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wa
]],
2107 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wd
]],
2108 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wf
]],
2109 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_ws
]]);
2111 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2112 if (rs6000_vector_unit
[m
] || rs6000_vector_mem
[m
])
2115 fprintf (stderr
, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2117 rs6000_debug_vector_unit
[ rs6000_vector_unit
[m
] ],
2118 rs6000_debug_vector_unit
[ rs6000_vector_mem
[m
] ]);
2124 if (rs6000_recip_control
)
2126 fprintf (stderr
, "\nReciprocal mask = 0x%x\n", rs6000_recip_control
);
2128 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2129 if (rs6000_recip_bits
[m
])
2132 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2134 (RS6000_RECIP_AUTO_RE_P (m
)
2136 : (RS6000_RECIP_HAVE_RE_P (m
) ? "have" : "none")),
2137 (RS6000_RECIP_AUTO_RSQRTE_P (m
)
2139 : (RS6000_RECIP_HAVE_RSQRTE_P (m
) ? "have" : "none")));
2142 fputs ("\n", stderr
);
2145 if (rs6000_cpu_index
>= 0)
2146 fprintf (stderr
, DEBUG_FMT_S
, "cpu",
2147 processor_target_table
[rs6000_cpu_index
].name
);
2149 if (rs6000_tune_index
>= 0)
2150 fprintf (stderr
, DEBUG_FMT_S
, "tune",
2151 processor_target_table
[rs6000_tune_index
].name
);
2153 switch (rs6000_sched_costly_dep
)
2155 case max_dep_latency
:
2156 costly_str
= "max_dep_latency";
2160 costly_str
= "no_dep_costly";
2163 case all_deps_costly
:
2164 costly_str
= "all_deps_costly";
2167 case true_store_to_load_dep_costly
:
2168 costly_str
= "true_store_to_load_dep_costly";
2171 case store_to_load_dep_costly
:
2172 costly_str
= "store_to_load_dep_costly";
2176 costly_str
= costly_num
;
2177 sprintf (costly_num
, "%d", (int)rs6000_sched_costly_dep
);
2181 fprintf (stderr
, DEBUG_FMT_S
, "sched_costly_dep", costly_str
);
2183 switch (rs6000_sched_insert_nops
)
2185 case sched_finish_regroup_exact
:
2186 nop_str
= "sched_finish_regroup_exact";
2189 case sched_finish_pad_groups
:
2190 nop_str
= "sched_finish_pad_groups";
2193 case sched_finish_none
:
2194 nop_str
= "sched_finish_none";
2199 sprintf (nop_num
, "%d", (int)rs6000_sched_insert_nops
);
2203 fprintf (stderr
, DEBUG_FMT_S
, "sched_insert_nops", nop_str
);
2205 switch (rs6000_sdata
)
2212 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "data");
2216 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "sysv");
2220 fprintf (stderr
, DEBUG_FMT_S
, "sdata", "eabi");
2225 switch (rs6000_traceback
)
2227 case traceback_default
: trace_str
= "default"; break;
2228 case traceback_none
: trace_str
= "none"; break;
2229 case traceback_part
: trace_str
= "part"; break;
2230 case traceback_full
: trace_str
= "full"; break;
2231 default: trace_str
= "unknown"; break;
2234 fprintf (stderr
, DEBUG_FMT_S
, "traceback", trace_str
);
2236 switch (rs6000_current_cmodel
)
2238 case CMODEL_SMALL
: cmodel_str
= "small"; break;
2239 case CMODEL_MEDIUM
: cmodel_str
= "medium"; break;
2240 case CMODEL_LARGE
: cmodel_str
= "large"; break;
2241 default: cmodel_str
= "unknown"; break;
2244 fprintf (stderr
, DEBUG_FMT_S
, "cmodel", cmodel_str
);
2246 switch (rs6000_current_abi
)
2248 case ABI_NONE
: abi_str
= "none"; break;
2249 case ABI_AIX
: abi_str
= "aix"; break;
2250 case ABI_V4
: abi_str
= "V4"; break;
2251 case ABI_DARWIN
: abi_str
= "darwin"; break;
2252 default: abi_str
= "unknown"; break;
2255 fprintf (stderr
, DEBUG_FMT_S
, "abi", abi_str
);
2257 if (rs6000_altivec_abi
)
2258 fprintf (stderr
, DEBUG_FMT_S
, "altivec_abi", "true");
2261 fprintf (stderr
, DEBUG_FMT_S
, "spe_abi", "true");
2263 if (rs6000_darwin64_abi
)
2264 fprintf (stderr
, DEBUG_FMT_S
, "darwin64_abi", "true");
2266 if (rs6000_float_gprs
)
2267 fprintf (stderr
, DEBUG_FMT_S
, "float_gprs", "true");
2269 fprintf (stderr
, DEBUG_FMT_S
, "always_hint", tf
[!!rs6000_always_hint
]);
2270 fprintf (stderr
, DEBUG_FMT_S
, "align_branch",
2271 tf
[!!rs6000_align_branch_targets
]);
2272 fprintf (stderr
, DEBUG_FMT_D
, "tls_size", rs6000_tls_size
);
2273 fprintf (stderr
, DEBUG_FMT_D
, "long_double_size",
2274 rs6000_long_double_type_size
);
2275 fprintf (stderr
, DEBUG_FMT_D
, "sched_restricted_insns_priority",
2276 (int)rs6000_sched_restricted_insns_priority
);
2279 /* Initialize the various global tables that are based on register size. */
2281 rs6000_init_hard_regno_mode_ok (bool global_init_p
)
2287 /* Precalculate REGNO_REG_CLASS. */
2288 rs6000_regno_regclass
[0] = GENERAL_REGS
;
2289 for (r
= 1; r
< 32; ++r
)
2290 rs6000_regno_regclass
[r
] = BASE_REGS
;
2292 for (r
= 32; r
< 64; ++r
)
2293 rs6000_regno_regclass
[r
] = FLOAT_REGS
;
2295 for (r
= 64; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2296 rs6000_regno_regclass
[r
] = NO_REGS
;
2298 for (r
= FIRST_ALTIVEC_REGNO
; r
<= LAST_ALTIVEC_REGNO
; ++r
)
2299 rs6000_regno_regclass
[r
] = ALTIVEC_REGS
;
2301 rs6000_regno_regclass
[CR0_REGNO
] = CR0_REGS
;
2302 for (r
= CR1_REGNO
; r
<= CR7_REGNO
; ++r
)
2303 rs6000_regno_regclass
[r
] = CR_REGS
;
2305 rs6000_regno_regclass
[MQ_REGNO
] = MQ_REGS
;
2306 rs6000_regno_regclass
[LR_REGNO
] = LINK_REGS
;
2307 rs6000_regno_regclass
[CTR_REGNO
] = CTR_REGS
;
2308 rs6000_regno_regclass
[CA_REGNO
] = CA_REGS
;
2309 rs6000_regno_regclass
[VRSAVE_REGNO
] = VRSAVE_REGS
;
2310 rs6000_regno_regclass
[VSCR_REGNO
] = VRSAVE_REGS
;
2311 rs6000_regno_regclass
[SPE_ACC_REGNO
] = SPE_ACC_REGS
;
2312 rs6000_regno_regclass
[SPEFSCR_REGNO
] = SPEFSCR_REGS
;
2313 rs6000_regno_regclass
[ARG_POINTER_REGNUM
] = BASE_REGS
;
2314 rs6000_regno_regclass
[FRAME_POINTER_REGNUM
] = BASE_REGS
;
2316 /* Precalculate vector information, this must be set up before the
2317 rs6000_hard_regno_nregs_internal below. */
2318 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2320 rs6000_vector_unit
[m
] = rs6000_vector_mem
[m
] = VECTOR_NONE
;
2321 rs6000_vector_reload
[m
][0] = CODE_FOR_nothing
;
2322 rs6000_vector_reload
[m
][1] = CODE_FOR_nothing
;
2325 for (c
= 0; c
< (int)(int)RS6000_CONSTRAINT_MAX
; c
++)
2326 rs6000_constraints
[c
] = NO_REGS
;
2328 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2329 believes it can use native alignment or still uses 128-bit alignment. */
2330 if (TARGET_VSX
&& !TARGET_VSX_ALIGN_128
)
2341 /* V2DF mode, VSX only. */
2344 rs6000_vector_unit
[V2DFmode
] = VECTOR_VSX
;
2345 rs6000_vector_mem
[V2DFmode
] = VECTOR_VSX
;
2346 rs6000_vector_align
[V2DFmode
] = align64
;
2349 /* V4SF mode, either VSX or Altivec. */
2352 rs6000_vector_unit
[V4SFmode
] = VECTOR_VSX
;
2353 rs6000_vector_mem
[V4SFmode
] = VECTOR_VSX
;
2354 rs6000_vector_align
[V4SFmode
] = align32
;
2356 else if (TARGET_ALTIVEC
)
2358 rs6000_vector_unit
[V4SFmode
] = VECTOR_ALTIVEC
;
2359 rs6000_vector_mem
[V4SFmode
] = VECTOR_ALTIVEC
;
2360 rs6000_vector_align
[V4SFmode
] = align32
;
2363 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2367 rs6000_vector_unit
[V4SImode
] = VECTOR_ALTIVEC
;
2368 rs6000_vector_unit
[V8HImode
] = VECTOR_ALTIVEC
;
2369 rs6000_vector_unit
[V16QImode
] = VECTOR_ALTIVEC
;
2370 rs6000_vector_align
[V4SImode
] = align32
;
2371 rs6000_vector_align
[V8HImode
] = align32
;
2372 rs6000_vector_align
[V16QImode
] = align32
;
2376 rs6000_vector_mem
[V4SImode
] = VECTOR_VSX
;
2377 rs6000_vector_mem
[V8HImode
] = VECTOR_VSX
;
2378 rs6000_vector_mem
[V16QImode
] = VECTOR_VSX
;
2382 rs6000_vector_mem
[V4SImode
] = VECTOR_ALTIVEC
;
2383 rs6000_vector_mem
[V8HImode
] = VECTOR_ALTIVEC
;
2384 rs6000_vector_mem
[V16QImode
] = VECTOR_ALTIVEC
;
2388 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2389 Altivec doesn't have 64-bit support. */
2392 rs6000_vector_mem
[V2DImode
] = VECTOR_VSX
;
2393 rs6000_vector_unit
[V2DImode
] = VECTOR_NONE
;
2394 rs6000_vector_align
[V2DImode
] = align64
;
2397 /* DFmode, see if we want to use the VSX unit. */
2398 if (TARGET_VSX
&& TARGET_VSX_SCALAR_DOUBLE
)
2400 rs6000_vector_unit
[DFmode
] = VECTOR_VSX
;
2401 rs6000_vector_mem
[DFmode
]
2402 = (TARGET_VSX_SCALAR_MEMORY
? VECTOR_VSX
: VECTOR_NONE
);
2403 rs6000_vector_align
[DFmode
] = align64
;
2406 /* TODO add SPE and paired floating point vector support. */
2408 /* Register class constaints for the constraints that depend on compile
2410 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2411 rs6000_constraints
[RS6000_CONSTRAINT_f
] = FLOAT_REGS
;
2413 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
2414 rs6000_constraints
[RS6000_CONSTRAINT_d
] = FLOAT_REGS
;
2418 /* At present, we just use VSX_REGS, but we have different constraints
2419 based on the use, in case we want to fine tune the default register
2420 class used. wa = any VSX register, wf = register class to use for
2421 V4SF, wd = register class to use for V2DF, and ws = register classs to
2422 use for DF scalars. */
2423 rs6000_constraints
[RS6000_CONSTRAINT_wa
] = VSX_REGS
;
2424 rs6000_constraints
[RS6000_CONSTRAINT_wf
] = VSX_REGS
;
2425 rs6000_constraints
[RS6000_CONSTRAINT_wd
] = VSX_REGS
;
2426 rs6000_constraints
[RS6000_CONSTRAINT_ws
] = (TARGET_VSX_SCALAR_MEMORY
2432 rs6000_constraints
[RS6000_CONSTRAINT_v
] = ALTIVEC_REGS
;
2434 /* Set up the reload helper functions. */
2435 if (TARGET_VSX
|| TARGET_ALTIVEC
)
2439 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_di_store
;
2440 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_di_load
;
2441 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_di_store
;
2442 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_di_load
;
2443 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_di_store
;
2444 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_di_load
;
2445 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_di_store
;
2446 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_di_load
;
2447 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_di_store
;
2448 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_di_load
;
2449 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_di_store
;
2450 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_di_load
;
2454 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_si_store
;
2455 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_si_load
;
2456 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_si_store
;
2457 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_si_load
;
2458 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_si_store
;
2459 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_si_load
;
2460 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_si_store
;
2461 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_si_load
;
2462 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_si_store
;
2463 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_si_load
;
2464 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_si_store
;
2465 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_si_load
;
2469 /* Precalculate HARD_REGNO_NREGS. */
2470 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2471 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2472 rs6000_hard_regno_nregs
[m
][r
]
2473 = rs6000_hard_regno_nregs_internal (r
, (enum machine_mode
)m
);
2475 /* Precalculate HARD_REGNO_MODE_OK. */
2476 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2477 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2478 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
)m
))
2479 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
2481 /* Precalculate CLASS_MAX_NREGS sizes. */
2482 for (c
= 0; c
< LIM_REG_CLASSES
; ++c
)
2486 if (TARGET_VSX
&& VSX_REG_CLASS_P (c
))
2487 reg_size
= UNITS_PER_VSX_WORD
;
2489 else if (c
== ALTIVEC_REGS
)
2490 reg_size
= UNITS_PER_ALTIVEC_WORD
;
2492 else if (c
== FLOAT_REGS
)
2493 reg_size
= UNITS_PER_FP_WORD
;
2496 reg_size
= UNITS_PER_WORD
;
2498 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2499 rs6000_class_max_nregs
[m
][c
]
2500 = (GET_MODE_SIZE (m
) + reg_size
- 1) / reg_size
;
2503 if (TARGET_E500_DOUBLE
)
2504 rs6000_class_max_nregs
[DFmode
][GENERAL_REGS
] = 1;
2506 /* Calculate which modes to automatically generate code to use a the
2507 reciprocal divide and square root instructions. In the future, possibly
2508 automatically generate the instructions even if the user did not specify
2509 -mrecip. The older machines double precision reciprocal sqrt estimate is
2510 not accurate enough. */
2511 memset (rs6000_recip_bits
, 0, sizeof (rs6000_recip_bits
));
2513 rs6000_recip_bits
[SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2515 rs6000_recip_bits
[DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2516 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2517 rs6000_recip_bits
[V4SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2518 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2519 rs6000_recip_bits
[V2DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2521 if (TARGET_FRSQRTES
)
2522 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2524 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2525 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2526 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2527 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2528 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2530 if (rs6000_recip_control
)
2532 if (!flag_finite_math_only
)
2533 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2534 if (flag_trapping_math
)
2535 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2536 if (!flag_reciprocal_math
)
2537 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2538 if (flag_finite_math_only
&& !flag_trapping_math
&& flag_reciprocal_math
)
2540 if (RS6000_RECIP_HAVE_RE_P (SFmode
)
2541 && (rs6000_recip_control
& RECIP_SF_DIV
) != 0)
2542 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2544 if (RS6000_RECIP_HAVE_RE_P (DFmode
)
2545 && (rs6000_recip_control
& RECIP_DF_DIV
) != 0)
2546 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2548 if (RS6000_RECIP_HAVE_RE_P (V4SFmode
)
2549 && (rs6000_recip_control
& RECIP_V4SF_DIV
) != 0)
2550 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2552 if (RS6000_RECIP_HAVE_RE_P (V2DFmode
)
2553 && (rs6000_recip_control
& RECIP_V2DF_DIV
) != 0)
2554 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2556 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode
)
2557 && (rs6000_recip_control
& RECIP_SF_RSQRT
) != 0)
2558 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2560 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode
)
2561 && (rs6000_recip_control
& RECIP_DF_RSQRT
) != 0)
2562 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2564 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode
)
2565 && (rs6000_recip_control
& RECIP_V4SF_RSQRT
) != 0)
2566 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2568 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode
)
2569 && (rs6000_recip_control
& RECIP_V2DF_RSQRT
) != 0)
2570 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2574 if (global_init_p
|| TARGET_DEBUG_TARGET
)
2576 if (TARGET_DEBUG_REG
)
2577 rs6000_debug_reg_global ();
2579 if (TARGET_DEBUG_COST
|| TARGET_DEBUG_REG
)
2581 "SImode variable mult cost = %d\n"
2582 "SImode constant mult cost = %d\n"
2583 "SImode short constant mult cost = %d\n"
2584 "DImode multipliciation cost = %d\n"
2585 "SImode division cost = %d\n"
2586 "DImode division cost = %d\n"
2587 "Simple fp operation cost = %d\n"
2588 "DFmode multiplication cost = %d\n"
2589 "SFmode division cost = %d\n"
2590 "DFmode division cost = %d\n"
2591 "cache line size = %d\n"
2592 "l1 cache size = %d\n"
2593 "l2 cache size = %d\n"
2594 "simultaneous prefetches = %d\n"
2597 rs6000_cost
->mulsi_const
,
2598 rs6000_cost
->mulsi_const9
,
2606 rs6000_cost
->cache_line_size
,
2607 rs6000_cost
->l1_cache_size
,
2608 rs6000_cost
->l2_cache_size
,
2609 rs6000_cost
->simultaneous_prefetches
);
2614 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2617 darwin_rs6000_override_options (void)
2619 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2621 rs6000_altivec_abi
= 1;
2622 TARGET_ALTIVEC_VRSAVE
= 1;
2624 if (DEFAULT_ABI
== ABI_DARWIN
2626 darwin_one_byte_bool
= 1;
2628 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
2630 target_flags
|= MASK_POWERPC64
;
2631 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2635 rs6000_default_long_calls
= 1;
2636 target_flags
|= MASK_SOFT_FLOAT
;
2639 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2641 if (!flag_mkernel
&& !flag_apple_kext
2643 && ! (target_flags_explicit
& MASK_ALTIVEC
))
2644 target_flags
|= MASK_ALTIVEC
;
2646 /* Unless the user (not the configurer) has explicitly overridden
2647 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2648 G4 unless targetting the kernel. */
2651 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
2652 && ! (target_flags_explicit
& MASK_ALTIVEC
)
2653 && ! rs6000_select
[1].string
)
2655 target_flags
|= MASK_ALTIVEC
;
2660 /* If not otherwise specified by a target, make 'long double' equivalent to
2663 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2664 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2667 /* Override command line options. Mostly we process the processor type and
2668 sometimes adjust other TARGET_ options. */
2671 rs6000_option_override_internal (bool global_init_p
)
2674 const char *default_cpu
= OPTION_TARGET_CPU_DEFAULT
;
2678 struct cl_target_option
*main_target_opt
2679 = ((global_init_p
|| target_option_default_node
== NULL
)
2680 ? NULL
: TREE_TARGET_OPTION (target_option_default_node
));
2682 /* Numerous experiment shows that IRA based loop pressure
2683 calculation works better for RTL loop invariant motion on targets
2684 with enough (>= 32) registers. It is an expensive optimization.
2685 So it is on only for peak performance. */
2686 if (optimize
>= 3 && global_init_p
)
2687 flag_ira_loop_pressure
= 1;
2689 /* Set the pointer size. */
2692 rs6000_pmode
= (int)DImode
;
2693 rs6000_pointer_size
= 64;
2697 rs6000_pmode
= (int)SImode
;
2698 rs6000_pointer_size
= 32;
2701 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
2702 #ifdef OS_MISSING_POWERPC64
2703 if (OS_MISSING_POWERPC64
)
2704 set_masks
&= ~MASK_POWERPC64
;
2706 #ifdef OS_MISSING_ALTIVEC
2707 if (OS_MISSING_ALTIVEC
)
2708 set_masks
&= ~MASK_ALTIVEC
;
2711 /* Don't override by the processor default if given explicitly. */
2712 set_masks
&= ~target_flags_explicit
;
2714 /* Identify the processor type. */
2717 if (TARGET_POWERPC64
)
2718 default_cpu
= "powerpc64";
2719 else if (TARGET_POWERPC
)
2720 default_cpu
= "powerpc";
2723 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2724 the cpu in a target attribute or pragma, but did not specify a tuning
2725 option, use the cpu for the tuning option rather than the option specified
2726 with -mtune on the command line. */
2727 if (rs6000_cpu_index
> 0)
2728 cpu_index
= rs6000_cpu_index
;
2729 else if (main_target_opt
!= NULL
&& main_target_opt
->x_rs6000_cpu_index
> 0)
2730 rs6000_cpu_index
= cpu_index
= main_target_opt
->x_rs6000_cpu_index
;
2732 rs6000_cpu_index
= cpu_index
= rs6000_cpu_name_lookup (default_cpu
);
2734 if (rs6000_tune_index
> 0)
2735 tune_index
= rs6000_tune_index
;
2737 rs6000_tune_index
= tune_index
= cpu_index
;
2741 target_flags
&= ~set_masks
;
2742 target_flags
|= (processor_target_table
[cpu_index
].target_enable
2746 rs6000_cpu
= ((tune_index
>= 0)
2747 ? processor_target_table
[tune_index
].processor
2749 ? PROCESSOR_DEFAULT64
2750 : PROCESSOR_DEFAULT
));
2752 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
2753 || rs6000_cpu
== PROCESSOR_PPCE500MC
|| rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2756 error ("AltiVec not supported in this target");
2758 error ("SPE not supported in this target");
2761 /* Disable Cell microcode if we are optimizing for the Cell
2762 and not optimizing for size. */
2763 if (rs6000_gen_cell_microcode
== -1)
2764 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
2767 /* If we are optimizing big endian systems for space and it's OK to
2768 use instructions that would be microcoded on the Cell, use the
2769 load/store multiple and string instructions. */
2770 if (BYTES_BIG_ENDIAN
&& optimize_size
&& rs6000_gen_cell_microcode
)
2771 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
2773 /* Don't allow -mmultiple or -mstring on little endian systems
2774 unless the cpu is a 750, because the hardware doesn't support the
2775 instructions used in little endian mode, and causes an alignment
2776 trap. The 750 does not cause an alignment trap (except when the
2777 target is unaligned). */
2779 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
2781 if (TARGET_MULTIPLE
)
2783 target_flags
&= ~MASK_MULTIPLE
;
2784 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
2785 warning (0, "-mmultiple is not supported on little endian systems");
2790 target_flags
&= ~MASK_STRING
;
2791 if ((target_flags_explicit
& MASK_STRING
) != 0)
2792 warning (0, "-mstring is not supported on little endian systems");
2796 /* Add some warnings for VSX. */
2799 const char *msg
= NULL
;
2800 if (!TARGET_HARD_FLOAT
|| !TARGET_FPRS
2801 || !TARGET_SINGLE_FLOAT
|| !TARGET_DOUBLE_FLOAT
)
2803 if (target_flags_explicit
& MASK_VSX
)
2804 msg
= N_("-mvsx requires hardware floating point");
2806 target_flags
&= ~ MASK_VSX
;
2808 else if (TARGET_PAIRED_FLOAT
)
2809 msg
= N_("-mvsx and -mpaired are incompatible");
2810 /* The hardware will allow VSX and little endian, but until we make sure
2811 things like vector select, etc. work don't allow VSX on little endian
2812 systems at this point. */
2813 else if (!BYTES_BIG_ENDIAN
)
2814 msg
= N_("-mvsx used with little endian code");
2815 else if (TARGET_AVOID_XFORM
> 0)
2816 msg
= N_("-mvsx needs indexed addressing");
2817 else if (!TARGET_ALTIVEC
&& (target_flags_explicit
& MASK_ALTIVEC
))
2819 if (target_flags_explicit
& MASK_VSX
)
2820 msg
= N_("-mvsx and -mno-altivec are incompatible");
2822 msg
= N_("-mno-altivec disables vsx");
2828 target_flags
&= ~ MASK_VSX
;
2829 target_flags_explicit
|= MASK_VSX
;
2833 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2834 unless the user explicitly used the -mno-<option> to disable the code. */
2836 target_flags
|= (ISA_2_6_MASKS_SERVER
& ~target_flags_explicit
);
2837 else if (TARGET_POPCNTD
)
2838 target_flags
|= (ISA_2_6_MASKS_EMBEDDED
& ~target_flags_explicit
);
2839 else if (TARGET_DFP
)
2840 target_flags
|= (ISA_2_5_MASKS_SERVER
& ~target_flags_explicit
);
2841 else if (TARGET_CMPB
)
2842 target_flags
|= (ISA_2_5_MASKS_EMBEDDED
& ~target_flags_explicit
);
2843 else if (TARGET_FPRND
)
2844 target_flags
|= (ISA_2_4_MASKS
& ~target_flags_explicit
);
2845 else if (TARGET_POPCNTB
)
2846 target_flags
|= (ISA_2_2_MASKS
& ~target_flags_explicit
);
2847 else if (TARGET_ALTIVEC
)
2848 target_flags
|= (MASK_PPC_GFXOPT
& ~target_flags_explicit
);
2850 /* E500mc does "better" if we inline more aggressively. Respect the
2851 user's opinion, though. */
2852 if (rs6000_block_move_inline_limit
== 0
2853 && (rs6000_cpu
== PROCESSOR_PPCE500MC
2854 || rs6000_cpu
== PROCESSOR_PPCE500MC64
))
2855 rs6000_block_move_inline_limit
= 128;
2857 /* store_one_arg depends on expand_block_move to handle at least the
2858 size of reg_parm_stack_space. */
2859 if (rs6000_block_move_inline_limit
< (TARGET_POWERPC64
? 64 : 32))
2860 rs6000_block_move_inline_limit
= (TARGET_POWERPC64
? 64 : 32);
2864 /* If the appropriate debug option is enabled, replace the target hooks
2865 with debug versions that call the real version and then prints
2866 debugging information. */
2867 if (TARGET_DEBUG_COST
)
2869 targetm
.rtx_costs
= rs6000_debug_rtx_costs
;
2870 targetm
.address_cost
= rs6000_debug_address_cost
;
2871 targetm
.sched
.adjust_cost
= rs6000_debug_adjust_cost
;
2874 if (TARGET_DEBUG_ADDR
)
2876 targetm
.legitimate_address_p
= rs6000_debug_legitimate_address_p
;
2877 targetm
.legitimize_address
= rs6000_debug_legitimize_address
;
2878 rs6000_secondary_reload_class_ptr
2879 = rs6000_debug_secondary_reload_class
;
2880 rs6000_secondary_memory_needed_ptr
2881 = rs6000_debug_secondary_memory_needed
;
2882 rs6000_cannot_change_mode_class_ptr
2883 = rs6000_debug_cannot_change_mode_class
;
2884 rs6000_preferred_reload_class_ptr
2885 = rs6000_debug_preferred_reload_class
;
2886 rs6000_legitimize_reload_address_ptr
2887 = rs6000_debug_legitimize_reload_address
;
2888 rs6000_mode_dependent_address_ptr
2889 = rs6000_debug_mode_dependent_address
;
2892 if (rs6000_veclibabi_name
)
2894 if (strcmp (rs6000_veclibabi_name
, "mass") == 0)
2895 rs6000_veclib_handler
= rs6000_builtin_vectorized_libmass
;
2898 error ("unknown vectorization library ABI type (%s) for "
2899 "-mveclibabi= switch", rs6000_veclibabi_name
);
2905 if (!rs6000_explicit_options
.long_double
)
2907 if (main_target_opt
!= NULL
2908 && (main_target_opt
->x_rs6000_long_double_type_size
2909 != RS6000_DEFAULT_LONG_DOUBLE_SIZE
))
2910 error ("target attribute or pragma changes long double size");
2912 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2915 #ifndef POWERPC_LINUX
2916 if (!rs6000_explicit_options
.ieee
)
2917 rs6000_ieeequad
= 1;
2920 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2921 target attribute or pragma which automatically enables both options,
2922 unless the altivec ABI was set. This is set by default for 64-bit, but
2924 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_altivec_abi
)
2925 target_flags
&= ~((MASK_VSX
| MASK_ALTIVEC
) & ~target_flags_explicit
);
2927 /* Enable Altivec ABI for AIX -maltivec. */
2928 if (TARGET_XCOFF
&& (TARGET_ALTIVEC
|| TARGET_VSX
))
2930 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_altivec_abi
)
2931 error ("target attribute or pragma changes AltiVec ABI");
2933 rs6000_altivec_abi
= 1;
2936 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2937 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2938 be explicitly overridden in either case. */
2941 if (!rs6000_explicit_options
.altivec_abi
2942 && (TARGET_64BIT
|| TARGET_ALTIVEC
|| TARGET_VSX
))
2944 if (main_target_opt
!= NULL
&&
2945 !main_target_opt
->x_rs6000_altivec_abi
)
2946 error ("target attribute or pragma changes AltiVec ABI");
2948 rs6000_altivec_abi
= 1;
2951 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2952 if (!rs6000_explicit_options
.vrsave
)
2953 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
2956 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2957 So far, the only darwin64 targets are also MACH-O. */
2959 && DEFAULT_ABI
== ABI_DARWIN
2962 if (main_target_opt
!= NULL
&& !main_target_opt
->x_rs6000_darwin64_abi
)
2963 error ("target attribute or pragma changes darwin64 ABI");
2966 rs6000_darwin64_abi
= 1;
2967 /* Default to natural alignment, for better performance. */
2968 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2972 /* Place FP constants in the constant pool instead of TOC
2973 if section anchors enabled. */
2974 if (flag_section_anchors
)
2975 TARGET_NO_FP_IN_TOC
= 1;
2977 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2978 SUBTARGET_OVERRIDE_OPTIONS
;
2980 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2981 SUBSUBTARGET_OVERRIDE_OPTIONS
;
2983 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2984 SUB3TARGET_OVERRIDE_OPTIONS
;
2987 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
2988 || rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2990 /* The e500 and e500mc do not have string instructions, and we set
2991 MASK_STRING above when optimizing for size. */
2992 if ((target_flags
& MASK_STRING
) != 0)
2993 target_flags
= target_flags
& ~MASK_STRING
;
2995 else if (rs6000_select
[1].string
!= NULL
)
2997 /* For the powerpc-eabispe configuration, we set all these by
2998 default, so let's unset them if we manually set another
2999 CPU that is not the E500. */
3000 if (main_target_opt
!= NULL
3001 && ((main_target_opt
->x_rs6000_spe_abi
!= rs6000_spe_abi
)
3002 || (main_target_opt
->x_rs6000_spe
!= rs6000_spe
)
3003 || (main_target_opt
->x_rs6000_float_gprs
!= rs6000_float_gprs
)))
3004 error ("target attribute or pragma changes SPE ABI");
3007 if (!rs6000_explicit_options
.spe_abi
)
3009 if (!rs6000_explicit_options
.spe
)
3011 if (!rs6000_explicit_options
.float_gprs
)
3012 rs6000_float_gprs
= 0;
3014 if (!(target_flags_explicit
& MASK_ISEL
))
3015 target_flags
&= ~MASK_ISEL
;
3018 /* Detect invalid option combinations with E500. */
3021 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
3022 && rs6000_cpu
!= PROCESSOR_POWER5
3023 && rs6000_cpu
!= PROCESSOR_POWER6
3024 && rs6000_cpu
!= PROCESSOR_POWER7
3025 && rs6000_cpu
!= PROCESSOR_PPCA2
3026 && rs6000_cpu
!= PROCESSOR_CELL
);
3027 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
3028 || rs6000_cpu
== PROCESSOR_POWER5
3029 || rs6000_cpu
== PROCESSOR_POWER7
);
3030 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
3031 || rs6000_cpu
== PROCESSOR_POWER5
3032 || rs6000_cpu
== PROCESSOR_POWER6
3033 || rs6000_cpu
== PROCESSOR_POWER7
3034 || rs6000_cpu
== PROCESSOR_PPCE500MC
3035 || rs6000_cpu
== PROCESSOR_PPCE500MC64
);
3037 /* Allow debug switches to override the above settings. These are set to -1
3038 in rs6000.opt to indicate the user hasn't directly set the switch. */
3039 if (TARGET_ALWAYS_HINT
>= 0)
3040 rs6000_always_hint
= TARGET_ALWAYS_HINT
;
3042 if (TARGET_SCHED_GROUPS
>= 0)
3043 rs6000_sched_groups
= TARGET_SCHED_GROUPS
;
3045 if (TARGET_ALIGN_BRANCH_TARGETS
>= 0)
3046 rs6000_align_branch_targets
= TARGET_ALIGN_BRANCH_TARGETS
;
3048 rs6000_sched_restricted_insns_priority
3049 = (rs6000_sched_groups
? 1 : 0);
3051 /* Handle -msched-costly-dep option. */
3052 rs6000_sched_costly_dep
3053 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
3055 if (rs6000_sched_costly_dep_str
)
3057 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
3058 rs6000_sched_costly_dep
= no_dep_costly
;
3059 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
3060 rs6000_sched_costly_dep
= all_deps_costly
;
3061 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
3062 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
3063 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
3064 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
3066 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
3067 atoi (rs6000_sched_costly_dep_str
));
3070 /* Handle -minsert-sched-nops option. */
3071 rs6000_sched_insert_nops
3072 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
3074 if (rs6000_sched_insert_nops_str
)
3076 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
3077 rs6000_sched_insert_nops
= sched_finish_none
;
3078 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
3079 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
3080 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
3081 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
3083 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
3084 atoi (rs6000_sched_insert_nops_str
));
3089 #ifdef TARGET_REGNAMES
3090 /* If the user desires alternate register names, copy in the
3091 alternate names now. */
3092 if (TARGET_REGNAMES
)
3093 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
3096 /* Set aix_struct_return last, after the ABI is determined.
3097 If -maix-struct-return or -msvr4-struct-return was explicitly
3098 used, don't override with the ABI default. */
3099 if (!rs6000_explicit_options
.aix_struct_ret
)
3100 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
3103 /* IBM XL compiler defaults to unsigned bitfields. */
3104 if (TARGET_XL_COMPAT
)
3105 flag_signed_bitfields
= 0;
3108 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
3109 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
3112 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
3114 /* We can only guarantee the availability of DI pseudo-ops when
3115 assembling for 64-bit targets. */
3118 targetm
.asm_out
.aligned_op
.di
= NULL
;
3119 targetm
.asm_out
.unaligned_op
.di
= NULL
;
3123 /* Set branch target alignment, if not optimizing for size. */
3126 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3127 aligned 8byte to avoid misprediction by the branch predictor. */
3128 if (rs6000_cpu
== PROCESSOR_TITAN
3129 || rs6000_cpu
== PROCESSOR_CELL
)
3131 if (align_functions
<= 0)
3132 align_functions
= 8;
3133 if (align_jumps
<= 0)
3135 if (align_loops
<= 0)
3138 if (rs6000_align_branch_targets
)
3140 if (align_functions
<= 0)
3141 align_functions
= 16;
3142 if (align_jumps
<= 0)
3144 if (align_loops
<= 0)
3146 can_override_loop_align
= 1;
3150 if (align_jumps_max_skip
<= 0)
3151 align_jumps_max_skip
= 15;
3152 if (align_loops_max_skip
<= 0)
3153 align_loops_max_skip
= 15;
3156 /* Arrange to save and restore machine status around nested functions. */
3157 init_machine_status
= rs6000_init_machine_status
;
3159 /* We should always be splitting complex arguments, but we can't break
3160 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3161 if (DEFAULT_ABI
!= ABI_AIX
)
3162 targetm
.calls
.split_complex_arg
= NULL
;
3165 /* Initialize rs6000_cost with the appropriate target costs. */
3167 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
3171 case PROCESSOR_RIOS1
:
3172 rs6000_cost
= &rios1_cost
;
3175 case PROCESSOR_RIOS2
:
3176 rs6000_cost
= &rios2_cost
;
3179 case PROCESSOR_RS64A
:
3180 rs6000_cost
= &rs64a_cost
;
3183 case PROCESSOR_MPCCORE
:
3184 rs6000_cost
= &mpccore_cost
;
3187 case PROCESSOR_PPC403
:
3188 rs6000_cost
= &ppc403_cost
;
3191 case PROCESSOR_PPC405
:
3192 rs6000_cost
= &ppc405_cost
;
3195 case PROCESSOR_PPC440
:
3196 rs6000_cost
= &ppc440_cost
;
3199 case PROCESSOR_PPC476
:
3200 rs6000_cost
= &ppc476_cost
;
3203 case PROCESSOR_PPC601
:
3204 rs6000_cost
= &ppc601_cost
;
3207 case PROCESSOR_PPC603
:
3208 rs6000_cost
= &ppc603_cost
;
3211 case PROCESSOR_PPC604
:
3212 rs6000_cost
= &ppc604_cost
;
3215 case PROCESSOR_PPC604e
:
3216 rs6000_cost
= &ppc604e_cost
;
3219 case PROCESSOR_PPC620
:
3220 rs6000_cost
= &ppc620_cost
;
3223 case PROCESSOR_PPC630
:
3224 rs6000_cost
= &ppc630_cost
;
3227 case PROCESSOR_CELL
:
3228 rs6000_cost
= &ppccell_cost
;
3231 case PROCESSOR_PPC750
:
3232 case PROCESSOR_PPC7400
:
3233 rs6000_cost
= &ppc750_cost
;
3236 case PROCESSOR_PPC7450
:
3237 rs6000_cost
= &ppc7450_cost
;
3240 case PROCESSOR_PPC8540
:
3241 rs6000_cost
= &ppc8540_cost
;
3244 case PROCESSOR_PPCE300C2
:
3245 case PROCESSOR_PPCE300C3
:
3246 rs6000_cost
= &ppce300c2c3_cost
;
3249 case PROCESSOR_PPCE500MC
:
3250 rs6000_cost
= &ppce500mc_cost
;
3253 case PROCESSOR_PPCE500MC64
:
3254 rs6000_cost
= &ppce500mc64_cost
;
3257 case PROCESSOR_TITAN
:
3258 rs6000_cost
= &titan_cost
;
3261 case PROCESSOR_POWER4
:
3262 case PROCESSOR_POWER5
:
3263 rs6000_cost
= &power4_cost
;
3266 case PROCESSOR_POWER6
:
3267 rs6000_cost
= &power6_cost
;
3270 case PROCESSOR_POWER7
:
3271 rs6000_cost
= &power7_cost
;
3274 case PROCESSOR_PPCA2
:
3275 rs6000_cost
= &ppca2_cost
;
3284 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES
,
3285 rs6000_cost
->simultaneous_prefetches
,
3286 global_options
.x_param_values
,
3287 global_options_set
.x_param_values
);
3288 maybe_set_param_value (PARAM_L1_CACHE_SIZE
, rs6000_cost
->l1_cache_size
,
3289 global_options
.x_param_values
,
3290 global_options_set
.x_param_values
);
3291 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE
,
3292 rs6000_cost
->cache_line_size
,
3293 global_options
.x_param_values
,
3294 global_options_set
.x_param_values
);
3295 maybe_set_param_value (PARAM_L2_CACHE_SIZE
, rs6000_cost
->l2_cache_size
,
3296 global_options
.x_param_values
,
3297 global_options_set
.x_param_values
);
3299 /* If using typedef char *va_list, signal that
3300 __builtin_va_start (&ap, 0) can be optimized to
3301 ap = __builtin_next_arg (0). */
3302 if (DEFAULT_ABI
!= ABI_V4
)
3303 targetm
.expand_builtin_va_start
= NULL
;
3306 /* Set up single/double float flags.
3307 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3308 then set both flags. */
3309 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
3310 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
3311 rs6000_single_float
= rs6000_double_float
= 1;
3313 /* Reset single and double FP flags if target is E500. */
3316 rs6000_single_float
= rs6000_double_float
= 0;
3317 if (TARGET_E500_SINGLE
)
3318 rs6000_single_float
= 1;
3319 if (TARGET_E500_DOUBLE
)
3320 rs6000_single_float
= rs6000_double_float
= 1;
3323 if (main_target_opt
)
3325 if (main_target_opt
->x_rs6000_single_float
!= rs6000_single_float
)
3326 error ("target attribute or pragma changes single precision floating "
3328 if (main_target_opt
->x_rs6000_double_float
!= rs6000_double_float
)
3329 error ("target attribute or pragma changes double precision floating "
3333 /* If not explicitly specified via option, decide whether to generate indexed
3334 load/store instructions. */
3335 if (TARGET_AVOID_XFORM
== -1)
3336 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3337 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3338 need indexed accesses and the type used is the scalar type of the element
3339 being loaded or stored. */
3340 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
3341 && !TARGET_ALTIVEC
);
3343 /* Set the -mrecip options. */
3344 if (rs6000_recip_name
)
3346 char *p
= ASTRDUP (rs6000_recip_name
);
3348 unsigned int mask
, i
;
3351 while ((q
= strtok (p
, ",")) != NULL
)
3362 if (!strcmp (q
, "default"))
3363 mask
= ((TARGET_RECIP_PRECISION
)
3364 ? RECIP_HIGH_PRECISION
: RECIP_LOW_PRECISION
);
3367 for (i
= 0; i
< ARRAY_SIZE (recip_options
); i
++)
3368 if (!strcmp (q
, recip_options
[i
].string
))
3370 mask
= recip_options
[i
].mask
;
3374 if (i
== ARRAY_SIZE (recip_options
))
3376 error ("unknown option for -mrecip=%s", q
);
3384 rs6000_recip_control
&= ~mask
;
3386 rs6000_recip_control
|= mask
;
3390 rs6000_init_hard_regno_mode_ok (global_init_p
);
3392 /* Save the initial options in case the user does function specific options */
3394 target_option_default_node
= target_option_current_node
3395 = build_target_option_node ();
3400 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3401 define the target cpu type. */
3404 rs6000_option_override (void)
3406 (void) rs6000_option_override_internal (true);
3410 /* Implement targetm.vectorize.builtin_mask_for_load. */
3412 rs6000_builtin_mask_for_load (void)
3414 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3415 return altivec_builtin_mask_for_load
;
3420 /* Implement LOOP_ALIGN. */
3422 rs6000_loop_align (rtx label
)
3427 /* Don't override loop alignment if -falign-loops was specified. */
3428 if (!can_override_loop_align
)
3429 return align_loops_log
;
3431 bb
= BLOCK_FOR_INSN (label
);
3432 ninsns
= num_loop_insns(bb
->loop_father
);
3434 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3435 if (ninsns
> 4 && ninsns
<= 8
3436 && (rs6000_cpu
== PROCESSOR_POWER4
3437 || rs6000_cpu
== PROCESSOR_POWER5
3438 || rs6000_cpu
== PROCESSOR_POWER6
3439 || rs6000_cpu
== PROCESSOR_POWER7
))
3442 return align_loops_log
;
3445 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3447 rs6000_loop_align_max_skip (rtx label
)
3449 return (1 << rs6000_loop_align (label
)) - 1;
3452 /* Implement targetm.vectorize.builtin_conversion.
3453 Returns a decl of a function that implements conversion of an integer vector
3454 into a floating-point vector, or vice-versa. DEST_TYPE is the
3455 destination type and SRC_TYPE the source type of the conversion.
3456 Return NULL_TREE if it is not available. */
3458 rs6000_builtin_conversion (unsigned int tcode
, tree dest_type
, tree src_type
)
3460 enum tree_code code
= (enum tree_code
) tcode
;
3464 case FIX_TRUNC_EXPR
:
3465 switch (TYPE_MODE (dest_type
))
3468 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3471 return TYPE_UNSIGNED (dest_type
)
3472 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPUXDS_UNS
]
3473 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPSXDS
];
3476 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3479 return TYPE_UNSIGNED (dest_type
)
3480 ? rs6000_builtin_decls
[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
]
3481 : rs6000_builtin_decls
[VECTOR_BUILTIN_FIX_V4SF_V4SI
];
3488 switch (TYPE_MODE (src_type
))
3491 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3494 return TYPE_UNSIGNED (src_type
)
3495 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVUXDDP
]
3496 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVSXDDP
];
3499 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3502 return TYPE_UNSIGNED (src_type
)
3503 ? rs6000_builtin_decls
[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
]
3504 : rs6000_builtin_decls
[VECTOR_BUILTIN_FLOAT_V4SI_V4SF
];
3515 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3517 rs6000_builtin_mul_widen_even (tree type
)
3519 if (!TARGET_ALTIVEC
)
3522 switch (TYPE_MODE (type
))
3525 return TYPE_UNSIGNED (type
)
3526 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH_UNS
]
3527 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
3530 return TYPE_UNSIGNED (type
)
3531 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB_UNS
]
3532 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
3538 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3540 rs6000_builtin_mul_widen_odd (tree type
)
3542 if (!TARGET_ALTIVEC
)
3545 switch (TYPE_MODE (type
))
3548 return TYPE_UNSIGNED (type
)
3549 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH_UNS
]
3550 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
3553 return TYPE_UNSIGNED (type
)
3554 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB_UNS
]
3555 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
3562 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3563 after applying N number of iterations. This routine does not determine
3564 how may iterations are required to reach desired alignment. */
3567 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
3574 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
3577 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
3587 /* Assuming that all other types are naturally aligned. CHECKME! */
3592 /* Return true if the vector misalignment factor is supported by the
3595 rs6000_builtin_support_vector_misalignment (enum machine_mode mode
,
3602 /* Return if movmisalign pattern is not supported for this mode. */
3603 if (optab_handler (movmisalign_optab
, mode
) == CODE_FOR_nothing
)
3606 if (misalignment
== -1)
3608 /* Misalignment factor is unknown at compile time but we know
3609 it's word aligned. */
3610 if (rs6000_vector_alignment_reachable (type
, is_packed
))
3612 int element_size
= TREE_INT_CST_LOW (TYPE_SIZE (type
));
3614 if (element_size
== 64 || element_size
== 32)
3621 /* VSX supports word-aligned vector. */
3622 if (misalignment
% 4 == 0)
3628 /* Implement targetm.vectorize.builtin_vec_perm. */
3630 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
3632 tree inner_type
= TREE_TYPE (type
);
3633 bool uns_p
= TYPE_UNSIGNED (inner_type
);
3636 *mask_element_type
= unsigned_char_type_node
;
3638 switch (TYPE_MODE (type
))
3642 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI_UNS
]
3643 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
]);
3648 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI_UNS
]
3649 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
]);
3654 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI_UNS
]
3655 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
]);
3659 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
3663 if (!TARGET_ALLOW_DF_PERMUTE
)
3666 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DF
];
3670 if (!TARGET_ALLOW_DF_PERMUTE
)
3674 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI_UNS
]
3675 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI
]);
3687 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3689 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost
,
3690 tree vectype
, int misalign
)
3694 switch (type_of_cost
)
3704 case cond_branch_not_taken
:
3708 case cond_branch_taken
:
3711 case unaligned_load
:
3712 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3714 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3716 /* Double word aligned. */
3724 /* Double word aligned. */
3728 /* Unknown misalignment. */
3741 /* Misaligned loads are not supported. */
3746 case unaligned_store
:
3747 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3749 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3751 /* Double word aligned. */
3759 /* Double word aligned. */
3763 /* Unknown misalignment. */
3776 /* Misaligned stores are not supported. */
3786 /* Implement targetm.vectorize.preferred_simd_mode. */
3788 static enum machine_mode
3789 rs6000_preferred_simd_mode (enum machine_mode mode
)
3798 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3822 if (TARGET_PAIRED_FLOAT
3828 /* Handle generic options of the form -mfoo=yes/no.
3829 NAME is the option name.
3830 VALUE is the option value.
3831 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3832 whether the option value is 'yes' or 'no' respectively. */
3834 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
3838 else if (!strcmp (value
, "yes"))
3840 else if (!strcmp (value
, "no"))
3843 error ("unknown -m%s= option specified: '%s'", name
, value
);
3846 /* Implement TARGET_OPTION_INIT_STRUCT. */
3849 rs6000_option_init_struct (struct gcc_options
*opts
)
3851 if (DEFAULT_ABI
== ABI_DARWIN
)
3852 /* The Darwin libraries never set errno, so we might as well
3853 avoid calling them when that's the only reason we would. */
3854 opts
->x_flag_errno_math
= 0;
3856 /* Enable section anchors by default. */
3858 opts
->x_flag_section_anchors
= 1;
3861 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3864 rs6000_option_default_params (void)
3866 /* Double growth factor to counter reduced min jump length. */
3867 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS
, 16);
3870 static enum fpu_type_t
3871 rs6000_parse_fpu_option (const char *option
)
3873 if (!strcmp("none", option
)) return FPU_NONE
;
3874 if (!strcmp("sp_lite", option
)) return FPU_SF_LITE
;
3875 if (!strcmp("dp_lite", option
)) return FPU_DF_LITE
;
3876 if (!strcmp("sp_full", option
)) return FPU_SF_FULL
;
3877 if (!strcmp("dp_full", option
)) return FPU_DF_FULL
;
3878 error("unknown value %s for -mfpu", option
);
3883 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3884 library with vectorized intrinsics. */
3887 rs6000_builtin_vectorized_libmass (tree fndecl
, tree type_out
, tree type_in
)
3890 const char *suffix
= NULL
;
3891 tree fntype
, new_fndecl
, bdecl
= NULL_TREE
;
3894 enum machine_mode el_mode
, in_mode
;
3897 /* Libmass is suitable for unsafe math only as it does not correctly support
3898 parts of IEEE with the required precision such as denormals. Only support
3899 it if we have VSX to use the simd d2 or f4 functions.
3900 XXX: Add variable length support. */
3901 if (!flag_unsafe_math_optimizations
|| !TARGET_VSX
)
3904 el_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3905 n
= TYPE_VECTOR_SUBPARTS (type_out
);
3906 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3907 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3908 if (el_mode
!= in_mode
3912 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3914 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3917 case BUILT_IN_ATAN2
:
3918 case BUILT_IN_HYPOT
:
3924 case BUILT_IN_ACOSH
:
3926 case BUILT_IN_ASINH
:
3928 case BUILT_IN_ATANH
:
3936 case BUILT_IN_EXPM1
:
3937 case BUILT_IN_LGAMMA
:
3938 case BUILT_IN_LOG10
:
3939 case BUILT_IN_LOG1P
:
3947 bdecl
= implicit_built_in_decls
[fn
];
3948 suffix
= "d2"; /* pow -> powd2 */
3949 if (el_mode
!= DFmode
3954 case BUILT_IN_ATAN2F
:
3955 case BUILT_IN_HYPOTF
:
3960 case BUILT_IN_ACOSF
:
3961 case BUILT_IN_ACOSHF
:
3962 case BUILT_IN_ASINF
:
3963 case BUILT_IN_ASINHF
:
3964 case BUILT_IN_ATANF
:
3965 case BUILT_IN_ATANHF
:
3966 case BUILT_IN_CBRTF
:
3968 case BUILT_IN_COSHF
:
3970 case BUILT_IN_ERFCF
:
3971 case BUILT_IN_EXP2F
:
3973 case BUILT_IN_EXPM1F
:
3974 case BUILT_IN_LGAMMAF
:
3975 case BUILT_IN_LOG10F
:
3976 case BUILT_IN_LOG1PF
:
3977 case BUILT_IN_LOG2F
:
3980 case BUILT_IN_SINHF
:
3981 case BUILT_IN_SQRTF
:
3983 case BUILT_IN_TANHF
:
3984 bdecl
= implicit_built_in_decls
[fn
];
3985 suffix
= "4"; /* powf -> powf4 */
3986 if (el_mode
!= SFmode
3998 gcc_assert (suffix
!= NULL
);
3999 bname
= IDENTIFIER_POINTER (DECL_NAME (bdecl
));
4000 strcpy (name
, bname
+ sizeof ("__builtin_") - 1);
4001 strcat (name
, suffix
);
4004 fntype
= build_function_type_list (type_out
, type_in
, NULL
);
4005 else if (n_args
== 2)
4006 fntype
= build_function_type_list (type_out
, type_in
, type_in
, NULL
);
4010 /* Build a function declaration for the vectorized function. */
4011 new_fndecl
= build_decl (BUILTINS_LOCATION
,
4012 FUNCTION_DECL
, get_identifier (name
), fntype
);
4013 TREE_PUBLIC (new_fndecl
) = 1;
4014 DECL_EXTERNAL (new_fndecl
) = 1;
4015 DECL_IS_NOVOPS (new_fndecl
) = 1;
4016 TREE_READONLY (new_fndecl
) = 1;
4021 /* Returns a function decl for a vectorized version of the builtin function
4022 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4023 if it is not available. */
4026 rs6000_builtin_vectorized_function (tree fndecl
, tree type_out
,
4029 enum machine_mode in_mode
, out_mode
;
4032 if (TREE_CODE (type_out
) != VECTOR_TYPE
4033 || TREE_CODE (type_in
) != VECTOR_TYPE
4034 || !TARGET_VECTORIZE_BUILTINS
)
4037 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
4038 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
4039 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
4040 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
4042 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
4044 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
4047 case BUILT_IN_COPYSIGN
:
4048 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4049 && out_mode
== DFmode
&& out_n
== 2
4050 && in_mode
== DFmode
&& in_n
== 2)
4051 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNDP
];
4053 case BUILT_IN_COPYSIGNF
:
4054 if (out_mode
!= SFmode
|| out_n
!= 4
4055 || in_mode
!= SFmode
|| in_n
!= 4)
4057 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4058 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNSP
];
4059 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4060 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_COPYSIGN_V4SF
];
4063 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4064 && out_mode
== DFmode
&& out_n
== 2
4065 && in_mode
== DFmode
&& in_n
== 2)
4066 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTDP
];
4068 case BUILT_IN_SQRTF
:
4069 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4070 && out_mode
== SFmode
&& out_n
== 4
4071 && in_mode
== SFmode
&& in_n
== 4)
4072 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTSP
];
4075 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4076 && out_mode
== DFmode
&& out_n
== 2
4077 && in_mode
== DFmode
&& in_n
== 2)
4078 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIP
];
4080 case BUILT_IN_CEILF
:
4081 if (out_mode
!= SFmode
|| out_n
!= 4
4082 || in_mode
!= SFmode
|| in_n
!= 4)
4084 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4085 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIP
];
4086 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4087 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIP
];
4089 case BUILT_IN_FLOOR
:
4090 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4091 && out_mode
== DFmode
&& out_n
== 2
4092 && in_mode
== DFmode
&& in_n
== 2)
4093 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIM
];
4095 case BUILT_IN_FLOORF
:
4096 if (out_mode
!= SFmode
|| out_n
!= 4
4097 || in_mode
!= SFmode
|| in_n
!= 4)
4099 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4100 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIM
];
4101 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4102 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIM
];
4105 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4106 && out_mode
== DFmode
&& out_n
== 2
4107 && in_mode
== DFmode
&& in_n
== 2)
4108 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDDP
];
4111 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4112 && out_mode
== SFmode
&& out_n
== 4
4113 && in_mode
== SFmode
&& in_n
== 4)
4114 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDSP
];
4115 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
)
4116 && out_mode
== SFmode
&& out_n
== 4
4117 && in_mode
== SFmode
&& in_n
== 4)
4118 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMADDFP
];
4120 case BUILT_IN_TRUNC
:
4121 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4122 && out_mode
== DFmode
&& out_n
== 2
4123 && in_mode
== DFmode
&& in_n
== 2)
4124 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIZ
];
4126 case BUILT_IN_TRUNCF
:
4127 if (out_mode
!= SFmode
|| out_n
!= 4
4128 || in_mode
!= SFmode
|| in_n
!= 4)
4130 if (VECTOR_UNIT_VSX_P (V4SFmode
))
4131 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIZ
];
4132 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
4133 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIZ
];
4135 case BUILT_IN_NEARBYINT
:
4136 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4137 && flag_unsafe_math_optimizations
4138 && out_mode
== DFmode
&& out_n
== 2
4139 && in_mode
== DFmode
&& in_n
== 2)
4140 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPI
];
4142 case BUILT_IN_NEARBYINTF
:
4143 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4144 && flag_unsafe_math_optimizations
4145 && out_mode
== SFmode
&& out_n
== 4
4146 && in_mode
== SFmode
&& in_n
== 4)
4147 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPI
];
4150 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4151 && !flag_trapping_math
4152 && out_mode
== DFmode
&& out_n
== 2
4153 && in_mode
== DFmode
&& in_n
== 2)
4154 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIC
];
4156 case BUILT_IN_RINTF
:
4157 if (VECTOR_UNIT_VSX_P (V4SFmode
)
4158 && !flag_trapping_math
4159 && out_mode
== SFmode
&& out_n
== 4
4160 && in_mode
== SFmode
&& in_n
== 4)
4161 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIC
];
4168 else if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4170 enum rs6000_builtins fn
4171 = (enum rs6000_builtins
)DECL_FUNCTION_CODE (fndecl
);
4174 case RS6000_BUILTIN_RSQRTF
:
4175 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
4176 && out_mode
== SFmode
&& out_n
== 4
4177 && in_mode
== SFmode
&& in_n
== 4)
4178 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRSQRTFP
];
4180 case RS6000_BUILTIN_RSQRT
:
4181 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4182 && out_mode
== DFmode
&& out_n
== 2
4183 && in_mode
== DFmode
&& in_n
== 2)
4184 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
4186 case RS6000_BUILTIN_RECIPF
:
4187 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
4188 && out_mode
== SFmode
&& out_n
== 4
4189 && in_mode
== SFmode
&& in_n
== 4)
4190 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRECIPFP
];
4192 case RS6000_BUILTIN_RECIP
:
4193 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4194 && out_mode
== DFmode
&& out_n
== 2
4195 && in_mode
== DFmode
&& in_n
== 2)
4196 return rs6000_builtin_decls
[VSX_BUILTIN_RECIP_V2DF
];
4203 /* Generate calls to libmass if appropriate. */
4204 if (rs6000_veclib_handler
)
4205 return rs6000_veclib_handler (fndecl
, type_out
, type_in
);
4211 /* Implement TARGET_HANDLE_OPTION. */
4214 rs6000_handle_option (struct gcc_options
*opts
, struct gcc_options
*opts_set
,
4215 const struct cl_decoded_option
*decoded
,
4216 location_t loc ATTRIBUTE_UNUSED
)
4218 enum fpu_type_t fpu_type
= FPU_NONE
;
4221 size_t code
= decoded
->opt_index
;
4222 const char *arg
= decoded
->arg
;
4223 int value
= decoded
->value
;
4225 gcc_assert (opts
== &global_options
);
4226 gcc_assert (opts_set
== &global_options_set
);
4231 target_flags
&= ~(MASK_POWER
| MASK_POWER2
4232 | MASK_MULTIPLE
| MASK_STRING
);
4233 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
4234 | MASK_MULTIPLE
| MASK_STRING
);
4236 case OPT_mno_powerpc
:
4237 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
4238 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
4239 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
4240 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
4243 target_flags
&= ~MASK_MINIMAL_TOC
;
4244 TARGET_NO_FP_IN_TOC
= 0;
4245 TARGET_NO_SUM_IN_TOC
= 0;
4246 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4247 #ifdef TARGET_USES_SYSV4_OPT
4248 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4249 just the same as -mminimal-toc. */
4250 target_flags
|= MASK_MINIMAL_TOC
;
4251 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4255 #ifdef TARGET_USES_SYSV4_OPT
4257 /* Make -mtoc behave like -mminimal-toc. */
4258 target_flags
|= MASK_MINIMAL_TOC
;
4259 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4263 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4265 if (strcmp (arg
, "small") == 0)
4266 rs6000_current_cmodel
= CMODEL_SMALL
;
4267 else if (strcmp (arg
, "medium") == 0)
4268 rs6000_current_cmodel
= CMODEL_MEDIUM
;
4269 else if (strcmp (arg
, "large") == 0)
4270 rs6000_current_cmodel
= CMODEL_LARGE
;
4273 error ("invalid option for -mcmodel: '%s'", arg
);
4276 rs6000_explicit_options
.cmodel
= true;
4279 #ifdef TARGET_USES_AIX64_OPT
4284 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
4285 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
4286 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
4289 #ifdef TARGET_USES_AIX64_OPT
4294 target_flags
&= ~MASK_POWERPC64
;
4295 target_flags_explicit
|= MASK_POWERPC64
;
4298 case OPT_minsert_sched_nops_
:
4299 rs6000_sched_insert_nops_str
= arg
;
4302 case OPT_mminimal_toc
:
4305 TARGET_NO_FP_IN_TOC
= 0;
4306 TARGET_NO_SUM_IN_TOC
= 0;
4313 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
4314 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
4321 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
4322 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
4326 case OPT_mpowerpc_gpopt
:
4327 case OPT_mpowerpc_gfxopt
:
4330 target_flags
|= MASK_POWERPC
;
4331 target_flags_explicit
|= MASK_POWERPC
;
4335 case OPT_maix_struct_return
:
4336 case OPT_msvr4_struct_return
:
4337 rs6000_explicit_options
.aix_struct_ret
= true;
4341 rs6000_explicit_options
.vrsave
= true;
4342 TARGET_ALTIVEC_VRSAVE
= value
;
4346 rs6000_explicit_options
.vrsave
= true;
4347 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
4351 target_flags_explicit
|= MASK_ISEL
;
4353 rs6000_parse_yes_no_option ("isel", arg
, &isel
);
4355 target_flags
|= MASK_ISEL
;
4357 target_flags
&= ~MASK_ISEL
;
4361 rs6000_explicit_options
.spe
= true;
4366 rs6000_explicit_options
.spe
= true;
4367 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
4374 while ((q
= strtok (p
, ",")) != NULL
)
4388 if (! strcmp (q
, "all"))
4389 mask
= MASK_DEBUG_ALL
;
4390 else if (! strcmp (q
, "stack"))
4391 mask
= MASK_DEBUG_STACK
;
4392 else if (! strcmp (q
, "arg"))
4393 mask
= MASK_DEBUG_ARG
;
4394 else if (! strcmp (q
, "reg"))
4395 mask
= MASK_DEBUG_REG
;
4396 else if (! strcmp (q
, "addr"))
4397 mask
= MASK_DEBUG_ADDR
;
4398 else if (! strcmp (q
, "cost"))
4399 mask
= MASK_DEBUG_COST
;
4400 else if (! strcmp (q
, "target"))
4401 mask
= MASK_DEBUG_TARGET
;
4403 error ("unknown -mdebug-%s switch", q
);
4406 rs6000_debug
&= ~mask
;
4408 rs6000_debug
|= mask
;
4412 #ifdef TARGET_USES_SYSV4_OPT
4414 rs6000_abi_name
= arg
;
4418 rs6000_sdata_name
= arg
;
4421 case OPT_mtls_size_
:
4422 if (strcmp (arg
, "16") == 0)
4423 rs6000_tls_size
= 16;
4424 else if (strcmp (arg
, "32") == 0)
4425 rs6000_tls_size
= 32;
4426 else if (strcmp (arg
, "64") == 0)
4427 rs6000_tls_size
= 64;
4429 error ("bad value %qs for -mtls-size switch", arg
);
4432 case OPT_mrelocatable
:
4435 target_flags
|= MASK_MINIMAL_TOC
;
4436 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4437 TARGET_NO_FP_IN_TOC
= 1;
4441 case OPT_mrelocatable_lib
:
4444 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4445 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4446 TARGET_NO_FP_IN_TOC
= 1;
4450 target_flags
&= ~MASK_RELOCATABLE
;
4451 target_flags_explicit
|= MASK_RELOCATABLE
;
4457 if (!strcmp (arg
, "altivec"))
4459 rs6000_explicit_options
.altivec_abi
= true;
4460 rs6000_altivec_abi
= 1;
4462 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4465 else if (! strcmp (arg
, "no-altivec"))
4467 rs6000_explicit_options
.altivec_abi
= true;
4468 rs6000_altivec_abi
= 0;
4470 else if (! strcmp (arg
, "spe"))
4472 rs6000_explicit_options
.spe_abi
= true;
4474 rs6000_altivec_abi
= 0;
4475 if (!TARGET_SPE_ABI
)
4476 error ("not configured for ABI: '%s'", arg
);
4478 else if (! strcmp (arg
, "no-spe"))
4480 rs6000_explicit_options
.spe_abi
= true;
4484 /* These are here for testing during development only, do not
4485 document in the manual please. */
4486 else if (! strcmp (arg
, "d64"))
4488 rs6000_darwin64_abi
= 1;
4489 warning (0, "using darwin64 ABI");
4491 else if (! strcmp (arg
, "d32"))
4493 rs6000_darwin64_abi
= 0;
4494 warning (0, "using old darwin ABI");
4497 else if (! strcmp (arg
, "ibmlongdouble"))
4499 rs6000_explicit_options
.ieee
= true;
4500 rs6000_ieeequad
= 0;
4501 warning (0, "using IBM extended precision long double");
4503 else if (! strcmp (arg
, "ieeelongdouble"))
4505 rs6000_explicit_options
.ieee
= true;
4506 rs6000_ieeequad
= 1;
4507 warning (0, "using IEEE extended precision long double");
4512 error ("unknown ABI specified: '%s'", arg
);
4518 rs6000_select
[1].string
= arg
;
4519 rs6000_cpu_index
= rs6000_cpu_name_lookup (arg
);
4520 if (rs6000_cpu_index
< 0)
4521 error ("bad value (%s) for -mcpu", arg
);
4525 rs6000_select
[2].string
= arg
;
4526 rs6000_tune_index
= rs6000_cpu_name_lookup (arg
);
4527 if (rs6000_tune_index
< 0)
4528 error ("bad value (%s) for -mtune", arg
);
4531 case OPT_mtraceback_
:
4532 if (! strncmp (arg
, "full", 4))
4533 rs6000_traceback
= traceback_full
;
4534 else if (! strncmp (arg
, "part", 4))
4535 rs6000_traceback
= traceback_part
;
4536 else if (! strncmp (arg
, "no", 2))
4537 rs6000_traceback
= traceback_none
;
4539 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4540 "%<partial%> or %<none%>", arg
);
4543 case OPT_mfloat_gprs_
:
4544 rs6000_explicit_options
.float_gprs
= true;
4545 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
4546 rs6000_float_gprs
= 1;
4547 else if (! strcmp (arg
, "double"))
4548 rs6000_float_gprs
= 2;
4549 else if (! strcmp (arg
, "no"))
4550 rs6000_float_gprs
= 0;
4553 error ("invalid option for -mfloat-gprs: '%s'", arg
);
4558 case OPT_mlong_double_
:
4559 rs6000_explicit_options
.long_double
= true;
4560 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
4561 if (value
!= 64 && value
!= 128)
4563 error ("unknown switch -mlong-double-%s", arg
);
4564 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
4568 rs6000_long_double_type_size
= value
;
4571 case OPT_msched_costly_dep_
:
4572 rs6000_sched_costly_dep_str
= arg
;
4576 rs6000_explicit_options
.alignment
= true;
4577 if (! strcmp (arg
, "power"))
4579 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4580 some C library functions, so warn about it. The flag may be
4581 useful for performance studies from time to time though, so
4582 don't disable it entirely. */
4583 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
4584 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4585 " it is incompatible with the installed C and C++ libraries");
4586 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
4588 else if (! strcmp (arg
, "natural"))
4589 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
4592 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
4597 case OPT_msingle_float
:
4598 if (!TARGET_SINGLE_FPU
)
4599 warning (0, "-msingle-float option equivalent to -mhard-float");
4600 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4601 rs6000_double_float
= 0;
4602 target_flags
&= ~MASK_SOFT_FLOAT
;
4603 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4606 case OPT_mdouble_float
:
4607 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4608 rs6000_single_float
= 1;
4609 target_flags
&= ~MASK_SOFT_FLOAT
;
4610 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4613 case OPT_msimple_fpu
:
4614 if (!TARGET_SINGLE_FPU
)
4615 warning (0, "-msimple-fpu option ignored");
4618 case OPT_mhard_float
:
4619 /* -mhard_float implies -msingle-float and -mdouble-float. */
4620 rs6000_single_float
= rs6000_double_float
= 1;
4623 case OPT_msoft_float
:
4624 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4625 rs6000_single_float
= rs6000_double_float
= 0;
4629 fpu_type
= rs6000_parse_fpu_option(arg
);
4630 if (fpu_type
!= FPU_NONE
)
4631 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4633 target_flags
&= ~MASK_SOFT_FLOAT
;
4634 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4635 rs6000_xilinx_fpu
= 1;
4636 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_SF_FULL
)
4637 rs6000_single_float
= 1;
4638 if (fpu_type
== FPU_DF_LITE
|| fpu_type
== FPU_DF_FULL
)
4639 rs6000_single_float
= rs6000_double_float
= 1;
4640 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_DF_LITE
)
4641 rs6000_simple_fpu
= 1;
4645 /* -mfpu=none is equivalent to -msoft-float */
4646 target_flags
|= MASK_SOFT_FLOAT
;
4647 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4648 rs6000_single_float
= rs6000_double_float
= 0;
4652 rs6000_recip_name
= (value
) ? "default" : "none";
4656 rs6000_recip_name
= arg
;
4662 /* Do anything needed at the start of the asm file. */
4665 rs6000_file_start (void)
4669 const char *start
= buffer
;
4670 struct rs6000_cpu_select
*ptr
;
4671 const char *default_cpu
= TARGET_CPU_DEFAULT
;
4672 FILE *file
= asm_out_file
;
4674 default_file_start ();
4676 #ifdef TARGET_BI_ARCH
4677 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
4681 if (flag_verbose_asm
)
4683 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
4684 rs6000_select
[0].string
= default_cpu
;
4686 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
4688 ptr
= &rs6000_select
[i
];
4689 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
4691 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
4696 if (PPC405_ERRATUM77
)
4698 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
4702 #ifdef USING_ELFOS_H
4703 switch (rs6000_sdata
)
4705 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
4706 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
4707 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
4708 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
4711 if (rs6000_sdata
&& g_switch_value
)
4713 fprintf (file
, "%s -G %d", start
,
4723 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
4725 switch_to_section (toc_section
);
4726 switch_to_section (text_section
);
4731 /* Return nonzero if this function is known to have a null epilogue. */
4734 direct_return (void)
4736 if (reload_completed
)
4738 rs6000_stack_t
*info
= rs6000_stack_info ();
4740 if (info
->first_gp_reg_save
== 32
4741 && info
->first_fp_reg_save
== 64
4742 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
4743 && ! info
->lr_save_p
4744 && ! info
->cr_save_p
4745 && info
->vrsave_mask
== 0
4753 /* Return the number of instructions it takes to form a constant in an
4754 integer register. */
4757 num_insns_constant_wide (HOST_WIDE_INT value
)
4759 /* signed constant loadable with {cal|addi} */
4760 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
4763 /* constant loadable with {cau|addis} */
4764 else if ((value
& 0xffff) == 0
4765 && (value
>> 31 == -1 || value
>> 31 == 0))
4768 #if HOST_BITS_PER_WIDE_INT == 64
4769 else if (TARGET_POWERPC64
)
4771 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
4772 HOST_WIDE_INT high
= value
>> 31;
4774 if (high
== 0 || high
== -1)
4780 return num_insns_constant_wide (high
) + 1;
4782 return num_insns_constant_wide (low
) + 1;
4784 return (num_insns_constant_wide (high
)
4785 + num_insns_constant_wide (low
) + 1);
4794 num_insns_constant (rtx op
, enum machine_mode mode
)
4796 HOST_WIDE_INT low
, high
;
4798 switch (GET_CODE (op
))
4801 #if HOST_BITS_PER_WIDE_INT == 64
4802 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
4803 && mask64_operand (op
, mode
))
4807 return num_insns_constant_wide (INTVAL (op
));
4810 if (mode
== SFmode
|| mode
== SDmode
)
4815 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4816 if (DECIMAL_FLOAT_MODE_P (mode
))
4817 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
4819 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
4820 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
4823 if (mode
== VOIDmode
|| mode
== DImode
)
4825 high
= CONST_DOUBLE_HIGH (op
);
4826 low
= CONST_DOUBLE_LOW (op
);
4833 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4834 if (DECIMAL_FLOAT_MODE_P (mode
))
4835 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
4837 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
4838 high
= l
[WORDS_BIG_ENDIAN
== 0];
4839 low
= l
[WORDS_BIG_ENDIAN
!= 0];
4843 return (num_insns_constant_wide (low
)
4844 + num_insns_constant_wide (high
));
4847 if ((high
== 0 && low
>= 0)
4848 || (high
== -1 && low
< 0))
4849 return num_insns_constant_wide (low
);
4851 else if (mask64_operand (op
, mode
))
4855 return num_insns_constant_wide (high
) + 1;
4858 return (num_insns_constant_wide (high
)
4859 + num_insns_constant_wide (low
) + 1);
4867 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4868 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4869 corresponding element of the vector, but for V4SFmode and V2SFmode,
4870 the corresponding "float" is interpreted as an SImode integer. */
4873 const_vector_elt_as_int (rtx op
, unsigned int elt
)
4877 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4878 gcc_assert (GET_MODE (op
) != V2DImode
4879 && GET_MODE (op
) != V2DFmode
);
4881 tmp
= CONST_VECTOR_ELT (op
, elt
);
4882 if (GET_MODE (op
) == V4SFmode
4883 || GET_MODE (op
) == V2SFmode
)
4884 tmp
= gen_lowpart (SImode
, tmp
);
4885 return INTVAL (tmp
);
4888 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4889 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4890 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4891 all items are set to the same value and contain COPIES replicas of the
4892 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4893 operand and the others are set to the value of the operand's msb. */
4896 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
4898 enum machine_mode mode
= GET_MODE (op
);
4899 enum machine_mode inner
= GET_MODE_INNER (mode
);
4907 HOST_WIDE_INT splat_val
;
4908 HOST_WIDE_INT msb_val
;
4910 if (mode
== V2DImode
|| mode
== V2DFmode
)
4913 nunits
= GET_MODE_NUNITS (mode
);
4914 bitsize
= GET_MODE_BITSIZE (inner
);
4915 mask
= GET_MODE_MASK (inner
);
4917 val
= const_vector_elt_as_int (op
, nunits
- 1);
4919 msb_val
= val
> 0 ? 0 : -1;
4921 /* Construct the value to be splatted, if possible. If not, return 0. */
4922 for (i
= 2; i
<= copies
; i
*= 2)
4924 HOST_WIDE_INT small_val
;
4926 small_val
= splat_val
>> bitsize
;
4928 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
4930 splat_val
= small_val
;
4933 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4934 if (EASY_VECTOR_15 (splat_val
))
4937 /* Also check if we can splat, and then add the result to itself. Do so if
4938 the value is positive, of if the splat instruction is using OP's mode;
4939 for splat_val < 0, the splat and the add should use the same mode. */
4940 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
4941 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
4944 /* Also check if are loading up the most significant bit which can be done by
4945 loading up -1 and shifting the value left by -1. */
4946 else if (EASY_VECTOR_MSB (splat_val
, inner
))
4952 /* Check if VAL is present in every STEP-th element, and the
4953 other elements are filled with its most significant bit. */
4954 for (i
= 0; i
< nunits
- 1; ++i
)
4956 HOST_WIDE_INT desired_val
;
4957 if (((i
+ 1) & (step
- 1)) == 0)
4960 desired_val
= msb_val
;
4962 if (desired_val
!= const_vector_elt_as_int (op
, i
))
4970 /* Return true if OP is of the given MODE and can be synthesized
4971 with a vspltisb, vspltish or vspltisw. */
4974 easy_altivec_constant (rtx op
, enum machine_mode mode
)
4976 unsigned step
, copies
;
4978 if (mode
== VOIDmode
)
4979 mode
= GET_MODE (op
);
4980 else if (mode
!= GET_MODE (op
))
4983 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4985 if (mode
== V2DFmode
)
4986 return zero_constant (op
, mode
);
4988 if (mode
== V2DImode
)
4990 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4992 if (GET_CODE (CONST_VECTOR_ELT (op
, 0)) != CONST_INT
4993 || GET_CODE (CONST_VECTOR_ELT (op
, 1)) != CONST_INT
)
4996 if (zero_constant (op
, mode
))
4999 if (INTVAL (CONST_VECTOR_ELT (op
, 0)) == -1
5000 && INTVAL (CONST_VECTOR_ELT (op
, 1)) == -1)
5006 /* Start with a vspltisw. */
5007 step
= GET_MODE_NUNITS (mode
) / 4;
5010 if (vspltis_constant (op
, step
, copies
))
5013 /* Then try with a vspltish. */
5019 if (vspltis_constant (op
, step
, copies
))
5022 /* And finally a vspltisb. */
5028 if (vspltis_constant (op
, step
, copies
))
5034 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
5035 result is OP. Abort if it is not possible. */
5038 gen_easy_altivec_constant (rtx op
)
5040 enum machine_mode mode
= GET_MODE (op
);
5041 int nunits
= GET_MODE_NUNITS (mode
);
5042 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
5043 unsigned step
= nunits
/ 4;
5044 unsigned copies
= 1;
5046 /* Start with a vspltisw. */
5047 if (vspltis_constant (op
, step
, copies
))
5048 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
5050 /* Then try with a vspltish. */
5056 if (vspltis_constant (op
, step
, copies
))
5057 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
5059 /* And finally a vspltisb. */
5065 if (vspltis_constant (op
, step
, copies
))
5066 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
5072 output_vec_const_move (rtx
*operands
)
5075 enum machine_mode mode
;
5080 mode
= GET_MODE (dest
);
5084 if (zero_constant (vec
, mode
))
5085 return "xxlxor %x0,%x0,%x0";
5087 if (mode
== V2DImode
5088 && INTVAL (CONST_VECTOR_ELT (vec
, 0)) == -1
5089 && INTVAL (CONST_VECTOR_ELT (vec
, 1)) == -1)
5090 return "vspltisw %0,-1";
5096 if (zero_constant (vec
, mode
))
5097 return "vxor %0,%0,%0";
5099 splat_vec
= gen_easy_altivec_constant (vec
);
5100 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
5101 operands
[1] = XEXP (splat_vec
, 0);
5102 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
5105 switch (GET_MODE (splat_vec
))
5108 return "vspltisw %0,%1";
5111 return "vspltish %0,%1";
5114 return "vspltisb %0,%1";
5121 gcc_assert (TARGET_SPE
);
5123 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5124 pattern of V1DI, V4HI, and V2SF.
5126 FIXME: We should probably return # and add post reload
5127 splitters for these, but this way is so easy ;-). */
5128 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
5129 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
5130 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
5131 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
5133 return "li %0,%1\n\tevmergelo %0,%0,%0";
5135 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5138 /* Initialize TARGET of vector PAIRED to VALS. */
5141 paired_expand_vector_init (rtx target
, rtx vals
)
5143 enum machine_mode mode
= GET_MODE (target
);
5144 int n_elts
= GET_MODE_NUNITS (mode
);
5146 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
5149 for (i
= 0; i
< n_elts
; ++i
)
5151 x
= XVECEXP (vals
, 0, i
);
5152 if (!CONSTANT_P (x
))
5157 /* Load from constant pool. */
5158 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
5164 /* The vector is initialized only with non-constants. */
5165 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
5166 XVECEXP (vals
, 0, 1));
5168 emit_move_insn (target
, new_rtx
);
5172 /* One field is non-constant and the other one is a constant. Load the
5173 constant from the constant pool and use ps_merge instruction to
5174 construct the whole vector. */
5175 op1
= XVECEXP (vals
, 0, 0);
5176 op2
= XVECEXP (vals
, 0, 1);
5178 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
5180 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
5181 emit_move_insn (tmp
, constant_op
);
5183 if (CONSTANT_P (op1
))
5184 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
5186 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
5188 emit_move_insn (target
, new_rtx
);
5192 paired_expand_vector_move (rtx operands
[])
5194 rtx op0
= operands
[0], op1
= operands
[1];
5196 emit_move_insn (op0
, op1
);
5199 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5200 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5201 operands for the relation operation COND. This is a recursive
5205 paired_emit_vector_compare (enum rtx_code rcode
,
5206 rtx dest
, rtx op0
, rtx op1
,
5207 rtx cc_op0
, rtx cc_op1
)
5209 rtx tmp
= gen_reg_rtx (V2SFmode
);
5212 gcc_assert (TARGET_PAIRED_FLOAT
);
5213 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
5219 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5223 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
5224 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
5228 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
5231 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5234 tmp1
= gen_reg_rtx (V2SFmode
);
5235 max
= gen_reg_rtx (V2SFmode
);
5236 min
= gen_reg_rtx (V2SFmode
);
5237 gen_reg_rtx (V2SFmode
);
5239 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
5240 emit_insn (gen_selv2sf4
5241 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
5242 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
5243 emit_insn (gen_selv2sf4
5244 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
5245 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
5246 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
5249 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5252 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5255 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5258 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5261 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5270 /* Emit vector conditional expression.
5271 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5272 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5275 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
5276 rtx cond
, rtx cc_op0
, rtx cc_op1
)
5278 enum rtx_code rcode
= GET_CODE (cond
);
5280 if (!TARGET_PAIRED_FLOAT
)
5283 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
5288 /* Initialize vector TARGET to VALS. */
5291 rs6000_expand_vector_init (rtx target
, rtx vals
)
5293 enum machine_mode mode
= GET_MODE (target
);
5294 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5295 int n_elts
= GET_MODE_NUNITS (mode
);
5296 int n_var
= 0, one_var
= -1;
5297 bool all_same
= true, all_const_zero
= true;
5301 for (i
= 0; i
< n_elts
; ++i
)
5303 x
= XVECEXP (vals
, 0, i
);
5304 if (!CONSTANT_P (x
))
5305 ++n_var
, one_var
= i
;
5306 else if (x
!= CONST0_RTX (inner_mode
))
5307 all_const_zero
= false;
5309 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
5315 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
5316 bool int_vector_p
= (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
5317 if ((int_vector_p
|| TARGET_VSX
) && all_const_zero
)
5319 /* Zero register. */
5320 emit_insn (gen_rtx_SET (VOIDmode
, target
,
5321 gen_rtx_XOR (mode
, target
, target
)));
5324 else if (int_vector_p
&& easy_vector_constant (const_vec
, mode
))
5326 /* Splat immediate. */
5327 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
5332 /* Load from constant pool. */
5333 emit_move_insn (target
, const_vec
);
5338 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5339 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5343 rtx element
= XVECEXP (vals
, 0, 0);
5344 if (mode
== V2DFmode
)
5345 emit_insn (gen_vsx_splat_v2df (target
, element
));
5347 emit_insn (gen_vsx_splat_v2di (target
, element
));
5351 if (mode
== V2DFmode
)
5353 rtx op0
= copy_to_mode_reg (DFmode
, XVECEXP (vals
, 0, 0));
5354 rtx op1
= copy_to_mode_reg (DFmode
, XVECEXP (vals
, 0, 1));
5355 emit_insn (gen_vsx_concat_v2df (target
, op0
, op1
));
5359 rtx op0
= copy_to_mode_reg (DImode
, XVECEXP (vals
, 0, 0));
5360 rtx op1
= copy_to_mode_reg (DImode
, XVECEXP (vals
, 0, 1));
5361 emit_insn (gen_vsx_concat_v2di (target
, op0
, op1
));
5367 /* With single precision floating point on VSX, know that internally single
5368 precision is actually represented as a double, and either make 2 V2DF
5369 vectors, and convert these vectors to single precision, or do one
5370 conversion, and splat the result to the other elements. */
5371 if (mode
== V4SFmode
&& VECTOR_MEM_VSX_P (mode
))
5375 rtx freg
= gen_reg_rtx (V4SFmode
);
5376 rtx sreg
= copy_to_reg (XVECEXP (vals
, 0, 0));
5378 emit_insn (gen_vsx_xscvdpsp_scalar (freg
, sreg
));
5379 emit_insn (gen_vsx_xxspltw_v4sf (target
, freg
, const0_rtx
));
5383 rtx dbl_even
= gen_reg_rtx (V2DFmode
);
5384 rtx dbl_odd
= gen_reg_rtx (V2DFmode
);
5385 rtx flt_even
= gen_reg_rtx (V4SFmode
);
5386 rtx flt_odd
= gen_reg_rtx (V4SFmode
);
5388 emit_insn (gen_vsx_concat_v2sf (dbl_even
,
5389 copy_to_reg (XVECEXP (vals
, 0, 0)),
5390 copy_to_reg (XVECEXP (vals
, 0, 1))));
5391 emit_insn (gen_vsx_concat_v2sf (dbl_odd
,
5392 copy_to_reg (XVECEXP (vals
, 0, 2)),
5393 copy_to_reg (XVECEXP (vals
, 0, 3))));
5394 emit_insn (gen_vsx_xvcvdpsp (flt_even
, dbl_even
));
5395 emit_insn (gen_vsx_xvcvdpsp (flt_odd
, dbl_odd
));
5396 emit_insn (gen_vec_extract_evenv4sf (target
, flt_even
, flt_odd
));
5401 /* Store value to stack temp. Load vector element. Splat. However, splat
5402 of 64-bit items is not supported on Altivec. */
5403 if (all_same
&& GET_MODE_SIZE (mode
) <= 4)
5405 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5406 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
5407 XVECEXP (vals
, 0, 0));
5408 x
= gen_rtx_UNSPEC (VOIDmode
,
5409 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5410 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5412 gen_rtx_SET (VOIDmode
,
5415 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
5416 gen_rtx_PARALLEL (VOIDmode
,
5417 gen_rtvec (1, const0_rtx
)));
5418 emit_insn (gen_rtx_SET (VOIDmode
, target
,
5419 gen_rtx_VEC_DUPLICATE (mode
, x
)));
5423 /* One field is non-constant. Load constant then overwrite
5427 rtx copy
= copy_rtx (vals
);
5429 /* Load constant part of vector, substitute neighboring value for
5431 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
5432 rs6000_expand_vector_init (target
, copy
);
5434 /* Insert variable. */
5435 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
5439 /* Construct the vector in memory one field at a time
5440 and load the whole vector. */
5441 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5442 for (i
= 0; i
< n_elts
; i
++)
5443 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
5444 i
* GET_MODE_SIZE (inner_mode
)),
5445 XVECEXP (vals
, 0, i
));
5446 emit_move_insn (target
, mem
);
5449 /* Set field ELT of TARGET to VAL. */
5452 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
5454 enum machine_mode mode
= GET_MODE (target
);
5455 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5456 rtx reg
= gen_reg_rtx (mode
);
5458 int width
= GET_MODE_SIZE (inner_mode
);
5461 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5463 rtx (*set_func
) (rtx
, rtx
, rtx
, rtx
)
5464 = ((mode
== V2DFmode
) ? gen_vsx_set_v2df
: gen_vsx_set_v2di
);
5465 emit_insn (set_func (target
, target
, val
, GEN_INT (elt
)));
5469 /* Load single variable value. */
5470 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5471 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
5472 x
= gen_rtx_UNSPEC (VOIDmode
,
5473 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5474 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5476 gen_rtx_SET (VOIDmode
,
5480 /* Linear sequence. */
5481 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
5482 for (i
= 0; i
< 16; ++i
)
5483 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
5485 /* Set permute mask to insert element into target. */
5486 for (i
= 0; i
< width
; ++i
)
5487 XVECEXP (mask
, 0, elt
*width
+ i
)
5488 = GEN_INT (i
+ 0x10);
5489 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
5490 x
= gen_rtx_UNSPEC (mode
,
5491 gen_rtvec (3, target
, reg
,
5492 force_reg (V16QImode
, x
)),
5494 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
5497 /* Extract field ELT from VEC into TARGET. */
5500 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
5502 enum machine_mode mode
= GET_MODE (vec
);
5503 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5506 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5508 rtx (*extract_func
) (rtx
, rtx
, rtx
)
5509 = ((mode
== V2DFmode
) ? gen_vsx_extract_v2df
: gen_vsx_extract_v2di
);
5510 emit_insn (extract_func (target
, vec
, GEN_INT (elt
)));
5514 /* Allocate mode-sized buffer. */
5515 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5517 emit_move_insn (mem
, vec
);
5519 /* Add offset to field within buffer matching vector element. */
5520 mem
= adjust_address_nv (mem
, inner_mode
, elt
* GET_MODE_SIZE (inner_mode
));
5522 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
5525 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5526 implement ANDing by the mask IN. */
5528 build_mask64_2_operands (rtx in
, rtx
*out
)
5530 #if HOST_BITS_PER_WIDE_INT >= 64
5531 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
5534 gcc_assert (GET_CODE (in
) == CONST_INT
);
5539 /* Assume c initially something like 0x00fff000000fffff. The idea
5540 is to rotate the word so that the middle ^^^^^^ group of zeros
5541 is at the MS end and can be cleared with an rldicl mask. We then
5542 rotate back and clear off the MS ^^ group of zeros with a
5544 c
= ~c
; /* c == 0xff000ffffff00000 */
5545 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
5546 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
5547 c
= ~c
; /* c == 0x00fff000000fffff */
5548 c
&= -lsb
; /* c == 0x00fff00000000000 */
5549 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5550 c
= ~c
; /* c == 0xff000fffffffffff */
5551 c
&= -lsb
; /* c == 0xff00000000000000 */
5553 while ((lsb
>>= 1) != 0)
5554 shift
++; /* shift == 44 on exit from loop */
5555 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
5556 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
5557 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
5561 /* Assume c initially something like 0xff000f0000000000. The idea
5562 is to rotate the word so that the ^^^ middle group of zeros
5563 is at the LS end and can be cleared with an rldicr mask. We then
5564 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5566 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
5567 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
5568 c
= ~c
; /* c == 0x00fff0ffffffffff */
5569 c
&= -lsb
; /* c == 0x00fff00000000000 */
5570 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5571 c
= ~c
; /* c == 0xff000fffffffffff */
5572 c
&= -lsb
; /* c == 0xff00000000000000 */
5574 while ((lsb
>>= 1) != 0)
5575 shift
++; /* shift == 44 on exit from loop */
5576 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
5577 m1
>>= shift
; /* m1 == 0x0000000000000fff */
5578 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
5581 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5582 masks will be all 1's. We are guaranteed more than one transition. */
5583 out
[0] = GEN_INT (64 - shift
);
5584 out
[1] = GEN_INT (m1
);
5585 out
[2] = GEN_INT (shift
);
5586 out
[3] = GEN_INT (m2
);
5594 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5597 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
5599 if (TARGET_E500_DOUBLE
)
5601 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5602 subreg:TI and reg:TF. Decimal float modes are like integer
5603 modes (only low part of each register used) for this
5605 if (GET_CODE (op
) == SUBREG
5606 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
5607 || mode
== DDmode
|| mode
== TDmode
)
5608 && REG_P (SUBREG_REG (op
))
5609 && (GET_MODE (SUBREG_REG (op
)) == DFmode
5610 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
5613 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5615 if (GET_CODE (op
) == SUBREG
5616 && (mode
== DFmode
|| mode
== TFmode
)
5617 && REG_P (SUBREG_REG (op
))
5618 && (GET_MODE (SUBREG_REG (op
)) == DImode
5619 || GET_MODE (SUBREG_REG (op
)) == TImode
5620 || GET_MODE (SUBREG_REG (op
)) == DDmode
5621 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
5626 && GET_CODE (op
) == SUBREG
5628 && REG_P (SUBREG_REG (op
))
5629 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
5635 /* AIX increases natural record alignment to doubleword if the first
5636 field is an FP double while the FP fields remain word aligned. */
5639 rs6000_special_round_type_align (tree type
, unsigned int computed
,
5640 unsigned int specified
)
5642 unsigned int align
= MAX (computed
, specified
);
5643 tree field
= TYPE_FIELDS (type
);
5645 /* Skip all non field decls */
5646 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5647 field
= DECL_CHAIN (field
);
5649 if (field
!= NULL
&& field
!= type
)
5651 type
= TREE_TYPE (field
);
5652 while (TREE_CODE (type
) == ARRAY_TYPE
)
5653 type
= TREE_TYPE (type
);
5655 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
5656 align
= MAX (align
, 64);
5662 /* Darwin increases record alignment to the natural alignment of
5666 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
5667 unsigned int specified
)
5669 unsigned int align
= MAX (computed
, specified
);
5671 if (TYPE_PACKED (type
))
5674 /* Find the first field, looking down into aggregates. */
5676 tree field
= TYPE_FIELDS (type
);
5677 /* Skip all non field decls */
5678 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5679 field
= DECL_CHAIN (field
);
5682 /* A packed field does not contribute any extra alignment. */
5683 if (DECL_PACKED (field
))
5685 type
= TREE_TYPE (field
);
5686 while (TREE_CODE (type
) == ARRAY_TYPE
)
5687 type
= TREE_TYPE (type
);
5688 } while (AGGREGATE_TYPE_P (type
));
5690 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
5691 align
= MAX (align
, TYPE_ALIGN (type
));
5696 /* Return 1 for an operand in small memory on V.4/eabi. */
5699 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
5700 enum machine_mode mode ATTRIBUTE_UNUSED
)
5705 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
5708 if (DEFAULT_ABI
!= ABI_V4
)
5711 /* Vector and float memory instructions have a limited offset on the
5712 SPE, so using a vector or float variable directly as an operand is
5715 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
5718 if (GET_CODE (op
) == SYMBOL_REF
)
5721 else if (GET_CODE (op
) != CONST
5722 || GET_CODE (XEXP (op
, 0)) != PLUS
5723 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
5724 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
5729 rtx sum
= XEXP (op
, 0);
5730 HOST_WIDE_INT summand
;
5732 /* We have to be careful here, because it is the referenced address
5733 that must be 32k from _SDA_BASE_, not just the symbol. */
5734 summand
= INTVAL (XEXP (sum
, 1));
5735 if (summand
< 0 || summand
> g_switch_value
)
5738 sym_ref
= XEXP (sum
, 0);
5741 return SYMBOL_REF_SMALL_P (sym_ref
);
5747 /* Return true if either operand is a general purpose register. */
5750 gpr_or_gpr_p (rtx op0
, rtx op1
)
5752 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
5753 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
5757 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5760 reg_offset_addressing_ok_p (enum machine_mode mode
)
5770 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5771 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
5779 /* Paired vector modes. Only reg+reg addressing is valid. */
5780 if (TARGET_PAIRED_FLOAT
)
5792 virtual_stack_registers_memory_p (rtx op
)
5796 if (GET_CODE (op
) == REG
)
5797 regnum
= REGNO (op
);
5799 else if (GET_CODE (op
) == PLUS
5800 && GET_CODE (XEXP (op
, 0)) == REG
5801 && GET_CODE (XEXP (op
, 1)) == CONST_INT
)
5802 regnum
= REGNO (XEXP (op
, 0));
5807 return (regnum
>= FIRST_VIRTUAL_REGISTER
5808 && regnum
<= LAST_VIRTUAL_POINTER_REGISTER
);
5811 /* Return true if memory accesses to OP are known to never straddle
5815 offsettable_ok_by_alignment (rtx op
, HOST_WIDE_INT offset
,
5816 enum machine_mode mode
)
5819 unsigned HOST_WIDE_INT dsize
, dalign
;
5821 if (GET_CODE (op
) != SYMBOL_REF
)
5824 decl
= SYMBOL_REF_DECL (op
);
5827 if (GET_MODE_SIZE (mode
) == 0)
5830 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5831 replacing memory addresses with an anchor plus offset. We
5832 could find the decl by rummaging around in the block->objects
5833 VEC for the given offset but that seems like too much work. */
5835 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op
)
5836 && SYMBOL_REF_ANCHOR_P (op
)
5837 && SYMBOL_REF_BLOCK (op
) != NULL
)
5839 struct object_block
*block
= SYMBOL_REF_BLOCK (op
);
5840 HOST_WIDE_INT lsb
, mask
;
5842 /* Given the alignment of the block.. */
5843 dalign
= block
->alignment
;
5844 mask
= dalign
/ BITS_PER_UNIT
- 1;
5846 /* ..and the combined offset of the anchor and any offset
5847 to this block object.. */
5848 offset
+= SYMBOL_REF_BLOCK_OFFSET (op
);
5849 lsb
= offset
& -offset
;
5851 /* ..find how many bits of the alignment we know for the
5856 return dalign
>= GET_MODE_SIZE (mode
);
5861 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5864 if (!DECL_SIZE_UNIT (decl
))
5867 if (!host_integerp (DECL_SIZE_UNIT (decl
), 1))
5870 dsize
= tree_low_cst (DECL_SIZE_UNIT (decl
), 1);
5874 dalign
= DECL_ALIGN_UNIT (decl
);
5875 return dalign
>= dsize
;
5878 type
= TREE_TYPE (decl
);
5880 if (TREE_CODE (decl
) == STRING_CST
)
5881 dsize
= TREE_STRING_LENGTH (decl
);
5882 else if (TYPE_SIZE_UNIT (type
)
5883 && host_integerp (TYPE_SIZE_UNIT (type
), 1))
5884 dsize
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
5890 dalign
= TYPE_ALIGN (type
);
5891 if (CONSTANT_CLASS_P (decl
))
5892 dalign
= CONSTANT_ALIGNMENT (decl
, dalign
);
5894 dalign
= DATA_ALIGNMENT (decl
, dalign
);
5895 dalign
/= BITS_PER_UNIT
;
5896 return dalign
>= dsize
;
5900 constant_pool_expr_p (rtx op
)
5904 split_const (op
, &base
, &offset
);
5905 return (GET_CODE (base
) == SYMBOL_REF
5906 && CONSTANT_POOL_ADDRESS_P (base
)
5907 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
5910 static rtx tocrel_base
, tocrel_offset
;
5913 toc_relative_expr_p (rtx op
)
5915 if (GET_CODE (op
) != CONST
)
5918 split_const (op
, &tocrel_base
, &tocrel_offset
);
5919 return (GET_CODE (tocrel_base
) == UNSPEC
5920 && XINT (tocrel_base
, 1) == UNSPEC_TOCREL
);
5923 /* Return true if X is a constant pool address, and also for cmodel=medium
5924 if X is a toc-relative address known to be offsettable within MODE. */
5927 legitimate_constant_pool_address_p (const_rtx x
, enum machine_mode mode
,
5931 && (GET_CODE (x
) == PLUS
|| GET_CODE (x
) == LO_SUM
)
5932 && GET_CODE (XEXP (x
, 0)) == REG
5933 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
5934 || ((TARGET_MINIMAL_TOC
5935 || TARGET_CMODEL
!= CMODEL_SMALL
)
5936 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
)))
5937 && toc_relative_expr_p (XEXP (x
, 1))
5938 && (TARGET_CMODEL
!= CMODEL_MEDIUM
5939 || constant_pool_expr_p (XVECEXP (tocrel_base
, 0, 0))
5941 || offsettable_ok_by_alignment (XVECEXP (tocrel_base
, 0, 0),
5942 INTVAL (tocrel_offset
), mode
)));
5946 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
5948 return (DEFAULT_ABI
== ABI_V4
5949 && !flag_pic
&& !TARGET_TOC
5950 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
5951 && small_data_operand (x
, mode
));
5954 /* SPE offset addressing is limited to 5-bits worth of double words. */
5955 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5958 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
5960 unsigned HOST_WIDE_INT offset
, extra
;
5962 if (GET_CODE (x
) != PLUS
)
5964 if (GET_CODE (XEXP (x
, 0)) != REG
)
5966 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5968 if (!reg_offset_addressing_ok_p (mode
))
5969 return virtual_stack_registers_memory_p (x
);
5970 if (legitimate_constant_pool_address_p (x
, mode
, strict
))
5972 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5975 offset
= INTVAL (XEXP (x
, 1));
5983 /* SPE vector modes. */
5984 return SPE_CONST_OFFSET_OK (offset
);
5987 if (TARGET_E500_DOUBLE
)
5988 return SPE_CONST_OFFSET_OK (offset
);
5990 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5992 if (VECTOR_MEM_VSX_P (DFmode
))
5997 /* On e500v2, we may have:
5999 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
6001 Which gets addressed with evldd instructions. */
6002 if (TARGET_E500_DOUBLE
)
6003 return SPE_CONST_OFFSET_OK (offset
);
6005 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
6007 else if (offset
& 3)
6012 if (TARGET_E500_DOUBLE
)
6013 return (SPE_CONST_OFFSET_OK (offset
)
6014 && SPE_CONST_OFFSET_OK (offset
+ 8));
6018 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
6020 else if (offset
& 3)
6031 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
6035 legitimate_indexed_address_p (rtx x
, int strict
)
6039 if (GET_CODE (x
) != PLUS
)
6045 /* Recognize the rtl generated by reload which we know will later be
6046 replaced with proper base and index regs. */
6048 && reload_in_progress
6049 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
6053 return (REG_P (op0
) && REG_P (op1
)
6054 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
6055 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
6056 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
6057 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
6061 avoiding_indexed_address_p (enum machine_mode mode
)
6063 /* Avoid indexed addressing for modes that have non-indexed
6064 load/store instruction forms. */
6065 return (TARGET_AVOID_XFORM
&& VECTOR_MEM_NONE_P (mode
));
6069 legitimate_indirect_address_p (rtx x
, int strict
)
6071 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
6075 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
6077 if (!TARGET_MACHO
|| !flag_pic
6078 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
6082 if (GET_CODE (x
) != LO_SUM
)
6084 if (GET_CODE (XEXP (x
, 0)) != REG
)
6086 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
6090 return CONSTANT_P (x
);
6094 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
6096 if (GET_CODE (x
) != LO_SUM
)
6098 if (GET_CODE (XEXP (x
, 0)) != REG
)
6100 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
6102 /* Restrict addressing for DI because of our SUBREG hackery. */
6103 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6104 || mode
== DDmode
|| mode
== TDmode
6109 if (TARGET_ELF
|| TARGET_MACHO
)
6111 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
6115 if (GET_MODE_NUNITS (mode
) != 1)
6117 if (GET_MODE_BITSIZE (mode
) > 64
6118 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
6119 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
6120 && (mode
== DFmode
|| mode
== DDmode
))))
6123 return CONSTANT_P (x
);
6130 /* Try machine-dependent ways of modifying an illegitimate address
6131 to be legitimate. If we find one, return the new, valid address.
6132 This is used from only one place: `memory_address' in explow.c.
6134 OLDX is the address as it was before break_out_memory_refs was
6135 called. In some cases it is useful to look at this to decide what
6138 It is always safe for this function to do nothing. It exists to
6139 recognize opportunities to optimize the output.
6141 On RS/6000, first check for the sum of a register with a constant
6142 integer that is out of range. If so, generate code to add the
6143 constant with the low-order 16 bits masked to the register and force
6144 this result into another register (this can be done with `cau').
6145 Then generate an address of REG+(CONST&0xffff), allowing for the
6146 possibility of bit 16 being a one.
6148 Then check for the sum of a register and something not constant, try to
6149 load the other things into a register and return the sum. */
6152 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
6153 enum machine_mode mode
)
6155 unsigned int extra
= 0;
6157 if (!reg_offset_addressing_ok_p (mode
))
6159 if (virtual_stack_registers_memory_p (x
))
6162 /* In theory we should not be seeing addresses of the form reg+0,
6163 but just in case it is generated, optimize it away. */
6164 if (GET_CODE (x
) == PLUS
&& XEXP (x
, 1) == const0_rtx
)
6165 return force_reg (Pmode
, XEXP (x
, 0));
6167 /* Make sure both operands are registers. */
6168 else if (GET_CODE (x
) == PLUS
)
6169 return gen_rtx_PLUS (Pmode
,
6170 force_reg (Pmode
, XEXP (x
, 0)),
6171 force_reg (Pmode
, XEXP (x
, 1)));
6173 return force_reg (Pmode
, x
);
6175 if (GET_CODE (x
) == SYMBOL_REF
)
6177 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
6179 return rs6000_legitimize_tls_address (x
, model
);
6189 if (!TARGET_POWERPC64
)
6197 extra
= TARGET_POWERPC64
? 8 : 12;
6203 if (GET_CODE (x
) == PLUS
6204 && GET_CODE (XEXP (x
, 0)) == REG
6205 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6206 && ((unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000)
6208 && !((TARGET_POWERPC64
6209 && (mode
== DImode
|| mode
== TImode
)
6210 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
6211 || SPE_VECTOR_MODE (mode
)
6212 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6213 || mode
== DImode
|| mode
== DDmode
6214 || mode
== TDmode
))))
6216 HOST_WIDE_INT high_int
, low_int
;
6218 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6219 if (low_int
>= 0x8000 - extra
)
6221 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
6222 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
6223 GEN_INT (high_int
)), 0);
6224 return plus_constant (sum
, low_int
);
6226 else if (GET_CODE (x
) == PLUS
6227 && GET_CODE (XEXP (x
, 0)) == REG
6228 && GET_CODE (XEXP (x
, 1)) != CONST_INT
6229 && GET_MODE_NUNITS (mode
) == 1
6230 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6232 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
6233 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
6234 && (TARGET_POWERPC64
|| mode
!= DImode
)
6235 && !avoiding_indexed_address_p (mode
)
6240 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
6241 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
6243 else if (SPE_VECTOR_MODE (mode
)
6244 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6245 || mode
== DDmode
|| mode
== TDmode
6246 || mode
== DImode
)))
6250 /* We accept [reg + reg] and [reg + OFFSET]. */
6252 if (GET_CODE (x
) == PLUS
)
6254 rtx op1
= XEXP (x
, 0);
6255 rtx op2
= XEXP (x
, 1);
6258 op1
= force_reg (Pmode
, op1
);
6260 if (GET_CODE (op2
) != REG
6261 && (GET_CODE (op2
) != CONST_INT
6262 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
6263 || (GET_MODE_SIZE (mode
) > 8
6264 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
6265 op2
= force_reg (Pmode
, op2
);
6267 /* We can't always do [reg + reg] for these, because [reg +
6268 reg + offset] is not a legitimate addressing mode. */
6269 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
6271 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
6272 return force_reg (Pmode
, y
);
6277 return force_reg (Pmode
, x
);
6283 && GET_CODE (x
) != CONST_INT
6284 && GET_CODE (x
) != CONST_DOUBLE
6286 && GET_MODE_NUNITS (mode
) == 1
6287 && (GET_MODE_BITSIZE (mode
) <= 32
6288 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6289 && (mode
== DFmode
|| mode
== DDmode
))))
6291 rtx reg
= gen_reg_rtx (Pmode
);
6292 emit_insn (gen_elf_high (reg
, x
));
6293 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
6295 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
6298 && ! MACHO_DYNAMIC_NO_PIC_P
6300 && GET_CODE (x
) != CONST_INT
6301 && GET_CODE (x
) != CONST_DOUBLE
6303 && GET_MODE_NUNITS (mode
) == 1
6304 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6305 || (mode
!= DFmode
&& mode
!= DDmode
))
6309 rtx reg
= gen_reg_rtx (Pmode
);
6310 emit_insn (gen_macho_high (reg
, x
));
6311 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
6314 && GET_CODE (x
) == SYMBOL_REF
6315 && constant_pool_expr_p (x
)
6316 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
6318 rtx reg
= TARGET_CMODEL
!= CMODEL_SMALL
? gen_reg_rtx (Pmode
) : NULL_RTX
;
6319 return create_TOC_reference (x
, reg
);
6325 /* Debug version of rs6000_legitimize_address. */
6327 rs6000_debug_legitimize_address (rtx x
, rtx oldx
, enum machine_mode mode
)
6333 ret
= rs6000_legitimize_address (x
, oldx
, mode
);
6334 insns
= get_insns ();
6340 "\nrs6000_legitimize_address: mode %s, old code %s, "
6341 "new code %s, modified\n",
6342 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)),
6343 GET_RTX_NAME (GET_CODE (ret
)));
6345 fprintf (stderr
, "Original address:\n");
6348 fprintf (stderr
, "oldx:\n");
6351 fprintf (stderr
, "New address:\n");
6356 fprintf (stderr
, "Insns added:\n");
6357 debug_rtx_list (insns
, 20);
6363 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6364 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)));
6375 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6376 We need to emit DTP-relative relocations. */
6379 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
6384 fputs ("\t.long\t", file
);
6387 fputs (DOUBLE_INT_ASM_OP
, file
);
6392 output_addr_const (file
, x
);
6393 fputs ("@dtprel+0x8000", file
);
6396 /* In the name of slightly smaller debug output, and to cater to
6397 general assembler lossage, recognize various UNSPEC sequences
6398 and turn them back into a direct symbol reference. */
6401 rs6000_delegitimize_address (rtx orig_x
)
6405 orig_x
= delegitimize_mem_from_attrs (orig_x
);
6410 if (GET_CODE (x
) == (TARGET_CMODEL
!= CMODEL_SMALL
? LO_SUM
: PLUS
)
6411 && GET_CODE (XEXP (x
, 1)) == CONST
)
6413 y
= XEXP (XEXP (x
, 1), 0);
6414 if (GET_CODE (y
) == UNSPEC
6415 && XINT (y
, 1) == UNSPEC_TOCREL
6416 && ((GET_CODE (XEXP (x
, 0)) == REG
6417 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
6418 || TARGET_MINIMAL_TOC
6419 || TARGET_CMODEL
!= CMODEL_SMALL
))
6420 || (TARGET_CMODEL
!= CMODEL_SMALL
6421 && GET_CODE (XEXP (x
, 0)) == PLUS
6422 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6423 && REGNO (XEXP (XEXP (x
, 0), 0)) == TOC_REGISTER
6424 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6425 && rtx_equal_p (XEXP (x
, 1),
6426 XEXP (XEXP (XEXP (x
, 0), 1), 0)))))
6428 y
= XVECEXP (y
, 0, 0);
6429 if (!MEM_P (orig_x
))
6432 return replace_equiv_address_nv (orig_x
, y
);
6437 && GET_CODE (orig_x
) == LO_SUM
6438 && GET_CODE (XEXP (x
, 1)) == CONST
)
6440 y
= XEXP (XEXP (x
, 1), 0);
6441 if (GET_CODE (y
) == UNSPEC
6442 && XINT (y
, 1) == UNSPEC_MACHOPIC_OFFSET
)
6443 return XVECEXP (y
, 0, 0);
6449 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6451 static GTY(()) rtx rs6000_tls_symbol
;
6453 rs6000_tls_get_addr (void)
6455 if (!rs6000_tls_symbol
)
6456 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
6458 return rs6000_tls_symbol
;
6461 /* Construct the SYMBOL_REF for TLS GOT references. */
6463 static GTY(()) rtx rs6000_got_symbol
;
6465 rs6000_got_sym (void)
6467 if (!rs6000_got_symbol
)
6469 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6470 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
6471 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
6474 return rs6000_got_symbol
;
6477 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6478 this (thread-local) address. */
6481 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
6485 dest
= gen_reg_rtx (Pmode
);
6486 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
6492 tlsreg
= gen_rtx_REG (Pmode
, 13);
6493 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
6497 tlsreg
= gen_rtx_REG (Pmode
, 2);
6498 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
6502 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
6506 tmp
= gen_reg_rtx (Pmode
);
6509 tlsreg
= gen_rtx_REG (Pmode
, 13);
6510 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
6514 tlsreg
= gen_rtx_REG (Pmode
, 2);
6515 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
6519 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
6521 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
6526 rtx r3
, got
, tga
, tmp1
, tmp2
, call_insn
;
6528 /* We currently use relocations like @got@tlsgd for tls, which
6529 means the linker will handle allocation of tls entries, placing
6530 them in the .got section. So use a pointer to the .got section,
6531 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6532 or to secondary GOT sections used by 32-bit -fPIC. */
6534 got
= gen_rtx_REG (Pmode
, 2);
6538 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
6541 rtx gsym
= rs6000_got_sym ();
6542 got
= gen_reg_rtx (Pmode
);
6544 rs6000_emit_move (got
, gsym
, Pmode
);
6549 tmp1
= gen_reg_rtx (Pmode
);
6550 tmp2
= gen_reg_rtx (Pmode
);
6551 mem
= gen_const_mem (Pmode
, tmp1
);
6552 lab
= gen_label_rtx ();
6553 emit_insn (gen_load_toc_v4_PIC_1b (gsym
, lab
));
6554 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
6555 emit_move_insn (tmp2
, mem
);
6556 last
= emit_insn (gen_addsi3 (got
, tmp1
, tmp2
));
6557 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
6562 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
6564 r3
= gen_rtx_REG (Pmode
, 3);
6565 tga
= rs6000_tls_get_addr ();
6566 emit_library_call_value (tga
, dest
, LCT_CONST
, Pmode
, 1, r3
, Pmode
);
6568 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6569 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
6570 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6571 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
6572 else if (DEFAULT_ABI
== ABI_V4
)
6573 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
6576 call_insn
= last_call_insn ();
6577 PATTERN (call_insn
) = insn
;
6578 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6579 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6580 pic_offset_table_rtx
);
6582 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
6584 r3
= gen_rtx_REG (Pmode
, 3);
6585 tga
= rs6000_tls_get_addr ();
6586 tmp1
= gen_reg_rtx (Pmode
);
6587 emit_library_call_value (tga
, tmp1
, LCT_CONST
, Pmode
, 1, r3
, Pmode
);
6589 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6590 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
6591 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6592 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
6593 else if (DEFAULT_ABI
== ABI_V4
)
6594 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
6597 call_insn
= last_call_insn ();
6598 PATTERN (call_insn
) = insn
;
6599 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6600 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6601 pic_offset_table_rtx
);
6603 if (rs6000_tls_size
== 16)
6606 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
6608 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
6610 else if (rs6000_tls_size
== 32)
6612 tmp2
= gen_reg_rtx (Pmode
);
6614 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
6616 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
6619 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
6621 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
6625 tmp2
= gen_reg_rtx (Pmode
);
6627 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
6629 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
6631 insn
= gen_rtx_SET (Pmode
, dest
,
6632 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
6638 /* IE, or 64-bit offset LE. */
6639 tmp2
= gen_reg_rtx (Pmode
);
6641 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
6643 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
6646 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
6648 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
6656 /* Return 1 if X contains a thread-local symbol. */
6659 rs6000_tls_referenced_p (rtx x
)
6661 if (! TARGET_HAVE_TLS
)
6664 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
6667 /* Return 1 if *X is a thread-local symbol. This is the same as
6668 rs6000_tls_symbol_ref except for the type of the unused argument. */
6671 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
6673 return RS6000_SYMBOL_REF_TLS_P (*x
);
6676 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6677 replace the input X, or the original X if no replacement is called for.
6678 The output parameter *WIN is 1 if the calling macro should goto WIN,
6681 For RS/6000, we wish to handle large displacements off a base
6682 register by splitting the addend across an addiu/addis and the mem insn.
6683 This cuts number of extra insns needed from 3 to 1.
6685 On Darwin, we use this to generate code for floating point constants.
6686 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6687 The Darwin code is inside #if TARGET_MACHO because only then are the
6688 machopic_* functions defined. */
6690 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6691 int opnum
, int type
,
6692 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
6694 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6696 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6697 DFmode/DImode MEM. */
6700 && ((mode
== DFmode
&& recog_data
.operand_mode
[0] == V2DFmode
)
6701 || (mode
== DImode
&& recog_data
.operand_mode
[0] == V2DImode
)))
6702 reg_offset_p
= false;
6704 /* We must recognize output that we have already generated ourselves. */
6705 if (GET_CODE (x
) == PLUS
6706 && GET_CODE (XEXP (x
, 0)) == PLUS
6707 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6708 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6709 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6711 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6712 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6713 opnum
, (enum reload_type
)type
);
6718 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6719 if (GET_CODE (x
) == LO_SUM
6720 && GET_CODE (XEXP (x
, 0)) == HIGH
)
6722 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6723 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6724 opnum
, (enum reload_type
)type
);
6730 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
6731 && GET_CODE (x
) == LO_SUM
6732 && GET_CODE (XEXP (x
, 0)) == PLUS
6733 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
6734 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6735 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
6736 && machopic_operand_p (XEXP (x
, 1)))
6738 /* Result of previous invocation of this function on Darwin
6739 floating point constant. */
6740 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6741 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6742 opnum
, (enum reload_type
)type
);
6748 if (TARGET_CMODEL
!= CMODEL_SMALL
6749 && GET_CODE (x
) == LO_SUM
6750 && GET_CODE (XEXP (x
, 0)) == PLUS
6751 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6752 && REGNO (XEXP (XEXP (x
, 0), 0)) == TOC_REGISTER
6753 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6754 && GET_CODE (XEXP (x
, 1)) == CONST
6755 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == UNSPEC
6756 && XINT (XEXP (XEXP (x
, 1), 0), 1) == UNSPEC_TOCREL
6757 && rtx_equal_p (XEXP (XEXP (XEXP (x
, 0), 1), 0), XEXP (x
, 1)))
6759 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6760 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6761 opnum
, (enum reload_type
) type
);
6766 /* Force ld/std non-word aligned offset into base register by wrapping
6768 if (GET_CODE (x
) == PLUS
6769 && GET_CODE (XEXP (x
, 0)) == REG
6770 && REGNO (XEXP (x
, 0)) < 32
6771 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6772 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6774 && (INTVAL (XEXP (x
, 1)) & 3) != 0
6775 && VECTOR_MEM_NONE_P (mode
)
6776 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
6777 && TARGET_POWERPC64
)
6779 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
6780 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6781 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6782 opnum
, (enum reload_type
) type
);
6787 if (GET_CODE (x
) == PLUS
6788 && GET_CODE (XEXP (x
, 0)) == REG
6789 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
6790 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6791 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6793 && !SPE_VECTOR_MODE (mode
)
6794 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6795 || mode
== DDmode
|| mode
== TDmode
6797 && VECTOR_MEM_NONE_P (mode
))
6799 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
6800 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
6802 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6804 /* Check for 32-bit overflow. */
6805 if (high
+ low
!= val
)
6811 /* Reload the high part into a base reg; leave the low part
6812 in the mem directly. */
6814 x
= gen_rtx_PLUS (GET_MODE (x
),
6815 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
6819 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6820 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6821 opnum
, (enum reload_type
)type
);
6826 if (GET_CODE (x
) == SYMBOL_REF
6828 && VECTOR_MEM_NONE_P (mode
)
6829 && !SPE_VECTOR_MODE (mode
)
6831 && DEFAULT_ABI
== ABI_DARWIN
6832 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
6834 && DEFAULT_ABI
== ABI_V4
6837 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6838 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6842 && (mode
!= DImode
|| TARGET_POWERPC64
)
6843 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
6844 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
6849 rtx offset
= machopic_gen_offset (x
);
6850 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6851 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
6852 gen_rtx_HIGH (Pmode
, offset
)), offset
);
6856 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6857 gen_rtx_HIGH (Pmode
, x
), x
);
6859 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6860 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6861 opnum
, (enum reload_type
)type
);
6866 /* Reload an offset address wrapped by an AND that represents the
6867 masking of the lower bits. Strip the outer AND and let reload
6868 convert the offset address into an indirect address. For VSX,
6869 force reload to create the address with an AND in a separate
6870 register, because we can't guarantee an altivec register will
6872 if (VECTOR_MEM_ALTIVEC_P (mode
)
6873 && GET_CODE (x
) == AND
6874 && GET_CODE (XEXP (x
, 0)) == PLUS
6875 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6876 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6877 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6878 && INTVAL (XEXP (x
, 1)) == -16)
6887 && GET_CODE (x
) == SYMBOL_REF
6888 && constant_pool_expr_p (x
)
6889 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
6891 x
= create_TOC_reference (x
, NULL_RTX
);
6892 if (TARGET_CMODEL
!= CMODEL_SMALL
)
6893 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6894 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6895 opnum
, (enum reload_type
) type
);
6903 /* Debug version of rs6000_legitimize_reload_address. */
6905 rs6000_debug_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6906 int opnum
, int type
,
6907 int ind_levels
, int *win
)
6909 rtx ret
= rs6000_legitimize_reload_address (x
, mode
, opnum
, type
,
6912 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6913 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6914 GET_MODE_NAME (mode
), opnum
, type
, ind_levels
, *win
);
6918 fprintf (stderr
, "Same address returned\n");
6920 fprintf (stderr
, "NULL returned\n");
6923 fprintf (stderr
, "New address:\n");
6930 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6931 that is a valid memory address for an instruction.
6932 The MODE argument is the machine mode for the MEM expression
6933 that wants to use this address.
6935 On the RS/6000, there are four valid address: a SYMBOL_REF that
6936 refers to a constant pool entry of an address (or the sum of it
6937 plus a constant), a short (16-bit signed) constant plus a register,
6938 the sum of two registers, or a register indirect, possibly with an
6939 auto-increment. For DFmode, DDmode and DImode with a constant plus
6940 register, we must ensure that both words are addressable or PowerPC64
6941 with offset word aligned.
6943 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6944 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6945 because adjacent memory cells are accessed by adding word-sized offsets
6946 during assembly output. */
6948 rs6000_legitimate_address_p (enum machine_mode mode
, rtx x
, bool reg_ok_strict
)
6950 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6952 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6953 if (VECTOR_MEM_ALTIVEC_P (mode
)
6954 && GET_CODE (x
) == AND
6955 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6956 && INTVAL (XEXP (x
, 1)) == -16)
6959 if (RS6000_SYMBOL_REF_TLS_P (x
))
6961 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
6963 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
6964 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6965 && !SPE_VECTOR_MODE (mode
)
6968 /* Restrict addressing for DI because of our SUBREG hackery. */
6969 && !(TARGET_E500_DOUBLE
6970 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6972 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
6974 if (virtual_stack_registers_memory_p (x
))
6976 if (reg_offset_p
&& legitimate_small_data_p (mode
, x
))
6979 && legitimate_constant_pool_address_p (x
, mode
, reg_ok_strict
))
6981 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6984 && GET_CODE (x
) == PLUS
6985 && GET_CODE (XEXP (x
, 0)) == REG
6986 && (XEXP (x
, 0) == virtual_stack_vars_rtx
6987 || XEXP (x
, 0) == arg_pointer_rtx
)
6988 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6990 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
6995 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6997 || (mode
!= DFmode
&& mode
!= DDmode
)
6998 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
6999 && (TARGET_POWERPC64
|| mode
!= DImode
)
7000 && !avoiding_indexed_address_p (mode
)
7001 && legitimate_indexed_address_p (x
, reg_ok_strict
))
7003 if (GET_CODE (x
) == PRE_MODIFY
7007 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
7009 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
7010 && (TARGET_POWERPC64
|| mode
!= DImode
)
7011 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
7012 && !SPE_VECTOR_MODE (mode
)
7013 /* Restrict addressing for DI because of our SUBREG hackery. */
7014 && !(TARGET_E500_DOUBLE
7015 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
7017 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
7018 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
7019 || (!avoiding_indexed_address_p (mode
)
7020 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
7021 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
7023 if (reg_offset_p
&& legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
7028 /* Debug version of rs6000_legitimate_address_p. */
7030 rs6000_debug_legitimate_address_p (enum machine_mode mode
, rtx x
,
7033 bool ret
= rs6000_legitimate_address_p (mode
, x
, reg_ok_strict
);
7035 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
7036 "strict = %d, code = %s\n",
7037 ret
? "true" : "false",
7038 GET_MODE_NAME (mode
),
7040 GET_RTX_NAME (GET_CODE (x
)));
7046 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7049 rs6000_mode_dependent_address_p (const_rtx addr
)
7051 return rs6000_mode_dependent_address_ptr (addr
);
7054 /* Go to LABEL if ADDR (a legitimate address expression)
7055 has an effect that depends on the machine mode it is used for.
7057 On the RS/6000 this is true of all integral offsets (since AltiVec
7058 and VSX modes don't allow them) or is a pre-increment or decrement.
7060 ??? Except that due to conceptual problems in offsettable_address_p
7061 we can't really report the problems of integral offsets. So leave
7062 this assuming that the adjustable offset must be valid for the
7063 sub-words of a TFmode operand, which is what we had before. */
7066 rs6000_mode_dependent_address (const_rtx addr
)
7068 switch (GET_CODE (addr
))
7071 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7072 is considered a legitimate address before reload, so there
7073 are no offset restrictions in that case. Note that this
7074 condition is safe in strict mode because any address involving
7075 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7076 been rejected as illegitimate. */
7077 if (XEXP (addr
, 0) != virtual_stack_vars_rtx
7078 && XEXP (addr
, 0) != arg_pointer_rtx
7079 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
7081 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
7082 return val
+ 12 + 0x8000 >= 0x10000;
7087 /* Anything in the constant pool is sufficiently aligned that
7088 all bytes have the same high part address. */
7089 return !legitimate_constant_pool_address_p (addr
, QImode
, false);
7091 /* Auto-increment cases are now treated generically in recog.c. */
7093 return TARGET_UPDATE
;
7095 /* AND is only allowed in Altivec loads. */
7106 /* Debug version of rs6000_mode_dependent_address. */
7108 rs6000_debug_mode_dependent_address (const_rtx addr
)
7110 bool ret
= rs6000_mode_dependent_address (addr
);
7112 fprintf (stderr
, "\nrs6000_mode_dependent_address: ret = %s\n",
7113 ret
? "true" : "false");
7119 /* Implement FIND_BASE_TERM. */
7122 rs6000_find_base_term (rtx op
)
7126 split_const (op
, &base
, &offset
);
7127 if (GET_CODE (base
) == UNSPEC
)
7128 switch (XINT (base
, 1))
7131 case UNSPEC_MACHOPIC_OFFSET
:
7132 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7133 for aliasing purposes. */
7134 return XVECEXP (base
, 0, 0);
7140 /* More elaborate version of recog's offsettable_memref_p predicate
7141 that works around the ??? note of rs6000_mode_dependent_address.
7142 In particular it accepts
7144 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7146 in 32-bit mode, that the recog predicate rejects. */
7149 rs6000_offsettable_memref_p (rtx op
)
7154 /* First mimic offsettable_memref_p. */
7155 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
7158 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7159 the latter predicate knows nothing about the mode of the memory
7160 reference and, therefore, assumes that it is the largest supported
7161 mode (TFmode). As a consequence, legitimate offsettable memory
7162 references are rejected. rs6000_legitimate_offset_address_p contains
7163 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7164 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
7167 /* Change register usage conditional on target flags. */
7169 rs6000_conditional_register_usage (void)
7173 if (TARGET_DEBUG_TARGET
)
7174 fprintf (stderr
, "rs6000_conditional_register_usage called\n");
7176 /* Set MQ register fixed (already call_used) if not POWER
7177 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7182 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7184 fixed_regs
[13] = call_used_regs
[13]
7185 = call_really_used_regs
[13] = 1;
7187 /* Conditionally disable FPRs. */
7188 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
7189 for (i
= 32; i
< 64; i
++)
7190 fixed_regs
[i
] = call_used_regs
[i
]
7191 = call_really_used_regs
[i
] = 1;
7193 /* The TOC register is not killed across calls in a way that is
7194 visible to the compiler. */
7195 if (DEFAULT_ABI
== ABI_AIX
)
7196 call_really_used_regs
[2] = 0;
7198 if (DEFAULT_ABI
== ABI_V4
7199 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
7201 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7203 if (DEFAULT_ABI
== ABI_V4
7204 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
7206 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7207 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7208 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7210 if (DEFAULT_ABI
== ABI_DARWIN
7211 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
7212 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7213 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7214 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7216 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
7217 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
7218 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
7222 global_regs
[SPEFSCR_REGNO
] = 1;
7223 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7224 registers in prologues and epilogues. We no longer use r14
7225 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7226 pool for link-compatibility with older versions of GCC. Once
7227 "old" code has died out, we can return r14 to the allocation
7230 = call_used_regs
[14]
7231 = call_really_used_regs
[14] = 1;
7234 if (!TARGET_ALTIVEC
&& !TARGET_VSX
)
7236 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
7237 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
7238 call_really_used_regs
[VRSAVE_REGNO
] = 1;
7241 if (TARGET_ALTIVEC
|| TARGET_VSX
)
7242 global_regs
[VSCR_REGNO
] = 1;
7244 if (TARGET_ALTIVEC_ABI
)
7246 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
7247 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
7249 /* AIX reserves VR20:31 in non-extended ABI mode. */
7251 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
7252 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
7256 /* Try to output insns to set TARGET equal to the constant C if it can
7257 be done in less than N insns. Do all computations in MODE.
7258 Returns the place where the output has been placed if it can be
7259 done and the insns have been emitted. If it would take more than N
7260 insns, zero is returned and no insns and emitted. */
7263 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
7264 rtx source
, int n ATTRIBUTE_UNUSED
)
7266 rtx result
, insn
, set
;
7267 HOST_WIDE_INT c0
, c1
;
7274 dest
= gen_reg_rtx (mode
);
7275 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
7279 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
7281 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
7282 GEN_INT (INTVAL (source
)
7283 & (~ (HOST_WIDE_INT
) 0xffff))));
7284 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
7285 gen_rtx_IOR (SImode
, copy_rtx (result
),
7286 GEN_INT (INTVAL (source
) & 0xffff))));
7291 switch (GET_CODE (source
))
7294 c0
= INTVAL (source
);
7299 #if HOST_BITS_PER_WIDE_INT >= 64
7300 c0
= CONST_DOUBLE_LOW (source
);
7303 c0
= CONST_DOUBLE_LOW (source
);
7304 c1
= CONST_DOUBLE_HIGH (source
);
7312 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
7319 insn
= get_last_insn ();
7320 set
= single_set (insn
);
7321 if (! CONSTANT_P (SET_SRC (set
)))
7322 set_unique_reg_note (insn
, REG_EQUAL
, source
);
7327 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7328 fall back to a straight forward decomposition. We do this to avoid
7329 exponential run times encountered when looking for longer sequences
7330 with rs6000_emit_set_const. */
7332 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
7334 if (!TARGET_POWERPC64
)
7336 rtx operand1
, operand2
;
7338 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
7340 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
7342 emit_move_insn (operand1
, GEN_INT (c1
));
7343 emit_move_insn (operand2
, GEN_INT (c2
));
7347 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
7350 ud2
= (c1
& 0xffff0000) >> 16;
7351 #if HOST_BITS_PER_WIDE_INT >= 64
7355 ud4
= (c2
& 0xffff0000) >> 16;
7357 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
7358 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
7361 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
7363 emit_move_insn (dest
, GEN_INT (ud1
));
7366 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
7367 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
7370 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
7373 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
7375 emit_move_insn (copy_rtx (dest
),
7376 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7379 else if (ud3
== 0 && ud4
== 0)
7381 gcc_assert (ud2
& 0x8000);
7382 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
7385 emit_move_insn (copy_rtx (dest
),
7386 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7388 emit_move_insn (copy_rtx (dest
),
7389 gen_rtx_ZERO_EXTEND (DImode
,
7390 gen_lowpart (SImode
,
7393 else if ((ud4
== 0xffff && (ud3
& 0x8000))
7394 || (ud4
== 0 && ! (ud3
& 0x8000)))
7397 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
7400 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
7403 emit_move_insn (copy_rtx (dest
),
7404 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7406 emit_move_insn (copy_rtx (dest
),
7407 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
7410 emit_move_insn (copy_rtx (dest
),
7411 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7417 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
7420 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
7423 emit_move_insn (copy_rtx (dest
),
7424 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7427 emit_move_insn (copy_rtx (dest
),
7428 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
7431 emit_move_insn (copy_rtx (dest
),
7432 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7433 GEN_INT (ud2
<< 16)));
7435 emit_move_insn (copy_rtx (dest
),
7436 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
7442 /* Helper for the following. Get rid of [r+r] memory refs
7443 in cases where it won't work (TImode, TFmode, TDmode). */
7446 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
7448 if (reload_in_progress
)
7451 if (GET_CODE (operands
[0]) == MEM
7452 && GET_CODE (XEXP (operands
[0], 0)) != REG
7453 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0),
7454 GET_MODE (operands
[0]), false))
7456 = replace_equiv_address (operands
[0],
7457 copy_addr_to_reg (XEXP (operands
[0], 0)));
7459 if (GET_CODE (operands
[1]) == MEM
7460 && GET_CODE (XEXP (operands
[1], 0)) != REG
7461 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0),
7462 GET_MODE (operands
[1]), false))
7464 = replace_equiv_address (operands
[1],
7465 copy_addr_to_reg (XEXP (operands
[1], 0)));
7468 /* Emit a move from SOURCE to DEST in mode MODE. */
7470 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
7474 operands
[1] = source
;
7476 if (TARGET_DEBUG_ADDR
)
7479 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7480 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7481 GET_MODE_NAME (mode
),
7484 can_create_pseudo_p ());
7486 fprintf (stderr
, "source:\n");
7490 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7491 if (GET_CODE (operands
[1]) == CONST_DOUBLE
7492 && ! FLOAT_MODE_P (mode
)
7493 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
7495 /* FIXME. This should never happen. */
7496 /* Since it seems that it does, do the safe thing and convert
7498 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
7500 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
7501 || FLOAT_MODE_P (mode
)
7502 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
7503 || CONST_DOUBLE_LOW (operands
[1]) < 0)
7504 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
7505 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
7507 /* Check if GCC is setting up a block move that will end up using FP
7508 registers as temporaries. We must make sure this is acceptable. */
7509 if (GET_CODE (operands
[0]) == MEM
7510 && GET_CODE (operands
[1]) == MEM
7512 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
7513 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
7514 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
7515 ? 32 : MEM_ALIGN (operands
[0])))
7516 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
7518 : MEM_ALIGN (operands
[1]))))
7519 && ! MEM_VOLATILE_P (operands
[0])
7520 && ! MEM_VOLATILE_P (operands
[1]))
7522 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
7523 adjust_address (operands
[1], SImode
, 0));
7524 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
7525 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
7529 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
7530 && !gpc_reg_operand (operands
[1], mode
))
7531 operands
[1] = force_reg (mode
, operands
[1]);
7533 if (mode
== SFmode
&& ! TARGET_POWERPC
7534 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
7535 && GET_CODE (operands
[0]) == MEM
)
7539 if (reload_in_progress
|| reload_completed
)
7540 regnum
= true_regnum (operands
[1]);
7541 else if (GET_CODE (operands
[1]) == REG
)
7542 regnum
= REGNO (operands
[1]);
7546 /* If operands[1] is a register, on POWER it may have
7547 double-precision data in it, so truncate it to single
7549 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
7552 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
7553 : gen_reg_rtx (mode
));
7554 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
7555 operands
[1] = newreg
;
7559 /* Recognize the case where operand[1] is a reference to thread-local
7560 data and load its address to a register. */
7561 if (rs6000_tls_referenced_p (operands
[1]))
7563 enum tls_model model
;
7564 rtx tmp
= operands
[1];
7567 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
7569 addend
= XEXP (XEXP (tmp
, 0), 1);
7570 tmp
= XEXP (XEXP (tmp
, 0), 0);
7573 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
7574 model
= SYMBOL_REF_TLS_MODEL (tmp
);
7575 gcc_assert (model
!= 0);
7577 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
7580 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
7581 tmp
= force_operand (tmp
, operands
[0]);
7586 /* Handle the case where reload calls us with an invalid address. */
7587 if (reload_in_progress
&& mode
== Pmode
7588 && (! general_operand (operands
[1], mode
)
7589 || ! nonimmediate_operand (operands
[0], mode
)))
7592 /* 128-bit constant floating-point values on Darwin should really be
7593 loaded as two parts. */
7594 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
7595 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
7597 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7598 know how to get a DFmode SUBREG of a TFmode. */
7599 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
7600 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
7601 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
7603 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
7604 GET_MODE_SIZE (imode
)),
7605 simplify_gen_subreg (imode
, operands
[1], mode
,
7606 GET_MODE_SIZE (imode
)),
7611 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
7612 cfun
->machine
->sdmode_stack_slot
=
7613 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
7615 if (reload_in_progress
7617 && MEM_P (operands
[0])
7618 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
7619 && REG_P (operands
[1]))
7621 if (FP_REGNO_P (REGNO (operands
[1])))
7623 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
7624 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7625 emit_insn (gen_movsd_store (mem
, operands
[1]));
7627 else if (INT_REGNO_P (REGNO (operands
[1])))
7629 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
7630 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7631 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
7637 if (reload_in_progress
7639 && REG_P (operands
[0])
7640 && MEM_P (operands
[1])
7641 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
7643 if (FP_REGNO_P (REGNO (operands
[0])))
7645 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
7646 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7647 emit_insn (gen_movsd_load (operands
[0], mem
));
7649 else if (INT_REGNO_P (REGNO (operands
[0])))
7651 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
7652 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7653 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
7660 /* FIXME: In the long term, this switch statement should go away
7661 and be replaced by a sequence of tests based on things like
7667 if (CONSTANT_P (operands
[1])
7668 && GET_CODE (operands
[1]) != CONST_INT
)
7669 operands
[1] = force_const_mem (mode
, operands
[1]);
7674 rs6000_eliminate_indexed_memrefs (operands
);
7681 if (CONSTANT_P (operands
[1])
7682 && ! easy_fp_constant (operands
[1], mode
))
7683 operands
[1] = force_const_mem (mode
, operands
[1]);
7696 if (CONSTANT_P (operands
[1])
7697 && !easy_vector_constant (operands
[1], mode
))
7698 operands
[1] = force_const_mem (mode
, operands
[1]);
7703 /* Use default pattern for address of ELF small data */
7706 && DEFAULT_ABI
== ABI_V4
7707 && (GET_CODE (operands
[1]) == SYMBOL_REF
7708 || GET_CODE (operands
[1]) == CONST
)
7709 && small_data_operand (operands
[1], mode
))
7711 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7715 if (DEFAULT_ABI
== ABI_V4
7716 && mode
== Pmode
&& mode
== SImode
7717 && flag_pic
== 1 && got_operand (operands
[1], mode
))
7719 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
7723 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
7727 && CONSTANT_P (operands
[1])
7728 && GET_CODE (operands
[1]) != HIGH
7729 && GET_CODE (operands
[1]) != CONST_INT
)
7731 rtx target
= (!can_create_pseudo_p ()
7733 : gen_reg_rtx (mode
));
7735 /* If this is a function address on -mcall-aixdesc,
7736 convert it to the address of the descriptor. */
7737 if (DEFAULT_ABI
== ABI_AIX
7738 && GET_CODE (operands
[1]) == SYMBOL_REF
7739 && XSTR (operands
[1], 0)[0] == '.')
7741 const char *name
= XSTR (operands
[1], 0);
7743 while (*name
== '.')
7745 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
7746 CONSTANT_POOL_ADDRESS_P (new_ref
)
7747 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
7748 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
7749 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
7750 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
7751 operands
[1] = new_ref
;
7754 if (DEFAULT_ABI
== ABI_DARWIN
)
7757 if (MACHO_DYNAMIC_NO_PIC_P
)
7759 /* Take care of any required data indirection. */
7760 operands
[1] = rs6000_machopic_legitimize_pic_address (
7761 operands
[1], mode
, operands
[0]);
7762 if (operands
[0] != operands
[1])
7763 emit_insn (gen_rtx_SET (VOIDmode
,
7764 operands
[0], operands
[1]));
7768 emit_insn (gen_macho_high (target
, operands
[1]));
7769 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
7773 emit_insn (gen_elf_high (target
, operands
[1]));
7774 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
7778 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7779 and we have put it in the TOC, we just need to make a TOC-relative
7782 && GET_CODE (operands
[1]) == SYMBOL_REF
7783 && constant_pool_expr_p (operands
[1])
7784 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
7785 get_pool_mode (operands
[1])))
7786 || (TARGET_CMODEL
== CMODEL_MEDIUM
7787 && GET_CODE (operands
[1]) == SYMBOL_REF
7788 && !CONSTANT_POOL_ADDRESS_P (operands
[1])
7789 && SYMBOL_REF_LOCAL_P (operands
[1])))
7792 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7794 if (can_create_pseudo_p ())
7795 reg
= gen_reg_rtx (Pmode
);
7799 operands
[1] = create_TOC_reference (operands
[1], reg
);
7801 else if (mode
== Pmode
7802 && CONSTANT_P (operands
[1])
7803 && ((GET_CODE (operands
[1]) != CONST_INT
7804 && ! easy_fp_constant (operands
[1], mode
))
7805 || (GET_CODE (operands
[1]) == CONST_INT
7806 && (num_insns_constant (operands
[1], mode
)
7807 > (TARGET_CMODEL
!= CMODEL_SMALL
? 3 : 2)))
7808 || (GET_CODE (operands
[0]) == REG
7809 && FP_REGNO_P (REGNO (operands
[0]))))
7810 && GET_CODE (operands
[1]) != HIGH
7811 && ! legitimate_constant_pool_address_p (operands
[1], mode
,
7813 && ! toc_relative_expr_p (operands
[1])
7814 && (TARGET_CMODEL
== CMODEL_SMALL
7815 || can_create_pseudo_p ()
7816 || (REG_P (operands
[0])
7817 && INT_REG_OK_FOR_BASE_P (operands
[0], true))))
7821 /* Darwin uses a special PIC legitimizer. */
7822 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
7825 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
7827 if (operands
[0] != operands
[1])
7828 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7833 /* If we are to limit the number of things we put in the TOC and
7834 this is a symbol plus a constant we can add in one insn,
7835 just put the symbol in the TOC and add the constant. Don't do
7836 this if reload is in progress. */
7837 if (GET_CODE (operands
[1]) == CONST
7838 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
7839 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
7840 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
7841 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
7842 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
7843 && ! side_effects_p (operands
[0]))
7846 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
7847 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
7849 sym
= force_reg (mode
, sym
);
7850 emit_insn (gen_add3_insn (operands
[0], sym
, other
));
7854 operands
[1] = force_const_mem (mode
, operands
[1]);
7857 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
7858 && constant_pool_expr_p (XEXP (operands
[1], 0))
7859 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7860 get_pool_constant (XEXP (operands
[1], 0)),
7861 get_pool_mode (XEXP (operands
[1], 0))))
7865 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7867 if (can_create_pseudo_p ())
7868 reg
= gen_reg_rtx (Pmode
);
7872 tocref
= create_TOC_reference (XEXP (operands
[1], 0), reg
);
7873 operands
[1] = gen_const_mem (mode
, tocref
);
7874 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
7880 rs6000_eliminate_indexed_memrefs (operands
);
7884 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
7886 gen_rtx_SET (VOIDmode
,
7887 operands
[0], operands
[1]),
7888 gen_rtx_CLOBBER (VOIDmode
,
7889 gen_rtx_SCRATCH (SImode
)))));
7895 fatal_insn ("bad move", gen_rtx_SET (VOIDmode
, dest
, source
));
7898 /* Above, we may have called force_const_mem which may have returned
7899 an invalid address. If we can, fix this up; otherwise, reload will
7900 have to deal with it. */
7901 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
7902 operands
[1] = validize_mem (operands
[1]);
7905 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7908 /* Nonzero if we can use a floating-point register to pass this arg. */
7909 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7910 (SCALAR_FLOAT_MODE_P (MODE) \
7911 && (CUM)->fregno <= FP_ARG_MAX_REG \
7912 && TARGET_HARD_FLOAT && TARGET_FPRS)
7914 /* Nonzero if we can use an AltiVec register to pass this arg. */
7915 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7916 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7917 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7918 && TARGET_ALTIVEC_ABI \
7921 /* Return a nonzero value to say to return the function value in
7922 memory, just as large structures are always returned. TYPE will be
7923 the data type of the value, and FNTYPE will be the type of the
7924 function doing the returning, or @code{NULL} for libcalls.
7926 The AIX ABI for the RS/6000 specifies that all structures are
7927 returned in memory. The Darwin ABI does the same.
7929 For the Darwin 64 Bit ABI, a function result can be returned in
7930 registers or in memory, depending on the size of the return data
7931 type. If it is returned in registers, the value occupies the same
7932 registers as it would if it were the first and only function
7933 argument. Otherwise, the function places its result in memory at
7934 the location pointed to by GPR3.
7936 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7937 but a draft put them in memory, and GCC used to implement the draft
7938 instead of the final standard. Therefore, aix_struct_return
7939 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7940 compatibility can change DRAFT_V4_STRUCT_RET to override the
7941 default, and -m switches get the final word. See
7942 rs6000_option_override_internal for more details.
7944 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7945 long double support is enabled. These values are returned in memory.
7947 int_size_in_bytes returns -1 for variable size objects, which go in
7948 memory always. The cast to unsigned makes -1 > 8. */
7951 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7953 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7955 && rs6000_darwin64_abi
7956 && TREE_CODE (type
) == RECORD_TYPE
7957 && int_size_in_bytes (type
) > 0)
7959 CUMULATIVE_ARGS valcum
;
7963 valcum
.fregno
= FP_ARG_MIN_REG
;
7964 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
7965 /* Do a trial code generation as if this were going to be passed
7966 as an argument; if any part goes in memory, we return NULL. */
7967 valret
= rs6000_darwin64_record_arg (&valcum
, type
, true, true);
7970 /* Otherwise fall through to more conventional ABI rules. */
7973 if (AGGREGATE_TYPE_P (type
)
7974 && (aix_struct_return
7975 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
7978 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7979 modes only exist for GCC vector types if -maltivec. */
7980 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
7981 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7984 /* Return synthetic vectors in memory. */
7985 if (TREE_CODE (type
) == VECTOR_TYPE
7986 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
7988 static bool warned_for_return_big_vectors
= false;
7989 if (!warned_for_return_big_vectors
)
7991 warning (0, "GCC vector returned by reference: "
7992 "non-standard ABI extension with no compatibility guarantee");
7993 warned_for_return_big_vectors
= true;
7998 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
8004 #ifdef HAVE_AS_GNU_ATTRIBUTE
8005 /* Return TRUE if a call to function FNDECL may be one that
8006 potentially affects the function calling ABI of the object file. */
8009 call_ABI_of_interest (tree fndecl
)
8011 if (cgraph_state
== CGRAPH_STATE_EXPANSION
)
8013 struct cgraph_node
*c_node
;
8015 /* Libcalls are always interesting. */
8016 if (fndecl
== NULL_TREE
)
8019 /* Any call to an external function is interesting. */
8020 if (DECL_EXTERNAL (fndecl
))
8023 /* Interesting functions that we are emitting in this object file. */
8024 c_node
= cgraph_node (fndecl
);
8025 return !cgraph_only_called_directly_p (c_node
);
8031 /* Initialize a variable CUM of type CUMULATIVE_ARGS
8032 for a call to a function whose data type is FNTYPE.
8033 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
8035 For incoming args we set the number of arguments in the prototype large
8036 so we never return a PARALLEL. */
8039 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
8040 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
8041 int libcall
, int n_named_args
,
8042 tree fndecl ATTRIBUTE_UNUSED
,
8043 enum machine_mode return_mode ATTRIBUTE_UNUSED
)
8045 static CUMULATIVE_ARGS zero_cumulative
;
8047 *cum
= zero_cumulative
;
8049 cum
->fregno
= FP_ARG_MIN_REG
;
8050 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
8051 cum
->prototype
= (fntype
&& prototype_p (fntype
));
8052 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
8053 ? CALL_LIBCALL
: CALL_NORMAL
);
8054 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
8055 cum
->stdarg
= stdarg_p (fntype
);
8057 cum
->nargs_prototype
= 0;
8058 if (incoming
|| cum
->prototype
)
8059 cum
->nargs_prototype
= n_named_args
;
8061 /* Check for a longcall attribute. */
8062 if ((!fntype
&& rs6000_default_long_calls
)
8064 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
8065 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
8066 cum
->call_cookie
|= CALL_LONG
;
8068 if (TARGET_DEBUG_ARG
)
8070 fprintf (stderr
, "\ninit_cumulative_args:");
8073 tree ret_type
= TREE_TYPE (fntype
);
8074 fprintf (stderr
, " ret code = %s,",
8075 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
8078 if (cum
->call_cookie
& CALL_LONG
)
8079 fprintf (stderr
, " longcall,");
8081 fprintf (stderr
, " proto = %d, nargs = %d\n",
8082 cum
->prototype
, cum
->nargs_prototype
);
8085 #ifdef HAVE_AS_GNU_ATTRIBUTE
8086 if (DEFAULT_ABI
== ABI_V4
)
8088 cum
->escapes
= call_ABI_of_interest (fndecl
);
8095 return_type
= TREE_TYPE (fntype
);
8096 return_mode
= TYPE_MODE (return_type
);
8099 return_type
= lang_hooks
.types
.type_for_mode (return_mode
, 0);
8101 if (return_type
!= NULL
)
8103 if (TREE_CODE (return_type
) == RECORD_TYPE
8104 && TYPE_TRANSPARENT_AGGR (return_type
))
8106 return_type
= TREE_TYPE (first_field (return_type
));
8107 return_mode
= TYPE_MODE (return_type
);
8109 if (AGGREGATE_TYPE_P (return_type
)
8110 && ((unsigned HOST_WIDE_INT
) int_size_in_bytes (return_type
)
8112 rs6000_returns_struct
= true;
8114 if (SCALAR_FLOAT_MODE_P (return_mode
))
8115 rs6000_passes_float
= true;
8116 else if (ALTIVEC_VECTOR_MODE (return_mode
)
8117 || VSX_VECTOR_MODE (return_mode
)
8118 || SPE_VECTOR_MODE (return_mode
))
8119 rs6000_passes_vector
= true;
8126 && TARGET_ALTIVEC_ABI
8127 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
8129 error ("cannot return value in vector register because"
8130 " altivec instructions are disabled, use -maltivec"
8135 /* Return true if TYPE must be passed on the stack and not in registers. */
8138 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
8140 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
8141 return must_pass_in_stack_var_size (mode
, type
);
8143 return must_pass_in_stack_var_size_or_pad (mode
, type
);
8146 /* If defined, a C expression which determines whether, and in which
8147 direction, to pad out an argument with extra space. The value
8148 should be of type `enum direction': either `upward' to pad above
8149 the argument, `downward' to pad below, or `none' to inhibit
8152 For the AIX ABI structs are always stored left shifted in their
8156 function_arg_padding (enum machine_mode mode
, const_tree type
)
8158 #ifndef AGGREGATE_PADDING_FIXED
8159 #define AGGREGATE_PADDING_FIXED 0
8161 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8162 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8165 if (!AGGREGATE_PADDING_FIXED
)
8167 /* GCC used to pass structures of the same size as integer types as
8168 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8169 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8170 passed padded downward, except that -mstrict-align further
8171 muddied the water in that multi-component structures of 2 and 4
8172 bytes in size were passed padded upward.
8174 The following arranges for best compatibility with previous
8175 versions of gcc, but removes the -mstrict-align dependency. */
8176 if (BYTES_BIG_ENDIAN
)
8178 HOST_WIDE_INT size
= 0;
8180 if (mode
== BLKmode
)
8182 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
8183 size
= int_size_in_bytes (type
);
8186 size
= GET_MODE_SIZE (mode
);
8188 if (size
== 1 || size
== 2 || size
== 4)
8194 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
8196 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
8200 /* Fall back to the default. */
8201 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
8204 /* If defined, a C expression that gives the alignment boundary, in bits,
8205 of an argument with the specified mode and type. If it is not defined,
8206 PARM_BOUNDARY is used for all arguments.
8208 V.4 wants long longs and doubles to be double word aligned. Just
8209 testing the mode size is a boneheaded way to do this as it means
8210 that other types such as complex int are also double word aligned.
8211 However, we're stuck with this because changing the ABI might break
8212 existing library interfaces.
8214 Doubleword align SPE vectors.
8215 Quadword align Altivec vectors.
8216 Quadword align large synthetic vector types. */
8219 rs6000_function_arg_boundary (enum machine_mode mode
, const_tree type
)
8221 if (DEFAULT_ABI
== ABI_V4
8222 && (GET_MODE_SIZE (mode
) == 8
8223 || (TARGET_HARD_FLOAT
8225 && (mode
== TFmode
|| mode
== TDmode
))))
8227 else if (SPE_VECTOR_MODE (mode
)
8228 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8229 && int_size_in_bytes (type
) >= 8
8230 && int_size_in_bytes (type
) < 16))
8232 else if ((ALTIVEC_VECTOR_MODE (mode
) || VSX_VECTOR_MODE (mode
))
8233 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8234 && int_size_in_bytes (type
) >= 16))
8236 else if (TARGET_MACHO
8237 && rs6000_darwin64_abi
8239 && type
&& TYPE_ALIGN (type
) > 64)
8242 return PARM_BOUNDARY
;
8245 /* For a function parm of MODE and TYPE, return the starting word in
8246 the parameter area. NWORDS of the parameter area are already used. */
8249 rs6000_parm_start (enum machine_mode mode
, const_tree type
,
8250 unsigned int nwords
)
8253 unsigned int parm_offset
;
8255 align
= rs6000_function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
8256 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
8257 return nwords
+ (-(parm_offset
+ nwords
) & align
);
8260 /* Compute the size (in words) of a function argument. */
8262 static unsigned long
8263 rs6000_arg_size (enum machine_mode mode
, const_tree type
)
8267 if (mode
!= BLKmode
)
8268 size
= GET_MODE_SIZE (mode
);
8270 size
= int_size_in_bytes (type
);
8273 return (size
+ 3) >> 2;
8275 return (size
+ 7) >> 3;
8278 /* Use this to flush pending int fields. */
8281 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
8282 HOST_WIDE_INT bitpos
, int final
)
8284 unsigned int startbit
, endbit
;
8285 int intregs
, intoffset
;
8286 enum machine_mode mode
;
8288 /* Handle the situations where a float is taking up the first half
8289 of the GPR, and the other half is empty (typically due to
8290 alignment restrictions). We can detect this by a 8-byte-aligned
8291 int field, or by seeing that this is the final flush for this
8292 argument. Count the word and continue on. */
8293 if (cum
->floats_in_gpr
== 1
8294 && (cum
->intoffset
% 64 == 0
8295 || (cum
->intoffset
== -1 && final
)))
8298 cum
->floats_in_gpr
= 0;
8301 if (cum
->intoffset
== -1)
8304 intoffset
= cum
->intoffset
;
8305 cum
->intoffset
= -1;
8306 cum
->floats_in_gpr
= 0;
8308 if (intoffset
% BITS_PER_WORD
!= 0)
8310 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
8312 if (mode
== BLKmode
)
8314 /* We couldn't find an appropriate mode, which happens,
8315 e.g., in packed structs when there are 3 bytes to load.
8316 Back intoffset back to the beginning of the word in this
8318 intoffset
= intoffset
& -BITS_PER_WORD
;
8322 startbit
= intoffset
& -BITS_PER_WORD
;
8323 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
8324 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
8325 cum
->words
+= intregs
;
8326 /* words should be unsigned. */
8327 if ((unsigned)cum
->words
< (endbit
/BITS_PER_WORD
))
8329 int pad
= (endbit
/BITS_PER_WORD
) - cum
->words
;
8334 /* The darwin64 ABI calls for us to recurse down through structs,
8335 looking for elements passed in registers. Unfortunately, we have
8336 to track int register count here also because of misalignments
8337 in powerpc alignment mode. */
8340 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
8342 HOST_WIDE_INT startbitpos
)
8346 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
8347 if (TREE_CODE (f
) == FIELD_DECL
)
8349 HOST_WIDE_INT bitpos
= startbitpos
;
8350 tree ftype
= TREE_TYPE (f
);
8351 enum machine_mode mode
;
8352 if (ftype
== error_mark_node
)
8354 mode
= TYPE_MODE (ftype
);
8356 if (DECL_SIZE (f
) != 0
8357 && host_integerp (bit_position (f
), 1))
8358 bitpos
+= int_bit_position (f
);
8360 /* ??? FIXME: else assume zero offset. */
8362 if (TREE_CODE (ftype
) == RECORD_TYPE
)
8363 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
8364 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
8366 unsigned n_fpregs
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8367 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
8368 cum
->fregno
+= n_fpregs
;
8369 /* Single-precision floats present a special problem for
8370 us, because they are smaller than an 8-byte GPR, and so
8371 the structure-packing rules combined with the standard
8372 varargs behavior mean that we want to pack float/float
8373 and float/int combinations into a single register's
8374 space. This is complicated by the arg advance flushing,
8375 which works on arbitrarily large groups of int-type
8379 if (cum
->floats_in_gpr
== 1)
8381 /* Two floats in a word; count the word and reset
8384 cum
->floats_in_gpr
= 0;
8386 else if (bitpos
% 64 == 0)
8388 /* A float at the beginning of an 8-byte word;
8389 count it and put off adjusting cum->words until
8390 we see if a arg advance flush is going to do it
8392 cum
->floats_in_gpr
++;
8396 /* The float is at the end of a word, preceded
8397 by integer fields, so the arg advance flush
8398 just above has already set cum->words and
8399 everything is taken care of. */
8403 cum
->words
+= n_fpregs
;
8405 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
8407 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
8411 else if (cum
->intoffset
== -1)
8412 cum
->intoffset
= bitpos
;
8416 /* Check for an item that needs to be considered specially under the darwin 64
8417 bit ABI. These are record types where the mode is BLK or the structure is
8420 rs6000_darwin64_struct_check_p (enum machine_mode mode
, const_tree type
)
8422 return rs6000_darwin64_abi
8423 && ((mode
== BLKmode
8424 && TREE_CODE (type
) == RECORD_TYPE
8425 && int_size_in_bytes (type
) > 0)
8426 || (type
&& TREE_CODE (type
) == RECORD_TYPE
8427 && int_size_in_bytes (type
) == 8)) ? 1 : 0;
8430 /* Update the data in CUM to advance over an argument
8431 of mode MODE and data type TYPE.
8432 (TYPE is null for libcalls where that information may not be available.)
8434 Note that for args passed by reference, function_arg will be called
8435 with MODE and TYPE set to that of the pointer to the arg, not the arg
8439 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8440 const_tree type
, bool named
, int depth
)
8442 /* Only tick off an argument if we're not recursing. */
8444 cum
->nargs_prototype
--;
8446 #ifdef HAVE_AS_GNU_ATTRIBUTE
8447 if (DEFAULT_ABI
== ABI_V4
8450 if (SCALAR_FLOAT_MODE_P (mode
))
8451 rs6000_passes_float
= true;
8452 else if (named
&& (ALTIVEC_VECTOR_MODE (mode
) || VSX_VECTOR_MODE (mode
)))
8453 rs6000_passes_vector
= true;
8454 else if (SPE_VECTOR_MODE (mode
)
8456 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
8457 rs6000_passes_vector
= true;
8461 if (TARGET_ALTIVEC_ABI
8462 && (ALTIVEC_VECTOR_MODE (mode
)
8463 || VSX_VECTOR_MODE (mode
)
8464 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8465 && int_size_in_bytes (type
) == 16)))
8469 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
8472 if (!TARGET_ALTIVEC
)
8473 error ("cannot pass argument in vector register because"
8474 " altivec instructions are disabled, use -maltivec"
8477 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8478 even if it is going to be passed in a vector register.
8479 Darwin does the same for variable-argument functions. */
8480 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
8481 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
8491 /* Vector parameters must be 16-byte aligned. This places
8492 them at 2 mod 4 in terms of words in 32-bit mode, since
8493 the parameter save area starts at offset 24 from the
8494 stack. In 64-bit mode, they just have to start on an
8495 even word, since the parameter save area is 16-byte
8496 aligned. Space for GPRs is reserved even if the argument
8497 will be passed in memory. */
8499 align
= (2 - cum
->words
) & 3;
8501 align
= cum
->words
& 1;
8502 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
8504 if (TARGET_DEBUG_ARG
)
8506 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
8508 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
8509 cum
->nargs_prototype
, cum
->prototype
,
8510 GET_MODE_NAME (mode
));
8514 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
8516 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
8519 else if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8521 int size
= int_size_in_bytes (type
);
8522 /* Variable sized types have size == -1 and are
8523 treated as if consisting entirely of ints.
8524 Pad to 16 byte boundary if needed. */
8525 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8526 && (cum
->words
% 2) != 0)
8528 /* For varargs, we can just go up by the size of the struct. */
8530 cum
->words
+= (size
+ 7) / 8;
8533 /* It is tempting to say int register count just goes up by
8534 sizeof(type)/8, but this is wrong in a case such as
8535 { int; double; int; } [powerpc alignment]. We have to
8536 grovel through the fields for these too. */
8538 cum
->floats_in_gpr
= 0;
8539 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
8540 rs6000_darwin64_record_arg_advance_flush (cum
,
8541 size
* BITS_PER_UNIT
, 1);
8543 if (TARGET_DEBUG_ARG
)
8545 fprintf (stderr
, "function_adv: words = %2d, align=%d, size=%d",
8546 cum
->words
, TYPE_ALIGN (type
), size
);
8548 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8549 cum
->nargs_prototype
, cum
->prototype
,
8550 GET_MODE_NAME (mode
));
8553 else if (DEFAULT_ABI
== ABI_V4
)
8555 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8556 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
8557 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
8558 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
8559 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8561 /* _Decimal128 must use an even/odd register pair. This assumes
8562 that the register number is odd when fregno is odd. */
8563 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8566 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
8567 <= FP_ARG_V4_MAX_REG
)
8568 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8571 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
8572 if (mode
== DFmode
|| mode
== TFmode
8573 || mode
== DDmode
|| mode
== TDmode
)
8574 cum
->words
+= cum
->words
& 1;
8575 cum
->words
+= rs6000_arg_size (mode
, type
);
8580 int n_words
= rs6000_arg_size (mode
, type
);
8581 int gregno
= cum
->sysv_gregno
;
8583 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8584 (r7,r8) or (r9,r10). As does any other 2 word item such
8585 as complex int due to a historical mistake. */
8587 gregno
+= (1 - gregno
) & 1;
8589 /* Multi-reg args are not split between registers and stack. */
8590 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8592 /* Long long and SPE vectors are aligned on the stack.
8593 So are other 2 word items such as complex int due to
8594 a historical mistake. */
8596 cum
->words
+= cum
->words
& 1;
8597 cum
->words
+= n_words
;
8600 /* Note: continuing to accumulate gregno past when we've started
8601 spilling to the stack indicates the fact that we've started
8602 spilling to the stack to expand_builtin_saveregs. */
8603 cum
->sysv_gregno
= gregno
+ n_words
;
8606 if (TARGET_DEBUG_ARG
)
8608 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8609 cum
->words
, cum
->fregno
);
8610 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
8611 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
8612 fprintf (stderr
, "mode = %4s, named = %d\n",
8613 GET_MODE_NAME (mode
), named
);
8618 int n_words
= rs6000_arg_size (mode
, type
);
8619 int start_words
= cum
->words
;
8620 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
8622 cum
->words
= align_words
+ n_words
;
8624 if (SCALAR_FLOAT_MODE_P (mode
)
8625 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8627 /* _Decimal128 must be passed in an even/odd float register pair.
8628 This assumes that the register number is odd when fregno is
8630 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8632 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8635 if (TARGET_DEBUG_ARG
)
8637 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8638 cum
->words
, cum
->fregno
);
8639 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
8640 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
8641 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
8642 named
, align_words
- start_words
, depth
);
8648 rs6000_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8649 const_tree type
, bool named
)
8651 rs6000_function_arg_advance_1 (cum
, mode
, type
, named
, 0);
8655 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
8662 r1
= gen_rtx_REG (DImode
, gregno
);
8663 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8664 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
8668 r1
= gen_rtx_REG (DImode
, gregno
);
8669 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8670 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8671 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8672 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
8675 r1
= gen_rtx_REG (DImode
, gregno
);
8676 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8677 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8678 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8679 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
8680 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
8681 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
8682 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
8683 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
8690 /* Determine where to put a SIMD argument on the SPE. */
8692 rs6000_spe_function_arg (const CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8695 int gregno
= cum
->sysv_gregno
;
8697 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8698 are passed and returned in a pair of GPRs for ABI compatibility. */
8699 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
8700 || mode
== DCmode
|| mode
== TCmode
))
8702 int n_words
= rs6000_arg_size (mode
, type
);
8704 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8706 gregno
+= (1 - gregno
) & 1;
8708 /* Multi-reg args are not split between registers and stack. */
8709 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8712 return spe_build_register_parallel (mode
, gregno
);
8716 int n_words
= rs6000_arg_size (mode
, type
);
8718 /* SPE vectors are put in odd registers. */
8719 if (n_words
== 2 && (gregno
& 1) == 0)
8722 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
8725 enum machine_mode m
= SImode
;
8727 r1
= gen_rtx_REG (m
, gregno
);
8728 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
8729 r2
= gen_rtx_REG (m
, gregno
+ 1);
8730 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
8731 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
8738 if (gregno
<= GP_ARG_MAX_REG
)
8739 return gen_rtx_REG (mode
, gregno
);
8745 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8746 structure between cum->intoffset and bitpos to integer registers. */
8749 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
8750 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
8752 enum machine_mode mode
;
8754 unsigned int startbit
, endbit
;
8755 int this_regno
, intregs
, intoffset
;
8758 if (cum
->intoffset
== -1)
8761 intoffset
= cum
->intoffset
;
8762 cum
->intoffset
= -1;
8764 /* If this is the trailing part of a word, try to only load that
8765 much into the register. Otherwise load the whole register. Note
8766 that in the latter case we may pick up unwanted bits. It's not a
8767 problem at the moment but may wish to revisit. */
8769 if (intoffset
% BITS_PER_WORD
!= 0)
8771 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
8773 if (mode
== BLKmode
)
8775 /* We couldn't find an appropriate mode, which happens,
8776 e.g., in packed structs when there are 3 bytes to load.
8777 Back intoffset back to the beginning of the word in this
8779 intoffset
= intoffset
& -BITS_PER_WORD
;
8786 startbit
= intoffset
& -BITS_PER_WORD
;
8787 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
8788 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
8789 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
8791 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
8794 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
8798 intoffset
/= BITS_PER_UNIT
;
8801 regno
= GP_ARG_MIN_REG
+ this_regno
;
8802 reg
= gen_rtx_REG (mode
, regno
);
8804 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
8807 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
8811 while (intregs
> 0);
8814 /* Recursive workhorse for the following. */
8817 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
8818 HOST_WIDE_INT startbitpos
, rtx rvec
[],
8823 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
8824 if (TREE_CODE (f
) == FIELD_DECL
)
8826 HOST_WIDE_INT bitpos
= startbitpos
;
8827 tree ftype
= TREE_TYPE (f
);
8828 enum machine_mode mode
;
8829 if (ftype
== error_mark_node
)
8831 mode
= TYPE_MODE (ftype
);
8833 if (DECL_SIZE (f
) != 0
8834 && host_integerp (bit_position (f
), 1))
8835 bitpos
+= int_bit_position (f
);
8837 /* ??? FIXME: else assume zero offset. */
8839 if (TREE_CODE (ftype
) == RECORD_TYPE
)
8840 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
8841 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
8843 unsigned n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8847 case SCmode
: mode
= SFmode
; break;
8848 case DCmode
: mode
= DFmode
; break;
8849 case TCmode
: mode
= TFmode
; break;
8853 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8854 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
8856 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
8857 && (mode
== TFmode
|| mode
== TDmode
));
8858 /* Long double or _Decimal128 split over regs and memory. */
8859 mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
8863 = gen_rtx_EXPR_LIST (VOIDmode
,
8864 gen_rtx_REG (mode
, cum
->fregno
++),
8865 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8866 if (mode
== TFmode
|| mode
== TDmode
)
8869 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
8871 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8873 = gen_rtx_EXPR_LIST (VOIDmode
,
8874 gen_rtx_REG (mode
, cum
->vregno
++),
8875 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8877 else if (cum
->intoffset
== -1)
8878 cum
->intoffset
= bitpos
;
8882 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8883 the register(s) to be used for each field and subfield of a struct
8884 being passed by value, along with the offset of where the
8885 register's value may be found in the block. FP fields go in FP
8886 register, vector fields go in vector registers, and everything
8887 else goes in int registers, packed as in memory.
8889 This code is also used for function return values. RETVAL indicates
8890 whether this is the case.
8892 Much of this is taken from the SPARC V9 port, which has a similar
8893 calling convention. */
8896 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
8897 bool named
, bool retval
)
8899 rtx rvec
[FIRST_PSEUDO_REGISTER
];
8900 int k
= 1, kbase
= 1;
8901 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
8902 /* This is a copy; modifications are not visible to our caller. */
8903 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
8904 CUMULATIVE_ARGS
*cum
= ©_cum
;
8906 /* Pad to 16 byte boundary if needed. */
8907 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8908 && (cum
->words
% 2) != 0)
8915 /* Put entries into rvec[] for individual FP and vector fields, and
8916 for the chunks of memory that go in int regs. Note we start at
8917 element 1; 0 is reserved for an indication of using memory, and
8918 may or may not be filled in below. */
8919 rs6000_darwin64_record_arg_recurse (cum
, type
, /* startbit pos= */ 0, rvec
, &k
);
8920 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
8922 /* If any part of the struct went on the stack put all of it there.
8923 This hack is because the generic code for
8924 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8925 parts of the struct are not at the beginning. */
8929 return NULL_RTX
; /* doesn't go in registers at all */
8931 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8933 if (k
> 1 || cum
->use_stack
)
8934 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
8939 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8942 rs6000_mixed_function_arg (enum machine_mode mode
, const_tree type
,
8947 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8949 if (align_words
>= GP_ARG_NUM_REG
)
8952 n_units
= rs6000_arg_size (mode
, type
);
8954 /* Optimize the simple case where the arg fits in one gpr, except in
8955 the case of BLKmode due to assign_parms assuming that registers are
8956 BITS_PER_WORD wide. */
8958 || (n_units
== 1 && mode
!= BLKmode
))
8959 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8962 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
8963 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8964 using a magic NULL_RTX component.
8965 This is not strictly correct. Only some of the arg belongs in
8966 memory, not all of it. However, the normal scheme using
8967 function_arg_partial_nregs can result in unusual subregs, eg.
8968 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8969 store the whole arg to memory is often more efficient than code
8970 to store pieces, and we know that space is available in the right
8971 place for the whole arg. */
8972 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8977 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
8978 rtx off
= GEN_INT (i
++ * 4);
8979 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8981 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
8983 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8986 /* Determine where to put an argument to a function.
8987 Value is zero to push the argument on the stack,
8988 or a hard register in which to store the argument.
8990 MODE is the argument's machine mode.
8991 TYPE is the data type of the argument (as a tree).
8992 This is null for libcalls where that information may
8994 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8995 the preceding args and about the function being called. It is
8996 not modified in this routine.
8997 NAMED is nonzero if this argument is a named parameter
8998 (otherwise it is an extra parameter matching an ellipsis).
9000 On RS/6000 the first eight words of non-FP are normally in registers
9001 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
9002 Under V.4, the first 8 FP args are in registers.
9004 If this is floating-point and no prototype is specified, we use
9005 both an FP and integer register (or possibly FP reg and stack). Library
9006 functions (when CALL_LIBCALL is set) always have the proper types for args,
9007 so we can pass the FP value just in one register. emit_library_function
9008 doesn't support PARALLEL anyway.
9010 Note that for args passed by reference, function_arg will be called
9011 with MODE and TYPE set to that of the pointer to the arg, not the arg
9015 rs6000_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
9016 const_tree type
, bool named
)
9018 enum rs6000_abi abi
= DEFAULT_ABI
;
9020 /* Return a marker to indicate whether CR1 needs to set or clear the
9021 bit that V.4 uses to say fp args were passed in registers.
9022 Assume that we don't need the marker for software floating point,
9023 or compiler generated library calls. */
9024 if (mode
== VOIDmode
)
9027 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
9029 || (cum
->nargs_prototype
< 0
9030 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
9032 /* For the SPE, we need to crxor CR6 always. */
9034 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
9035 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
9036 return GEN_INT (cum
->call_cookie
9037 | ((cum
->fregno
== FP_ARG_MIN_REG
)
9038 ? CALL_V4_SET_FP_ARGS
9039 : CALL_V4_CLEAR_FP_ARGS
));
9042 return GEN_INT (cum
->call_cookie
);
9045 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
9047 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, /*retval= */false);
9048 if (rslt
!= NULL_RTX
)
9050 /* Else fall through to usual handling. */
9053 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
9054 if (TARGET_64BIT
&& ! cum
->prototype
)
9056 /* Vector parameters get passed in vector register
9057 and also in GPRs or memory, in absence of prototype. */
9060 align_words
= (cum
->words
+ 1) & ~1;
9062 if (align_words
>= GP_ARG_NUM_REG
)
9068 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
9070 return gen_rtx_PARALLEL (mode
,
9072 gen_rtx_EXPR_LIST (VOIDmode
,
9074 gen_rtx_EXPR_LIST (VOIDmode
,
9075 gen_rtx_REG (mode
, cum
->vregno
),
9079 return gen_rtx_REG (mode
, cum
->vregno
);
9080 else if (TARGET_ALTIVEC_ABI
9081 && (ALTIVEC_VECTOR_MODE (mode
)
9082 || VSX_VECTOR_MODE (mode
)
9083 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
9084 && int_size_in_bytes (type
) == 16)))
9086 if (named
|| abi
== ABI_V4
)
9090 /* Vector parameters to varargs functions under AIX or Darwin
9091 get passed in memory and possibly also in GPRs. */
9092 int align
, align_words
, n_words
;
9093 enum machine_mode part_mode
;
9095 /* Vector parameters must be 16-byte aligned. This places them at
9096 2 mod 4 in terms of words in 32-bit mode, since the parameter
9097 save area starts at offset 24 from the stack. In 64-bit mode,
9098 they just have to start on an even word, since the parameter
9099 save area is 16-byte aligned. */
9101 align
= (2 - cum
->words
) & 3;
9103 align
= cum
->words
& 1;
9104 align_words
= cum
->words
+ align
;
9106 /* Out of registers? Memory, then. */
9107 if (align_words
>= GP_ARG_NUM_REG
)
9110 if (TARGET_32BIT
&& TARGET_POWERPC64
)
9111 return rs6000_mixed_function_arg (mode
, type
, align_words
);
9113 /* The vector value goes in GPRs. Only the part of the
9114 value in GPRs is reported here. */
9116 n_words
= rs6000_arg_size (mode
, type
);
9117 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
9118 /* Fortunately, there are only two possibilities, the value
9119 is either wholly in GPRs or half in GPRs and half not. */
9122 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
9125 else if (TARGET_SPE_ABI
&& TARGET_SPE
9126 && (SPE_VECTOR_MODE (mode
)
9127 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
9130 || mode
== TCmode
))))
9131 return rs6000_spe_function_arg (cum
, mode
, type
);
9133 else if (abi
== ABI_V4
)
9135 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9136 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
9137 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
9138 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
9139 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
9141 /* _Decimal128 must use an even/odd register pair. This assumes
9142 that the register number is odd when fregno is odd. */
9143 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
9146 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
9147 <= FP_ARG_V4_MAX_REG
)
9148 return gen_rtx_REG (mode
, cum
->fregno
);
9154 int n_words
= rs6000_arg_size (mode
, type
);
9155 int gregno
= cum
->sysv_gregno
;
9157 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9158 (r7,r8) or (r9,r10). As does any other 2 word item such
9159 as complex int due to a historical mistake. */
9161 gregno
+= (1 - gregno
) & 1;
9163 /* Multi-reg args are not split between registers and stack. */
9164 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
9167 if (TARGET_32BIT
&& TARGET_POWERPC64
)
9168 return rs6000_mixed_function_arg (mode
, type
,
9169 gregno
- GP_ARG_MIN_REG
);
9170 return gen_rtx_REG (mode
, gregno
);
9175 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
9177 /* _Decimal128 must be passed in an even/odd float register pair.
9178 This assumes that the register number is odd when fregno is odd. */
9179 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
9182 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
9184 rtx rvec
[GP_ARG_NUM_REG
+ 1];
9188 enum machine_mode fmode
= mode
;
9189 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
9191 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
9193 /* Currently, we only ever need one reg here because complex
9194 doubles are split. */
9195 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
9196 && (fmode
== TFmode
|| fmode
== TDmode
));
9198 /* Long double or _Decimal128 split over regs and memory. */
9199 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
9202 /* Do we also need to pass this arg in the parameter save
9205 && (cum
->nargs_prototype
<= 0
9206 || (DEFAULT_ABI
== ABI_AIX
9208 && align_words
>= GP_ARG_NUM_REG
)));
9210 if (!needs_psave
&& mode
== fmode
)
9211 return gen_rtx_REG (fmode
, cum
->fregno
);
9216 /* Describe the part that goes in gprs or the stack.
9217 This piece must come first, before the fprs. */
9218 if (align_words
< GP_ARG_NUM_REG
)
9220 unsigned long n_words
= rs6000_arg_size (mode
, type
);
9222 if (align_words
+ n_words
> GP_ARG_NUM_REG
9223 || (TARGET_32BIT
&& TARGET_POWERPC64
))
9225 /* If this is partially on the stack, then we only
9226 include the portion actually in registers here. */
9227 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
9230 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
9231 /* Not all of the arg fits in gprs. Say that it
9232 goes in memory too, using a magic NULL_RTX
9233 component. Also see comment in
9234 rs6000_mixed_function_arg for why the normal
9235 function_arg_partial_nregs scheme doesn't work
9237 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
9241 r
= gen_rtx_REG (rmode
,
9242 GP_ARG_MIN_REG
+ align_words
);
9243 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
9244 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
9246 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
9250 /* The whole arg fits in gprs. */
9251 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
9252 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
9256 /* It's entirely in memory. */
9257 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
9260 /* Describe where this piece goes in the fprs. */
9261 r
= gen_rtx_REG (fmode
, cum
->fregno
);
9262 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
9264 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
9266 else if (align_words
< GP_ARG_NUM_REG
)
9268 if (TARGET_32BIT
&& TARGET_POWERPC64
)
9269 return rs6000_mixed_function_arg (mode
, type
, align_words
);
9271 if (mode
== BLKmode
)
9274 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
9281 /* For an arg passed partly in registers and partly in memory, this is
9282 the number of bytes passed in registers. For args passed entirely in
9283 registers or entirely in memory, zero. When an arg is described by a
9284 PARALLEL, perhaps using more than one register type, this function
9285 returns the number of bytes used by the first element of the PARALLEL. */
9288 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
9289 tree type
, bool named
)
9294 if (DEFAULT_ABI
== ABI_V4
)
9297 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
9298 && cum
->nargs_prototype
>= 0)
9301 /* In this complicated case we just disable the partial_nregs code. */
9302 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
9305 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
9307 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
9309 /* If we are passing this arg in the fixed parameter save area
9310 (gprs or memory) as well as fprs, then this function should
9311 return the number of partial bytes passed in the parameter
9312 save area rather than partial bytes passed in fprs. */
9314 && (cum
->nargs_prototype
<= 0
9315 || (DEFAULT_ABI
== ABI_AIX
9317 && align_words
>= GP_ARG_NUM_REG
)))
9319 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
9320 > FP_ARG_MAX_REG
+ 1)
9321 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
9322 else if (cum
->nargs_prototype
>= 0)
9326 if (align_words
< GP_ARG_NUM_REG
9327 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
9328 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
9330 if (ret
!= 0 && TARGET_DEBUG_ARG
)
9331 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
9336 /* A C expression that indicates when an argument must be passed by
9337 reference. If nonzero for an argument, a copy of that argument is
9338 made in memory and a pointer to the argument is passed instead of
9339 the argument itself. The pointer is passed in whatever way is
9340 appropriate for passing a pointer to that type.
9342 Under V.4, aggregates and long double are passed by reference.
9344 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9345 reference unless the AltiVec vector extension ABI is in force.
9347 As an extension to all ABIs, variable sized types are passed by
9351 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
9352 enum machine_mode mode
, const_tree type
,
9353 bool named ATTRIBUTE_UNUSED
)
9355 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
9357 if (TARGET_DEBUG_ARG
)
9358 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
9365 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
9367 if (TARGET_DEBUG_ARG
)
9368 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
9372 if (int_size_in_bytes (type
) < 0)
9374 if (TARGET_DEBUG_ARG
)
9375 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
9379 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9380 modes only exist for GCC vector types if -maltivec. */
9381 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
9383 if (TARGET_DEBUG_ARG
)
9384 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
9388 /* Pass synthetic vectors in memory. */
9389 if (TREE_CODE (type
) == VECTOR_TYPE
9390 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
9392 static bool warned_for_pass_big_vectors
= false;
9393 if (TARGET_DEBUG_ARG
)
9394 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
9395 if (!warned_for_pass_big_vectors
)
9397 warning (0, "GCC vector passed by reference: "
9398 "non-standard ABI extension with no compatibility guarantee");
9399 warned_for_pass_big_vectors
= true;
9408 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
9411 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
9416 for (i
= 0; i
< nregs
; i
++)
9418 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
9419 if (reload_completed
)
9421 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
9424 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
9425 i
* GET_MODE_SIZE (reg_mode
));
9428 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
9432 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
9436 /* Perform any needed actions needed for a function that is receiving a
9437 variable number of arguments.
9441 MODE and TYPE are the mode and type of the current parameter.
9443 PRETEND_SIZE is a variable that should be set to the amount of stack
9444 that must be pushed by the prolog to pretend that our caller pushed
9447 Normally, this macro will push all remaining incoming registers on the
9448 stack and set PRETEND_SIZE to the length of the registers pushed. */
9451 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
9452 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
9455 CUMULATIVE_ARGS next_cum
;
9456 int reg_size
= TARGET_32BIT
? 4 : 8;
9457 rtx save_area
= NULL_RTX
, mem
;
9458 int first_reg_offset
;
9461 /* Skip the last named argument. */
9463 rs6000_function_arg_advance_1 (&next_cum
, mode
, type
, true, 0);
9465 if (DEFAULT_ABI
== ABI_V4
)
9467 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
9471 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
9472 HOST_WIDE_INT offset
= 0;
9474 /* Try to optimize the size of the varargs save area.
9475 The ABI requires that ap.reg_save_area is doubleword
9476 aligned, but we don't need to allocate space for all
9477 the bytes, only those to which we actually will save
9479 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
9480 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
9481 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9482 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
9483 && cfun
->va_list_fpr_size
)
9486 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
9487 * UNITS_PER_FP_WORD
;
9488 if (cfun
->va_list_fpr_size
9489 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
9490 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
9492 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
9493 * UNITS_PER_FP_WORD
;
9497 offset
= -((first_reg_offset
* reg_size
) & ~7);
9498 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
9500 gpr_reg_num
= cfun
->va_list_gpr_size
;
9501 if (reg_size
== 4 && (first_reg_offset
& 1))
9504 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
9507 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
9509 - (int) (GP_ARG_NUM_REG
* reg_size
);
9511 if (gpr_size
+ fpr_size
)
9514 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
9515 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
9516 reg_save_area
= XEXP (reg_save_area
, 0);
9517 if (GET_CODE (reg_save_area
) == PLUS
)
9519 gcc_assert (XEXP (reg_save_area
, 0)
9520 == virtual_stack_vars_rtx
);
9521 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
9522 offset
+= INTVAL (XEXP (reg_save_area
, 1));
9525 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
9528 cfun
->machine
->varargs_save_offset
= offset
;
9529 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
9534 first_reg_offset
= next_cum
.words
;
9535 save_area
= virtual_incoming_args_rtx
;
9537 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
9538 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
9541 set
= get_varargs_alias_set ();
9542 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
9543 && cfun
->va_list_gpr_size
)
9545 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
9547 if (va_list_gpr_counter_field
)
9549 /* V4 va_list_gpr_size counts number of registers needed. */
9550 if (nregs
> cfun
->va_list_gpr_size
)
9551 nregs
= cfun
->va_list_gpr_size
;
9555 /* char * va_list instead counts number of bytes needed. */
9556 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
9557 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
9560 mem
= gen_rtx_MEM (BLKmode
,
9561 plus_constant (save_area
,
9562 first_reg_offset
* reg_size
));
9563 MEM_NOTRAP_P (mem
) = 1;
9564 set_mem_alias_set (mem
, set
);
9565 set_mem_align (mem
, BITS_PER_WORD
);
9567 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
9571 /* Save FP registers if needed. */
9572 if (DEFAULT_ABI
== ABI_V4
9573 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9575 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
9576 && cfun
->va_list_fpr_size
)
9578 int fregno
= next_cum
.fregno
, nregs
;
9579 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
9580 rtx lab
= gen_label_rtx ();
9581 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
9582 * UNITS_PER_FP_WORD
);
9585 (gen_rtx_SET (VOIDmode
,
9587 gen_rtx_IF_THEN_ELSE (VOIDmode
,
9588 gen_rtx_NE (VOIDmode
, cr1
,
9590 gen_rtx_LABEL_REF (VOIDmode
, lab
),
9594 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
9595 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
9597 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9599 plus_constant (save_area
, off
));
9600 MEM_NOTRAP_P (mem
) = 1;
9601 set_mem_alias_set (mem
, set
);
9602 set_mem_align (mem
, GET_MODE_ALIGNMENT (
9603 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9604 ? DFmode
: SFmode
));
9605 emit_move_insn (mem
, gen_rtx_REG (
9606 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9607 ? DFmode
: SFmode
, fregno
));
9614 /* Create the va_list data type. */
9617 rs6000_build_builtin_va_list (void)
9619 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
9621 /* For AIX, prefer 'char *' because that's what the system
9622 header files like. */
9623 if (DEFAULT_ABI
!= ABI_V4
)
9624 return build_pointer_type (char_type_node
);
9626 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
9627 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9628 get_identifier ("__va_list_tag"), record
);
9630 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
9631 unsigned_char_type_node
);
9632 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
9633 unsigned_char_type_node
);
9634 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9636 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9637 get_identifier ("reserved"), short_unsigned_type_node
);
9638 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9639 get_identifier ("overflow_arg_area"),
9641 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9642 get_identifier ("reg_save_area"),
9645 va_list_gpr_counter_field
= f_gpr
;
9646 va_list_fpr_counter_field
= f_fpr
;
9648 DECL_FIELD_CONTEXT (f_gpr
) = record
;
9649 DECL_FIELD_CONTEXT (f_fpr
) = record
;
9650 DECL_FIELD_CONTEXT (f_res
) = record
;
9651 DECL_FIELD_CONTEXT (f_ovf
) = record
;
9652 DECL_FIELD_CONTEXT (f_sav
) = record
;
9654 TYPE_STUB_DECL (record
) = type_decl
;
9655 TYPE_NAME (record
) = type_decl
;
9656 TYPE_FIELDS (record
) = f_gpr
;
9657 DECL_CHAIN (f_gpr
) = f_fpr
;
9658 DECL_CHAIN (f_fpr
) = f_res
;
9659 DECL_CHAIN (f_res
) = f_ovf
;
9660 DECL_CHAIN (f_ovf
) = f_sav
;
9662 layout_type (record
);
9664 /* The correct type is an array type of one element. */
9665 return build_array_type (record
, build_index_type (size_zero_node
));
9668 /* Implement va_start. */
9671 rs6000_va_start (tree valist
, rtx nextarg
)
9673 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
9674 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9675 tree gpr
, fpr
, ovf
, sav
, t
;
9677 /* Only SVR4 needs something special. */
9678 if (DEFAULT_ABI
!= ABI_V4
)
9680 std_expand_builtin_va_start (valist
, nextarg
);
9684 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9685 f_fpr
= DECL_CHAIN (f_gpr
);
9686 f_res
= DECL_CHAIN (f_fpr
);
9687 f_ovf
= DECL_CHAIN (f_res
);
9688 f_sav
= DECL_CHAIN (f_ovf
);
9690 valist
= build_simple_mem_ref (valist
);
9691 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9692 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9694 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9696 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9699 /* Count number of gp and fp argument registers used. */
9700 words
= crtl
->args
.info
.words
;
9701 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
9703 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
9706 if (TARGET_DEBUG_ARG
)
9707 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
9708 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
9709 words
, n_gpr
, n_fpr
);
9711 if (cfun
->va_list_gpr_size
)
9713 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
9714 build_int_cst (NULL_TREE
, n_gpr
));
9715 TREE_SIDE_EFFECTS (t
) = 1;
9716 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9719 if (cfun
->va_list_fpr_size
)
9721 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
9722 build_int_cst (NULL_TREE
, n_fpr
));
9723 TREE_SIDE_EFFECTS (t
) = 1;
9724 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9726 #ifdef HAVE_AS_GNU_ATTRIBUTE
9727 if (call_ABI_of_interest (cfun
->decl
))
9728 rs6000_passes_float
= true;
9732 /* Find the overflow area. */
9733 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
9735 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
9736 size_int (words
* UNITS_PER_WORD
));
9737 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
9738 TREE_SIDE_EFFECTS (t
) = 1;
9739 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9741 /* If there were no va_arg invocations, don't set up the register
9743 if (!cfun
->va_list_gpr_size
9744 && !cfun
->va_list_fpr_size
9745 && n_gpr
< GP_ARG_NUM_REG
9746 && n_fpr
< FP_ARG_V4_MAX_REG
)
9749 /* Find the register save area. */
9750 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
9751 if (cfun
->machine
->varargs_save_offset
)
9752 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
9753 size_int (cfun
->machine
->varargs_save_offset
));
9754 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
9755 TREE_SIDE_EFFECTS (t
) = 1;
9756 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9759 /* Implement va_arg. */
9762 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
9765 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9766 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
9767 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
9768 tree lab_false
, lab_over
, addr
;
9770 tree ptrtype
= build_pointer_type_for_mode (type
, ptr_mode
, true);
9774 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
9776 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
9777 return build_va_arg_indirect_ref (t
);
9780 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9781 earlier version of gcc, with the property that it always applied alignment
9782 adjustments to the va-args (even for zero-sized types). The cheapest way
9783 to deal with this is to replicate the effect of the part of
9784 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9786 We don't need to check for pass-by-reference because of the test above.
9787 We can return a simplifed answer, since we know there's no offset to add. */
9790 && rs6000_darwin64_abi
9791 && integer_zerop (TYPE_SIZE (type
)))
9793 unsigned HOST_WIDE_INT align
, boundary
;
9794 tree valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
9795 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
9796 boundary
= rs6000_function_arg_boundary (TYPE_MODE (type
), type
);
9797 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
9798 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
9799 boundary
/= BITS_PER_UNIT
;
9800 if (boundary
> align
)
9803 /* This updates arg ptr by the amount that would be necessary
9804 to align the zero-sized (but not zero-alignment) item. */
9805 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9806 fold_build2 (POINTER_PLUS_EXPR
,
9808 valist_tmp
, size_int (boundary
- 1)));
9809 gimplify_and_add (t
, pre_p
);
9811 t
= fold_convert (sizetype
, valist_tmp
);
9812 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9813 fold_convert (TREE_TYPE (valist
),
9814 fold_build2 (BIT_AND_EXPR
, sizetype
, t
,
9815 size_int (-boundary
))));
9816 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
9817 gimplify_and_add (t
, pre_p
);
9819 /* Since it is zero-sized there's no increment for the item itself. */
9820 valist_tmp
= fold_convert (build_pointer_type (type
), valist_tmp
);
9821 return build_va_arg_indirect_ref (valist_tmp
);
9824 if (DEFAULT_ABI
!= ABI_V4
)
9826 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
9828 tree elem_type
= TREE_TYPE (type
);
9829 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
9830 int elem_size
= GET_MODE_SIZE (elem_mode
);
9832 if (elem_size
< UNITS_PER_WORD
)
9834 tree real_part
, imag_part
;
9835 gimple_seq post
= NULL
;
9837 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9839 /* Copy the value into a temporary, lest the formal temporary
9840 be reused out from under us. */
9841 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
9842 gimple_seq_add_seq (pre_p
, post
);
9844 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9847 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
9851 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
9854 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9855 f_fpr
= DECL_CHAIN (f_gpr
);
9856 f_res
= DECL_CHAIN (f_fpr
);
9857 f_ovf
= DECL_CHAIN (f_res
);
9858 f_sav
= DECL_CHAIN (f_ovf
);
9860 valist
= build_va_arg_indirect_ref (valist
);
9861 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9862 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9864 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9866 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9869 size
= int_size_in_bytes (type
);
9870 rsize
= (size
+ 3) / 4;
9873 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9874 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
9875 || (TARGET_DOUBLE_FLOAT
9876 && (TYPE_MODE (type
) == DFmode
9877 || TYPE_MODE (type
) == TFmode
9878 || TYPE_MODE (type
) == SDmode
9879 || TYPE_MODE (type
) == DDmode
9880 || TYPE_MODE (type
) == TDmode
))))
9882 /* FP args go in FP registers, if present. */
9884 n_reg
= (size
+ 7) / 8;
9885 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
9886 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
9887 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
9892 /* Otherwise into GP registers. */
9901 /* Pull the value out of the saved registers.... */
9904 addr
= create_tmp_var (ptr_type_node
, "addr");
9906 /* AltiVec vectors never go in registers when -mabi=altivec. */
9907 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
9911 lab_false
= create_artificial_label (input_location
);
9912 lab_over
= create_artificial_label (input_location
);
9914 /* Long long and SPE vectors are aligned in the registers.
9915 As are any other 2 gpr item such as complex int due to a
9916 historical mistake. */
9918 if (n_reg
== 2 && reg
== gpr
)
9921 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9922 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
9923 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
9924 unshare_expr (reg
), u
);
9926 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9927 reg number is 0 for f1, so we want to make it odd. */
9928 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
9930 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9931 build_int_cst (TREE_TYPE (reg
), 1));
9932 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
9935 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
9936 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
9937 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
9938 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
9939 gimplify_and_add (t
, pre_p
);
9943 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
9945 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9946 build_int_cst (TREE_TYPE (reg
), n_reg
));
9947 u
= fold_convert (sizetype
, u
);
9948 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
9949 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
9951 /* _Decimal32 varargs are located in the second word of the 64-bit
9952 FP register for 32-bit binaries. */
9953 if (!TARGET_POWERPC64
9954 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9955 && TYPE_MODE (type
) == SDmode
)
9956 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9958 gimplify_assign (addr
, t
, pre_p
);
9960 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
9962 stmt
= gimple_build_label (lab_false
);
9963 gimple_seq_add_stmt (pre_p
, stmt
);
9965 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
9967 /* Ensure that we don't find any more args in regs.
9968 Alignment has taken care of for special cases. */
9969 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
9973 /* ... otherwise out of the overflow area. */
9975 /* Care for on-stack alignment if needed. */
9979 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
9980 t
= fold_convert (sizetype
, t
);
9981 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
9983 t
= fold_convert (TREE_TYPE (ovf
), t
);
9985 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9987 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
9989 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9990 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
9994 stmt
= gimple_build_label (lab_over
);
9995 gimple_seq_add_stmt (pre_p
, stmt
);
9998 if (STRICT_ALIGNMENT
9999 && (TYPE_ALIGN (type
)
10000 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
10002 /* The value (of type complex double, for example) may not be
10003 aligned in memory in the saved registers, so copy via a
10004 temporary. (This is the same code as used for SPARC.) */
10005 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
10006 tree dest_addr
= build_fold_addr_expr (tmp
);
10008 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
10009 3, dest_addr
, addr
, size_int (rsize
* 4));
10011 gimplify_and_add (copy
, pre_p
);
10015 addr
= fold_convert (ptrtype
, addr
);
10016 return build_va_arg_indirect_ref (addr
);
10022 def_builtin (int mask
, const char *name
, tree type
, int code
)
10024 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
10027 if (rs6000_builtin_decls
[code
])
10028 fatal_error ("internal error: builtin function to %s already processed",
10031 rs6000_builtin_decls
[code
] = t
=
10032 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
10035 gcc_assert (code
>= 0 && code
< (int)RS6000_BUILTIN_COUNT
);
10036 switch (builtin_classify
[code
])
10039 gcc_unreachable ();
10041 /* assume builtin can do anything. */
10042 case RS6000_BTC_MISC
:
10045 /* const function, function only depends on the inputs. */
10046 case RS6000_BTC_CONST
:
10047 TREE_READONLY (t
) = 1;
10048 TREE_NOTHROW (t
) = 1;
10051 /* pure function, function can read global memory. */
10052 case RS6000_BTC_PURE
:
10053 DECL_PURE_P (t
) = 1;
10054 TREE_NOTHROW (t
) = 1;
10057 /* Function is a math function. If rounding mode is on, then treat
10058 the function as not reading global memory, but it can have
10059 arbitrary side effects. If it is off, then assume the function is
10060 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10061 attribute in builtin-attribute.def that is used for the math
10063 case RS6000_BTC_FP_PURE
:
10064 TREE_NOTHROW (t
) = 1;
10065 if (flag_rounding_math
)
10067 DECL_PURE_P (t
) = 1;
10068 DECL_IS_NOVOPS (t
) = 1;
10071 TREE_READONLY (t
) = 1;
10077 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10079 static const struct builtin_description bdesc_3arg
[] =
10081 { MASK_ALTIVEC
, CODE_FOR_fmav4sf4
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
10082 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
10083 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
10084 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
10085 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
10086 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
10087 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
10088 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
10089 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
10090 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
10091 { MASK_ALTIVEC
, CODE_FOR_nfmsv4sf4
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
10092 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2df
, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF
},
10093 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di
, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI
},
10094 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
10095 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
10096 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
10097 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
10098 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS
},
10099 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS
},
10100 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS
},
10101 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS
},
10102 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
10103 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
10104 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
10105 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
10106 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2df
, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF
},
10107 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di
, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI
},
10108 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si_uns
, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS
},
10109 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS
},
10110 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS
},
10111 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di_uns
, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS
},
10112 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
10113 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
10114 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
10115 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
10117 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
10118 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
10119 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
10120 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
10121 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
10122 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
10123 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
10124 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
10125 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
10126 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
10127 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
10128 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
10129 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
10130 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
10131 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
10133 { MASK_VSX
, CODE_FOR_fmav2df4
, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP
},
10134 { MASK_VSX
, CODE_FOR_fmsv2df4
, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP
},
10135 { MASK_VSX
, CODE_FOR_nfmav2df4
, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP
},
10136 { MASK_VSX
, CODE_FOR_nfmsv2df4
, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP
},
10138 { MASK_VSX
, CODE_FOR_fmav4sf4
, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP
},
10139 { MASK_VSX
, CODE_FOR_fmsv4sf4
, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP
},
10140 { MASK_VSX
, CODE_FOR_nfmav4sf4
, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP
},
10141 { MASK_VSX
, CODE_FOR_nfmsv4sf4
, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP
},
10143 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB
},
10144 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD
},
10146 { MASK_VSX
, CODE_FOR_vector_select_v2di
, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI
},
10147 { MASK_VSX
, CODE_FOR_vector_select_v2df
, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF
},
10148 { MASK_VSX
, CODE_FOR_vector_select_v4sf
, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF
},
10149 { MASK_VSX
, CODE_FOR_vector_select_v4si
, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI
},
10150 { MASK_VSX
, CODE_FOR_vector_select_v8hi
, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI
},
10151 { MASK_VSX
, CODE_FOR_vector_select_v16qi
, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI
},
10152 { MASK_VSX
, CODE_FOR_vector_select_v2di_uns
, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS
},
10153 { MASK_VSX
, CODE_FOR_vector_select_v4si_uns
, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS
},
10154 { MASK_VSX
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS
},
10155 { MASK_VSX
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS
},
10157 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di
, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI
},
10158 { MASK_VSX
, CODE_FOR_altivec_vperm_v2df
, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF
},
10159 { MASK_VSX
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF
},
10160 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si
, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI
},
10161 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI
},
10162 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI
},
10163 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS
},
10164 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS
},
10165 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS
},
10166 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS
},
10168 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2df
, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF
},
10169 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2di
, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI
},
10170 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4sf
, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF
},
10171 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4si
, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI
},
10172 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v8hi
, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI
},
10173 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v16qi
, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI
},
10174 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI
},
10175 { MASK_VSX
, CODE_FOR_vsx_set_v2df
, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF
},
10176 { MASK_VSX
, CODE_FOR_vsx_set_v2di
, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI
},
10178 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2di
, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI
},
10179 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2df
, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF
},
10180 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4sf
, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF
},
10181 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4si
, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI
},
10182 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v8hi
, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI
},
10183 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v16qi
, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI
},
10184 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI
},
10186 { 0, CODE_FOR_fmsv2sf4
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
10187 { 0, CODE_FOR_fmav2sf4
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
10188 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
10189 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
10190 { 0, CODE_FOR_nfmsv2sf4
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
10191 { 0, CODE_FOR_nfmav2sf4
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
10192 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
10193 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
10194 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
10197 /* DST operations: void foo (void *, const int, const char). */
10199 static const struct builtin_description bdesc_dst
[] =
10201 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
10202 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
10203 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
10204 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
10206 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
10207 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
10208 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
10209 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
10212 /* Simple binary operations: VECc = foo (VECa, VECb). */
10214 static struct builtin_description bdesc_2arg
[] =
10216 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
10217 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
10218 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
10219 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
10220 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
10221 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
10222 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
10223 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
10224 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
10225 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
10226 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
10227 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
10228 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
10229 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
10230 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
10231 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
10232 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
10233 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
10234 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
10235 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
10236 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
10237 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
10238 { MASK_ALTIVEC
, CODE_FOR_vector_eqv16qi
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
10239 { MASK_ALTIVEC
, CODE_FOR_vector_eqv8hi
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
10240 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4si
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
10241 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4sf
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
10242 { MASK_ALTIVEC
, CODE_FOR_vector_gev4sf
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
10243 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv16qi
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
10244 { MASK_ALTIVEC
, CODE_FOR_vector_gtv16qi
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
10245 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv8hi
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
10246 { MASK_ALTIVEC
, CODE_FOR_vector_gtv8hi
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
10247 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv4si
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
10248 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4si
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
10249 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4sf
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
10250 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
10251 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
10252 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
10253 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
10254 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
10255 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
10256 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
10257 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
10258 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
10259 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
10260 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
10261 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
10262 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
10263 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
10264 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
10265 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
10266 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
10267 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
10268 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
10269 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
10270 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
10271 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
10272 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
10273 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS
},
10274 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
10275 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
10276 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS
},
10277 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
10278 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
10279 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS
},
10280 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
10281 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
10282 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS
},
10283 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
10284 { MASK_ALTIVEC
, CODE_FOR_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
10285 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
10286 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
10287 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
10288 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
10289 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
10290 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
10291 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
10292 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
10293 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
10294 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
10295 { MASK_ALTIVEC
, CODE_FOR_recipv4sf3
, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP
},
10296 { MASK_ALTIVEC
, CODE_FOR_vrotlv16qi3
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
10297 { MASK_ALTIVEC
, CODE_FOR_vrotlv8hi3
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
10298 { MASK_ALTIVEC
, CODE_FOR_vrotlv4si3
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
10299 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
10300 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
10301 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
10302 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
10303 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
10304 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
10305 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
10306 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
10307 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
10308 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
10309 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
10310 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
10311 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
10312 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
10313 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
10314 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
10315 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
10316 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
10317 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
10318 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
10319 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
10320 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
10321 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
10322 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
10323 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
10324 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
10325 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
10326 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
10327 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
10328 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
10329 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
10330 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
10331 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
10332 { MASK_ALTIVEC
, CODE_FOR_vector_copysignv4sf3
, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF
},
10334 { MASK_VSX
, CODE_FOR_addv2df3
, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP
},
10335 { MASK_VSX
, CODE_FOR_subv2df3
, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP
},
10336 { MASK_VSX
, CODE_FOR_mulv2df3
, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP
},
10337 { MASK_VSX
, CODE_FOR_divv2df3
, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP
},
10338 { MASK_VSX
, CODE_FOR_recipv2df3
, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF
},
10339 { MASK_VSX
, CODE_FOR_sminv2df3
, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP
},
10340 { MASK_VSX
, CODE_FOR_smaxv2df3
, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP
},
10341 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fe
, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE
},
10342 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fg
, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG
},
10343 { MASK_VSX
, CODE_FOR_vector_eqv2df
, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP
},
10344 { MASK_VSX
, CODE_FOR_vector_gtv2df
, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP
},
10345 { MASK_VSX
, CODE_FOR_vector_gev2df
, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP
},
10347 { MASK_VSX
, CODE_FOR_addv4sf3
, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP
},
10348 { MASK_VSX
, CODE_FOR_subv4sf3
, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP
},
10349 { MASK_VSX
, CODE_FOR_mulv4sf3
, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP
},
10350 { MASK_VSX
, CODE_FOR_divv4sf3
, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP
},
10351 { MASK_VSX
, CODE_FOR_recipv4sf3
, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF
},
10352 { MASK_VSX
, CODE_FOR_sminv4sf3
, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP
},
10353 { MASK_VSX
, CODE_FOR_smaxv4sf3
, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP
},
10354 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fe
, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE
},
10355 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fg
, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG
},
10356 { MASK_VSX
, CODE_FOR_vector_eqv4sf
, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP
},
10357 { MASK_VSX
, CODE_FOR_vector_gtv4sf
, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP
},
10358 { MASK_VSX
, CODE_FOR_vector_gev4sf
, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP
},
10360 { MASK_VSX
, CODE_FOR_smindf3
, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP
},
10361 { MASK_VSX
, CODE_FOR_smaxdf3
, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP
},
10362 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fe
, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE
},
10363 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fg
, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG
},
10364 { MASK_VSX
, CODE_FOR_vector_copysignv2df3
, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP
},
10365 { MASK_VSX
, CODE_FOR_vector_copysignv4sf3
, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP
},
10367 { MASK_VSX
, CODE_FOR_vsx_concat_v2df
, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF
},
10368 { MASK_VSX
, CODE_FOR_vsx_concat_v2di
, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI
},
10369 { MASK_VSX
, CODE_FOR_vsx_splat_v2df
, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF
},
10370 { MASK_VSX
, CODE_FOR_vsx_splat_v2di
, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI
},
10371 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4sf
, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF
},
10372 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4si
, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI
},
10373 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4sf
, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF
},
10374 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4si
, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI
},
10375 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2df
, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF
},
10376 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2di
, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI
},
10377 { MASK_VSX
, CODE_FOR_vec_interleave_highv2df
, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF
},
10378 { MASK_VSX
, CODE_FOR_vec_interleave_highv2di
, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI
},
10380 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
10381 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
10382 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
10383 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
10384 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
10385 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
10386 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
10387 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
10388 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
10389 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
10390 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
10391 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
10392 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
10393 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
10394 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
10395 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
10396 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
10397 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
10398 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
10399 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
10400 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
10401 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
10402 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
10403 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
10404 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
10405 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
10406 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
10407 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
10408 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
10409 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
10410 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
10411 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
10412 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
10413 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
10414 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
10415 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
10416 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
10417 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
10418 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
10419 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN
},
10420 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
10421 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
10422 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
10423 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
10424 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
10425 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
10426 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
10427 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
10428 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
10429 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
10430 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
10431 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
10432 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
10433 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
10434 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
10435 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
10436 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
10437 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
10438 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
10439 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
10440 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
10441 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
10442 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
10443 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
10444 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
10445 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
10446 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
10447 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
10448 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
10449 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
10450 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
10451 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
10452 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
10453 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
10454 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
10455 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
10456 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
10457 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
10458 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
10459 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
10460 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
10461 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
10462 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
10463 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
10464 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
10465 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
10466 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
10467 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
10468 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP
},
10469 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
10470 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
10471 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
10472 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
10473 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
10474 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
10475 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
10476 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
10477 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
10478 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
10479 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
10480 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
10481 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
10482 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
10483 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
10484 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
10485 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
10486 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
10487 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
10488 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
10489 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
10490 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
10491 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
10492 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
10493 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
10494 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
10495 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
10496 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
10497 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
10498 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
10499 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
10500 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
10501 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
10502 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
10503 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
10504 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
10505 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
10506 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
10507 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
10508 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
10510 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL
},
10511 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV
},
10513 { 0, CODE_FOR_paired_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
10514 { 0, CODE_FOR_paired_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
10515 { 0, CODE_FOR_paired_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
10516 { 0, CODE_FOR_paired_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
10517 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
10518 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
10519 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
10520 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
10521 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
10522 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
10524 /* Place holder, leave as first spe builtin. */
10525 { 0, CODE_FOR_addv2si3
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
10526 { 0, CODE_FOR_andv2si3
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
10527 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
10528 { 0, CODE_FOR_divv2si3
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
10529 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
10530 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
10531 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
10532 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
10533 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
10534 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
10535 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
10536 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
10537 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
10538 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
10539 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
10540 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
10541 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
10542 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
10543 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
10544 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
10545 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
10546 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
10547 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
10548 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
10549 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
10550 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
10551 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
10552 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
10553 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
10554 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
10555 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
10556 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
10557 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
10558 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
10559 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
10560 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
10561 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
10562 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
10563 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
10564 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
10565 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
10566 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
10567 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
10568 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
10569 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
10570 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
10571 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
10572 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
10573 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
10574 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
10575 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
10576 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
10577 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
10578 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
10579 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
10580 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
10581 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
10582 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
10583 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
10584 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
10585 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
10586 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
10587 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
10588 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
10589 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
10590 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
10591 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
10592 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
10593 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
10594 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
10595 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
10596 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
10597 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
10598 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
10599 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
10600 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
10601 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
10602 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
10603 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
10604 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
10605 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
10606 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
10607 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
10608 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
10609 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
10610 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
10611 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
10612 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
10613 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
10614 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
10615 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
10616 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
10617 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
10618 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
10619 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
10620 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
10621 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
10622 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
10623 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
10624 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
10625 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
10626 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
10627 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
10628 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
10629 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
10630 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
10631 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
10632 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
10633 { 0, CODE_FOR_subv2si3
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
10635 /* SPE binary operations expecting a 5-bit unsigned literal. */
10636 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
10638 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
10639 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
10640 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
10641 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
10642 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
10643 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
10644 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
10645 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
10646 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
10647 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
10648 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
10649 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
10650 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
10651 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
10652 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
10653 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
10654 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
10655 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
10656 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
10657 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
10658 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
10659 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
10660 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
10661 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
10662 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
10663 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
10665 /* Place-holder. Leave as last binary SPE builtin. */
10666 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
10669 /* AltiVec predicates. */
10671 struct builtin_description_predicates
10673 const unsigned int mask
;
10674 const enum insn_code icode
;
10675 const char *const name
;
10676 const enum rs6000_builtins code
;
10679 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
10681 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp_p
, "__builtin_altivec_vcmpbfp_p",
10682 ALTIVEC_BUILTIN_VCMPBFP_P
},
10683 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
,
10684 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
10685 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
,
10686 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
10687 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
,
10688 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
10689 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v4si_p
, "__builtin_altivec_vcmpequw_p",
10690 ALTIVEC_BUILTIN_VCMPEQUW_P
},
10691 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v4si_p
, "__builtin_altivec_vcmpgtsw_p",
10692 ALTIVEC_BUILTIN_VCMPGTSW_P
},
10693 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v4si_p
, "__builtin_altivec_vcmpgtuw_p",
10694 ALTIVEC_BUILTIN_VCMPGTUW_P
},
10695 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v8hi_p
, "__builtin_altivec_vcmpequh_p",
10696 ALTIVEC_BUILTIN_VCMPEQUH_P
},
10697 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v8hi_p
, "__builtin_altivec_vcmpgtsh_p",
10698 ALTIVEC_BUILTIN_VCMPGTSH_P
},
10699 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v8hi_p
, "__builtin_altivec_vcmpgtuh_p",
10700 ALTIVEC_BUILTIN_VCMPGTUH_P
},
10701 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v16qi_p
, "__builtin_altivec_vcmpequb_p",
10702 ALTIVEC_BUILTIN_VCMPEQUB_P
},
10703 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v16qi_p
, "__builtin_altivec_vcmpgtsb_p",
10704 ALTIVEC_BUILTIN_VCMPGTSB_P
},
10705 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v16qi_p
, "__builtin_altivec_vcmpgtub_p",
10706 ALTIVEC_BUILTIN_VCMPGTUB_P
},
10708 { MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
, "__builtin_vsx_xvcmpeqsp_p",
10709 VSX_BUILTIN_XVCMPEQSP_P
},
10710 { MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
, "__builtin_vsx_xvcmpgesp_p",
10711 VSX_BUILTIN_XVCMPGESP_P
},
10712 { MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
, "__builtin_vsx_xvcmpgtsp_p",
10713 VSX_BUILTIN_XVCMPGTSP_P
},
10714 { MASK_VSX
, CODE_FOR_vector_eq_v2df_p
, "__builtin_vsx_xvcmpeqdp_p",
10715 VSX_BUILTIN_XVCMPEQDP_P
},
10716 { MASK_VSX
, CODE_FOR_vector_ge_v2df_p
, "__builtin_vsx_xvcmpgedp_p",
10717 VSX_BUILTIN_XVCMPGEDP_P
},
10718 { MASK_VSX
, CODE_FOR_vector_gt_v2df_p
, "__builtin_vsx_xvcmpgtdp_p",
10719 VSX_BUILTIN_XVCMPGTDP_P
},
10721 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpeq_p",
10722 ALTIVEC_BUILTIN_VCMPEQ_P
},
10723 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpgt_p",
10724 ALTIVEC_BUILTIN_VCMPGT_P
},
10725 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpge_p",
10726 ALTIVEC_BUILTIN_VCMPGE_P
}
10729 /* SPE predicates. */
10730 static struct builtin_description bdesc_spe_predicates
[] =
10732 /* Place-holder. Leave as first. */
10733 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
10734 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
10735 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
10736 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
10737 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
10738 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
10739 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
10740 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
10741 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
10742 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
10743 /* Place-holder. Leave as last. */
10744 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
10747 /* SPE evsel predicates. */
10748 static struct builtin_description bdesc_spe_evsel
[] =
10750 /* Place-holder. Leave as first. */
10751 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
10752 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
10753 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
10754 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
10755 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
10756 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
10757 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
10758 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
10759 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
10760 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
10761 /* Place-holder. Leave as last. */
10762 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
10765 /* PAIRED predicates. */
10766 static const struct builtin_description bdesc_paired_preds
[] =
10768 /* Place-holder. Leave as first. */
10769 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
10770 /* Place-holder. Leave as last. */
10771 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
10774 /* ABS* operations. */
10776 static const struct builtin_description bdesc_abs
[] =
10778 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
10779 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
10780 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
10781 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
10782 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
10783 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
10784 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
},
10785 { MASK_VSX
, CODE_FOR_absv2df2
, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP
},
10786 { MASK_VSX
, CODE_FOR_vsx_nabsv2df2
, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP
},
10787 { MASK_VSX
, CODE_FOR_absv4sf2
, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP
},
10788 { MASK_VSX
, CODE_FOR_vsx_nabsv4sf2
, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP
},
10791 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10794 static struct builtin_description bdesc_1arg
[] =
10796 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
10797 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
10798 { MASK_ALTIVEC
, CODE_FOR_rev4sf2
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
10799 { MASK_ALTIVEC
, CODE_FOR_vector_floorv4sf2
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
10800 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
10801 { MASK_ALTIVEC
, CODE_FOR_vector_ceilv4sf2
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
10802 { MASK_ALTIVEC
, CODE_FOR_vector_btruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
10803 { MASK_ALTIVEC
, CODE_FOR_rsqrtv4sf2
, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP
},
10804 { MASK_ALTIVEC
, CODE_FOR_rsqrtev4sf2
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
10805 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
10806 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
10807 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
10808 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
10809 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
10810 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
10811 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
10812 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
10813 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
10815 { MASK_VSX
, CODE_FOR_negv2df2
, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP
},
10816 { MASK_VSX
, CODE_FOR_sqrtv2df2
, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP
},
10817 { MASK_VSX
, CODE_FOR_rsqrtv2df2
, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF
},
10818 { MASK_VSX
, CODE_FOR_rsqrtev2df2
, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP
},
10819 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fe
, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE
},
10820 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fg
, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG
},
10821 { MASK_VSX
, CODE_FOR_vsx_frev2df2
, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP
},
10823 { MASK_VSX
, CODE_FOR_negv4sf2
, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP
},
10824 { MASK_VSX
, CODE_FOR_sqrtv4sf2
, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP
},
10825 { MASK_VSX
, CODE_FOR_rsqrtv4sf2
, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF
},
10826 { MASK_VSX
, CODE_FOR_rsqrtev4sf2
, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP
},
10827 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fe
, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE
},
10828 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fg
, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG
},
10829 { MASK_VSX
, CODE_FOR_vsx_frev4sf2
, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP
},
10831 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP
},
10832 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP
},
10833 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsp
, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP
},
10834 { MASK_VSX
, CODE_FOR_vsx_xvcvspdp
, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP
},
10835 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fe
, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE
},
10836 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fg
, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG
},
10838 { MASK_VSX
, CODE_FOR_vsx_fix_truncv2dfv2di2
, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS
},
10839 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS
},
10840 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS
},
10841 { MASK_VSX
, CODE_FOR_vsx_floatv2div2df2
, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP
},
10842 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP
},
10843 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS
},
10845 { MASK_VSX
, CODE_FOR_vsx_fix_truncv4sfv4si2
, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS
},
10846 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv4sfv4si2
, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS
},
10847 { MASK_VSX
, CODE_FOR_vsx_floatv4siv4sf2
, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP
},
10848 { MASK_VSX
, CODE_FOR_vsx_floatunsv4siv4sf2
, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP
},
10850 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsxws
, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS
},
10851 { MASK_VSX
, CODE_FOR_vsx_xvcvdpuxws
, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS
},
10852 { MASK_VSX
, CODE_FOR_vsx_xvcvsxwdp
, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP
},
10853 { MASK_VSX
, CODE_FOR_vsx_xvcvuxwdp
, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP
},
10854 { MASK_VSX
, CODE_FOR_vsx_xvrdpi
, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI
},
10855 { MASK_VSX
, CODE_FOR_vsx_xvrdpic
, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC
},
10856 { MASK_VSX
, CODE_FOR_vsx_floorv2df2
, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM
},
10857 { MASK_VSX
, CODE_FOR_vsx_ceilv2df2
, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP
},
10858 { MASK_VSX
, CODE_FOR_vsx_btruncv2df2
, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ
},
10860 { MASK_VSX
, CODE_FOR_vsx_xvcvspsxds
, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS
},
10861 { MASK_VSX
, CODE_FOR_vsx_xvcvspuxds
, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS
},
10862 { MASK_VSX
, CODE_FOR_vsx_xvcvsxdsp
, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP
},
10863 { MASK_VSX
, CODE_FOR_vsx_xvcvuxdsp
, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP
},
10864 { MASK_VSX
, CODE_FOR_vsx_xvrspi
, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI
},
10865 { MASK_VSX
, CODE_FOR_vsx_xvrspic
, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC
},
10866 { MASK_VSX
, CODE_FOR_vsx_floorv4sf2
, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM
},
10867 { MASK_VSX
, CODE_FOR_vsx_ceilv4sf2
, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP
},
10868 { MASK_VSX
, CODE_FOR_vsx_btruncv4sf2
, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ
},
10870 { MASK_VSX
, CODE_FOR_vsx_xsrdpi
, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI
},
10871 { MASK_VSX
, CODE_FOR_vsx_xsrdpic
, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC
},
10872 { MASK_VSX
, CODE_FOR_vsx_floordf2
, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM
},
10873 { MASK_VSX
, CODE_FOR_vsx_ceildf2
, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP
},
10874 { MASK_VSX
, CODE_FOR_vsx_btruncdf2
, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ
},
10876 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
10877 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
10878 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
10879 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
10880 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
10881 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
10882 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
10883 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
10884 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
10885 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT
},
10886 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
10887 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
10888 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
10889 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
10890 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
10891 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
10892 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
10893 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
10894 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
10895 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
10897 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT
},
10898 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT
},
10899 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT
},
10901 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_floatv4siv4sf2
, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF
},
10902 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_unsigned_floatv4siv4sf2
, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
},
10903 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fix_truncv4sfv4si2
, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI
},
10904 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fixuns_truncv4sfv4si2
, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
},
10906 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10907 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10908 { 0, CODE_FOR_absv2si2
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
10909 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
10910 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
10911 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
10912 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
10913 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
10914 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
10915 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
10916 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
10917 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
10918 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
10919 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
10920 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
10921 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
10922 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
10923 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
10924 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
10925 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
10926 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
10927 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
10928 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
10929 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
10930 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
10931 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
10932 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
10933 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
10934 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
10935 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
10937 /* Place-holder. Leave as last unary SPE builtin. */
10938 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
10940 { 0, CODE_FOR_paired_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
10941 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
10942 { 0, CODE_FOR_paired_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
10943 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
10944 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
10948 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10951 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10952 rtx op0
= expand_normal (arg0
);
10953 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10954 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10956 if (icode
== CODE_FOR_nothing
)
10957 /* Builtin not supported on this processor. */
10960 /* If we got invalid arguments bail out before generating bad rtl. */
10961 if (arg0
== error_mark_node
)
10964 if (icode
== CODE_FOR_altivec_vspltisb
10965 || icode
== CODE_FOR_altivec_vspltish
10966 || icode
== CODE_FOR_altivec_vspltisw
10967 || icode
== CODE_FOR_spe_evsplatfi
10968 || icode
== CODE_FOR_spe_evsplati
)
10970 /* Only allow 5-bit *signed* literals. */
10971 if (GET_CODE (op0
) != CONST_INT
10972 || INTVAL (op0
) > 15
10973 || INTVAL (op0
) < -16)
10975 error ("argument 1 must be a 5-bit signed literal");
10981 || GET_MODE (target
) != tmode
10982 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10983 target
= gen_reg_rtx (tmode
);
10985 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10986 op0
= copy_to_mode_reg (mode0
, op0
);
10988 pat
= GEN_FCN (icode
) (target
, op0
);
10997 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
10999 rtx pat
, scratch1
, scratch2
;
11000 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11001 rtx op0
= expand_normal (arg0
);
11002 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11003 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11005 /* If we have invalid arguments, bail out before generating bad rtl. */
11006 if (arg0
== error_mark_node
)
11010 || GET_MODE (target
) != tmode
11011 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11012 target
= gen_reg_rtx (tmode
);
11014 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11015 op0
= copy_to_mode_reg (mode0
, op0
);
11017 scratch1
= gen_reg_rtx (mode0
);
11018 scratch2
= gen_reg_rtx (mode0
);
11020 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
11029 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
11032 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11033 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11034 rtx op0
= expand_normal (arg0
);
11035 rtx op1
= expand_normal (arg1
);
11036 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11037 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11038 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11040 if (icode
== CODE_FOR_nothing
)
11041 /* Builtin not supported on this processor. */
11044 /* If we got invalid arguments bail out before generating bad rtl. */
11045 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11048 if (icode
== CODE_FOR_altivec_vcfux
11049 || icode
== CODE_FOR_altivec_vcfsx
11050 || icode
== CODE_FOR_altivec_vctsxs
11051 || icode
== CODE_FOR_altivec_vctuxs
11052 || icode
== CODE_FOR_altivec_vspltb
11053 || icode
== CODE_FOR_altivec_vsplth
11054 || icode
== CODE_FOR_altivec_vspltw
11055 || icode
== CODE_FOR_spe_evaddiw
11056 || icode
== CODE_FOR_spe_evldd
11057 || icode
== CODE_FOR_spe_evldh
11058 || icode
== CODE_FOR_spe_evldw
11059 || icode
== CODE_FOR_spe_evlhhesplat
11060 || icode
== CODE_FOR_spe_evlhhossplat
11061 || icode
== CODE_FOR_spe_evlhhousplat
11062 || icode
== CODE_FOR_spe_evlwhe
11063 || icode
== CODE_FOR_spe_evlwhos
11064 || icode
== CODE_FOR_spe_evlwhou
11065 || icode
== CODE_FOR_spe_evlwhsplat
11066 || icode
== CODE_FOR_spe_evlwwsplat
11067 || icode
== CODE_FOR_spe_evrlwi
11068 || icode
== CODE_FOR_spe_evslwi
11069 || icode
== CODE_FOR_spe_evsrwis
11070 || icode
== CODE_FOR_spe_evsubifw
11071 || icode
== CODE_FOR_spe_evsrwiu
)
11073 /* Only allow 5-bit unsigned literals. */
11075 if (TREE_CODE (arg1
) != INTEGER_CST
11076 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
11078 error ("argument 2 must be a 5-bit unsigned literal");
11084 || GET_MODE (target
) != tmode
11085 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11086 target
= gen_reg_rtx (tmode
);
11088 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11089 op0
= copy_to_mode_reg (mode0
, op0
);
11090 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11091 op1
= copy_to_mode_reg (mode1
, op1
);
11093 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
11102 altivec_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
11105 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
11106 tree arg0
= CALL_EXPR_ARG (exp
, 1);
11107 tree arg1
= CALL_EXPR_ARG (exp
, 2);
11108 rtx op0
= expand_normal (arg0
);
11109 rtx op1
= expand_normal (arg1
);
11110 enum machine_mode tmode
= SImode
;
11111 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11112 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11115 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
11117 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11121 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
11123 gcc_assert (mode0
== mode1
);
11125 /* If we have invalid arguments, bail out before generating bad rtl. */
11126 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11130 || GET_MODE (target
) != tmode
11131 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11132 target
= gen_reg_rtx (tmode
);
11134 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11135 op0
= copy_to_mode_reg (mode0
, op0
);
11136 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11137 op1
= copy_to_mode_reg (mode1
, op1
);
11139 scratch
= gen_reg_rtx (mode0
);
11141 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11146 /* The vec_any* and vec_all* predicates use the same opcodes for two
11147 different operations, but the bits in CR6 will be different
11148 depending on what information we want. So we have to play tricks
11149 with CR6 to get the right bits out.
11151 If you think this is disgusting, look at the specs for the
11152 AltiVec predicates. */
11154 switch (cr6_form_int
)
11157 emit_insn (gen_cr6_test_for_zero (target
));
11160 emit_insn (gen_cr6_test_for_zero_reverse (target
));
11163 emit_insn (gen_cr6_test_for_lt (target
));
11166 emit_insn (gen_cr6_test_for_lt_reverse (target
));
11169 error ("argument 1 of __builtin_altivec_predicate is out of range");
11177 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
11180 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11181 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11182 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11183 enum machine_mode mode0
= Pmode
;
11184 enum machine_mode mode1
= Pmode
;
11185 rtx op0
= expand_normal (arg0
);
11186 rtx op1
= expand_normal (arg1
);
11188 if (icode
== CODE_FOR_nothing
)
11189 /* Builtin not supported on this processor. */
11192 /* If we got invalid arguments bail out before generating bad rtl. */
11193 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11197 || GET_MODE (target
) != tmode
11198 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11199 target
= gen_reg_rtx (tmode
);
11201 op1
= copy_to_mode_reg (mode1
, op1
);
11203 if (op0
== const0_rtx
)
11205 addr
= gen_rtx_MEM (tmode
, op1
);
11209 op0
= copy_to_mode_reg (mode0
, op0
);
11210 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
11213 pat
= GEN_FCN (icode
) (target
, addr
);
11223 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
11226 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11227 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11228 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11229 enum machine_mode mode0
= Pmode
;
11230 enum machine_mode mode1
= Pmode
;
11231 rtx op0
= expand_normal (arg0
);
11232 rtx op1
= expand_normal (arg1
);
11234 if (icode
== CODE_FOR_nothing
)
11235 /* Builtin not supported on this processor. */
11238 /* If we got invalid arguments bail out before generating bad rtl. */
11239 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11243 || GET_MODE (target
) != tmode
11244 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11245 target
= gen_reg_rtx (tmode
);
11247 op1
= copy_to_mode_reg (mode1
, op1
);
11249 if (op0
== const0_rtx
)
11251 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
11255 op0
= copy_to_mode_reg (mode0
, op0
);
11256 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
11259 pat
= GEN_FCN (icode
) (target
, addr
);
11269 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
11271 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11272 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11273 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11274 rtx op0
= expand_normal (arg0
);
11275 rtx op1
= expand_normal (arg1
);
11276 rtx op2
= expand_normal (arg2
);
11278 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
11279 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
11280 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
11282 /* Invalid arguments. Bail before doing anything stoopid! */
11283 if (arg0
== error_mark_node
11284 || arg1
== error_mark_node
11285 || arg2
== error_mark_node
)
11288 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
11289 op0
= copy_to_mode_reg (mode2
, op0
);
11290 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
11291 op1
= copy_to_mode_reg (mode0
, op1
);
11292 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
11293 op2
= copy_to_mode_reg (mode1
, op2
);
11295 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
11302 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
11304 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11305 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11306 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11307 rtx op0
= expand_normal (arg0
);
11308 rtx op1
= expand_normal (arg1
);
11309 rtx op2
= expand_normal (arg2
);
11311 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11312 enum machine_mode mode1
= Pmode
;
11313 enum machine_mode mode2
= Pmode
;
11315 /* Invalid arguments. Bail before doing anything stoopid! */
11316 if (arg0
== error_mark_node
11317 || arg1
== error_mark_node
11318 || arg2
== error_mark_node
)
11321 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
11322 op0
= copy_to_mode_reg (tmode
, op0
);
11324 op2
= copy_to_mode_reg (mode2
, op2
);
11326 if (op1
== const0_rtx
)
11328 addr
= gen_rtx_MEM (tmode
, op2
);
11332 op1
= copy_to_mode_reg (mode1
, op1
);
11333 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
11336 pat
= GEN_FCN (icode
) (addr
, op0
);
11343 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
11345 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11346 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11347 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11348 rtx op0
= expand_normal (arg0
);
11349 rtx op1
= expand_normal (arg1
);
11350 rtx op2
= expand_normal (arg2
);
11352 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11353 enum machine_mode smode
= insn_data
[icode
].operand
[1].mode
;
11354 enum machine_mode mode1
= Pmode
;
11355 enum machine_mode mode2
= Pmode
;
11357 /* Invalid arguments. Bail before doing anything stoopid! */
11358 if (arg0
== error_mark_node
11359 || arg1
== error_mark_node
11360 || arg2
== error_mark_node
)
11363 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, smode
))
11364 op0
= copy_to_mode_reg (smode
, op0
);
11366 op2
= copy_to_mode_reg (mode2
, op2
);
11368 if (op1
== const0_rtx
)
11370 addr
= gen_rtx_MEM (tmode
, op2
);
11374 op1
= copy_to_mode_reg (mode1
, op1
);
11375 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
11378 pat
= GEN_FCN (icode
) (addr
, op0
);
11385 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
11388 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11389 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11390 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11391 rtx op0
= expand_normal (arg0
);
11392 rtx op1
= expand_normal (arg1
);
11393 rtx op2
= expand_normal (arg2
);
11394 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11395 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11396 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11397 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
11399 if (icode
== CODE_FOR_nothing
)
11400 /* Builtin not supported on this processor. */
11403 /* If we got invalid arguments bail out before generating bad rtl. */
11404 if (arg0
== error_mark_node
11405 || arg1
== error_mark_node
11406 || arg2
== error_mark_node
)
11409 /* Check and prepare argument depending on the instruction code.
11411 Note that a switch statement instead of the sequence of tests
11412 would be incorrect as many of the CODE_FOR values could be
11413 CODE_FOR_nothing and that would yield multiple alternatives
11414 with identical values. We'd never reach here at runtime in
11416 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
11417 || icode
== CODE_FOR_altivec_vsldoi_v4si
11418 || icode
== CODE_FOR_altivec_vsldoi_v8hi
11419 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
11421 /* Only allow 4-bit unsigned literals. */
11423 if (TREE_CODE (arg2
) != INTEGER_CST
11424 || TREE_INT_CST_LOW (arg2
) & ~0xf)
11426 error ("argument 3 must be a 4-bit unsigned literal");
11430 else if (icode
== CODE_FOR_vsx_xxpermdi_v2df
11431 || icode
== CODE_FOR_vsx_xxpermdi_v2di
11432 || icode
== CODE_FOR_vsx_xxsldwi_v16qi
11433 || icode
== CODE_FOR_vsx_xxsldwi_v8hi
11434 || icode
== CODE_FOR_vsx_xxsldwi_v4si
11435 || icode
== CODE_FOR_vsx_xxsldwi_v4sf
11436 || icode
== CODE_FOR_vsx_xxsldwi_v2di
11437 || icode
== CODE_FOR_vsx_xxsldwi_v2df
)
11439 /* Only allow 2-bit unsigned literals. */
11441 if (TREE_CODE (arg2
) != INTEGER_CST
11442 || TREE_INT_CST_LOW (arg2
) & ~0x3)
11444 error ("argument 3 must be a 2-bit unsigned literal");
11448 else if (icode
== CODE_FOR_vsx_set_v2df
11449 || icode
== CODE_FOR_vsx_set_v2di
)
11451 /* Only allow 1-bit unsigned literals. */
11453 if (TREE_CODE (arg2
) != INTEGER_CST
11454 || TREE_INT_CST_LOW (arg2
) & ~0x1)
11456 error ("argument 3 must be a 1-bit unsigned literal");
11462 || GET_MODE (target
) != tmode
11463 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11464 target
= gen_reg_rtx (tmode
);
11466 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11467 op0
= copy_to_mode_reg (mode0
, op0
);
11468 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11469 op1
= copy_to_mode_reg (mode1
, op1
);
11470 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
11471 op2
= copy_to_mode_reg (mode2
, op2
);
11473 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
11474 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
11476 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
11484 /* Expand the lvx builtins. */
11486 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
11488 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11489 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11491 enum machine_mode tmode
, mode0
;
11493 enum insn_code icode
;
11497 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
11498 icode
= CODE_FOR_vector_altivec_load_v16qi
;
11500 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
11501 icode
= CODE_FOR_vector_altivec_load_v8hi
;
11503 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
11504 icode
= CODE_FOR_vector_altivec_load_v4si
;
11506 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
11507 icode
= CODE_FOR_vector_altivec_load_v4sf
;
11509 case ALTIVEC_BUILTIN_LD_INTERNAL_2df
:
11510 icode
= CODE_FOR_vector_altivec_load_v2df
;
11512 case ALTIVEC_BUILTIN_LD_INTERNAL_2di
:
11513 icode
= CODE_FOR_vector_altivec_load_v2di
;
11516 *expandedp
= false;
11522 arg0
= CALL_EXPR_ARG (exp
, 0);
11523 op0
= expand_normal (arg0
);
11524 tmode
= insn_data
[icode
].operand
[0].mode
;
11525 mode0
= insn_data
[icode
].operand
[1].mode
;
11528 || GET_MODE (target
) != tmode
11529 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11530 target
= gen_reg_rtx (tmode
);
11532 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11533 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
11535 pat
= GEN_FCN (icode
) (target
, op0
);
11542 /* Expand the stvx builtins. */
11544 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
11547 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11548 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11550 enum machine_mode mode0
, mode1
;
11552 enum insn_code icode
;
11556 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
11557 icode
= CODE_FOR_vector_altivec_store_v16qi
;
11559 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
11560 icode
= CODE_FOR_vector_altivec_store_v8hi
;
11562 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
11563 icode
= CODE_FOR_vector_altivec_store_v4si
;
11565 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
11566 icode
= CODE_FOR_vector_altivec_store_v4sf
;
11568 case ALTIVEC_BUILTIN_ST_INTERNAL_2df
:
11569 icode
= CODE_FOR_vector_altivec_store_v2df
;
11571 case ALTIVEC_BUILTIN_ST_INTERNAL_2di
:
11572 icode
= CODE_FOR_vector_altivec_store_v2di
;
11575 *expandedp
= false;
11579 arg0
= CALL_EXPR_ARG (exp
, 0);
11580 arg1
= CALL_EXPR_ARG (exp
, 1);
11581 op0
= expand_normal (arg0
);
11582 op1
= expand_normal (arg1
);
11583 mode0
= insn_data
[icode
].operand
[0].mode
;
11584 mode1
= insn_data
[icode
].operand
[1].mode
;
11586 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11587 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
11588 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
11589 op1
= copy_to_mode_reg (mode1
, op1
);
11591 pat
= GEN_FCN (icode
) (op0
, op1
);
11599 /* Expand the dst builtins. */
11601 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
11604 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11605 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11606 tree arg0
, arg1
, arg2
;
11607 enum machine_mode mode0
, mode1
;
11608 rtx pat
, op0
, op1
, op2
;
11609 const struct builtin_description
*d
;
11612 *expandedp
= false;
11614 /* Handle DST variants. */
11616 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
11617 if (d
->code
== fcode
)
11619 arg0
= CALL_EXPR_ARG (exp
, 0);
11620 arg1
= CALL_EXPR_ARG (exp
, 1);
11621 arg2
= CALL_EXPR_ARG (exp
, 2);
11622 op0
= expand_normal (arg0
);
11623 op1
= expand_normal (arg1
);
11624 op2
= expand_normal (arg2
);
11625 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
11626 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
11628 /* Invalid arguments, bail out before generating bad rtl. */
11629 if (arg0
== error_mark_node
11630 || arg1
== error_mark_node
11631 || arg2
== error_mark_node
)
11636 if (TREE_CODE (arg2
) != INTEGER_CST
11637 || TREE_INT_CST_LOW (arg2
) & ~0x3)
11639 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
11643 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
11644 op0
= copy_to_mode_reg (Pmode
, op0
);
11645 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
11646 op1
= copy_to_mode_reg (mode1
, op1
);
11648 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
11658 /* Expand vec_init builtin. */
11660 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
11662 enum machine_mode tmode
= TYPE_MODE (type
);
11663 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
11664 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
11665 rtvec v
= rtvec_alloc (n_elt
);
11667 gcc_assert (VECTOR_MODE_P (tmode
));
11668 gcc_assert (n_elt
== call_expr_nargs (exp
));
11670 for (i
= 0; i
< n_elt
; ++i
)
11672 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
11673 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
11676 if (!target
|| !register_operand (target
, tmode
))
11677 target
= gen_reg_rtx (tmode
);
11679 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
11683 /* Return the integer constant in ARG. Constrain it to be in the range
11684 of the subparts of VEC_TYPE; issue an error if not. */
11687 get_element_number (tree vec_type
, tree arg
)
11689 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
11691 if (!host_integerp (arg
, 1)
11692 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
11694 error ("selector must be an integer constant in the range 0..%wi", max
);
11701 /* Expand vec_set builtin. */
11703 altivec_expand_vec_set_builtin (tree exp
)
11705 enum machine_mode tmode
, mode1
;
11706 tree arg0
, arg1
, arg2
;
11710 arg0
= CALL_EXPR_ARG (exp
, 0);
11711 arg1
= CALL_EXPR_ARG (exp
, 1);
11712 arg2
= CALL_EXPR_ARG (exp
, 2);
11714 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
11715 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11716 gcc_assert (VECTOR_MODE_P (tmode
));
11718 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
11719 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
11720 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
11722 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
11723 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
11725 op0
= force_reg (tmode
, op0
);
11726 op1
= force_reg (mode1
, op1
);
11728 rs6000_expand_vector_set (op0
, op1
, elt
);
11733 /* Expand vec_ext builtin. */
11735 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
11737 enum machine_mode tmode
, mode0
;
11742 arg0
= CALL_EXPR_ARG (exp
, 0);
11743 arg1
= CALL_EXPR_ARG (exp
, 1);
11745 op0
= expand_normal (arg0
);
11746 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
11748 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11749 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
11750 gcc_assert (VECTOR_MODE_P (mode0
));
11752 op0
= force_reg (mode0
, op0
);
11754 if (optimize
|| !target
|| !register_operand (target
, tmode
))
11755 target
= gen_reg_rtx (tmode
);
11757 rs6000_expand_vector_extract (target
, op0
, elt
);
11762 /* Expand the builtin in EXP and store the result in TARGET. Store
11763 true in *EXPANDEDP if we found a builtin to expand. */
11765 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11767 const struct builtin_description
*d
;
11768 const struct builtin_description_predicates
*dp
;
11770 enum insn_code icode
;
11771 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11774 enum machine_mode tmode
, mode0
;
11775 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11777 if ((fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11778 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
11779 || (fcode
>= VSX_BUILTIN_OVERLOADED_FIRST
11780 && fcode
<= VSX_BUILTIN_OVERLOADED_LAST
))
11783 error ("unresolved overload for Altivec builtin %qF", fndecl
);
11787 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
11791 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
11795 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
11803 case ALTIVEC_BUILTIN_STVX
:
11804 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si
, exp
);
11805 case ALTIVEC_BUILTIN_STVEBX
:
11806 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
11807 case ALTIVEC_BUILTIN_STVEHX
:
11808 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
11809 case ALTIVEC_BUILTIN_STVEWX
:
11810 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
11811 case ALTIVEC_BUILTIN_STVXL
:
11812 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
11814 case ALTIVEC_BUILTIN_STVLX
:
11815 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
11816 case ALTIVEC_BUILTIN_STVLXL
:
11817 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
11818 case ALTIVEC_BUILTIN_STVRX
:
11819 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
11820 case ALTIVEC_BUILTIN_STVRXL
:
11821 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
11823 case VSX_BUILTIN_STXVD2X_V2DF
:
11824 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df
, exp
);
11825 case VSX_BUILTIN_STXVD2X_V2DI
:
11826 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di
, exp
);
11827 case VSX_BUILTIN_STXVW4X_V4SF
:
11828 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf
, exp
);
11829 case VSX_BUILTIN_STXVW4X_V4SI
:
11830 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si
, exp
);
11831 case VSX_BUILTIN_STXVW4X_V8HI
:
11832 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi
, exp
);
11833 case VSX_BUILTIN_STXVW4X_V16QI
:
11834 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi
, exp
);
11836 case ALTIVEC_BUILTIN_MFVSCR
:
11837 icode
= CODE_FOR_altivec_mfvscr
;
11838 tmode
= insn_data
[icode
].operand
[0].mode
;
11841 || GET_MODE (target
) != tmode
11842 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11843 target
= gen_reg_rtx (tmode
);
11845 pat
= GEN_FCN (icode
) (target
);
11851 case ALTIVEC_BUILTIN_MTVSCR
:
11852 icode
= CODE_FOR_altivec_mtvscr
;
11853 arg0
= CALL_EXPR_ARG (exp
, 0);
11854 op0
= expand_normal (arg0
);
11855 mode0
= insn_data
[icode
].operand
[0].mode
;
11857 /* If we got invalid arguments bail out before generating bad rtl. */
11858 if (arg0
== error_mark_node
)
11861 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11862 op0
= copy_to_mode_reg (mode0
, op0
);
11864 pat
= GEN_FCN (icode
) (op0
);
11869 case ALTIVEC_BUILTIN_DSSALL
:
11870 emit_insn (gen_altivec_dssall ());
11873 case ALTIVEC_BUILTIN_DSS
:
11874 icode
= CODE_FOR_altivec_dss
;
11875 arg0
= CALL_EXPR_ARG (exp
, 0);
11877 op0
= expand_normal (arg0
);
11878 mode0
= insn_data
[icode
].operand
[0].mode
;
11880 /* If we got invalid arguments bail out before generating bad rtl. */
11881 if (arg0
== error_mark_node
)
11884 if (TREE_CODE (arg0
) != INTEGER_CST
11885 || TREE_INT_CST_LOW (arg0
) & ~0x3)
11887 error ("argument to dss must be a 2-bit unsigned literal");
11891 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11892 op0
= copy_to_mode_reg (mode0
, op0
);
11894 emit_insn (gen_altivec_dss (op0
));
11897 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
11898 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
11899 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
11900 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
11901 case VSX_BUILTIN_VEC_INIT_V2DF
:
11902 case VSX_BUILTIN_VEC_INIT_V2DI
:
11903 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
11905 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
11906 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
11907 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
11908 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
11909 case VSX_BUILTIN_VEC_SET_V2DF
:
11910 case VSX_BUILTIN_VEC_SET_V2DI
:
11911 return altivec_expand_vec_set_builtin (exp
);
11913 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
11914 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
11915 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
11916 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
11917 case VSX_BUILTIN_VEC_EXT_V2DF
:
11918 case VSX_BUILTIN_VEC_EXT_V2DI
:
11919 return altivec_expand_vec_ext_builtin (exp
, target
);
11923 /* Fall through. */
11926 /* Expand abs* operations. */
11928 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
11929 if (d
->code
== fcode
)
11930 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
11932 /* Expand the AltiVec predicates. */
11933 dp
= bdesc_altivec_preds
;
11934 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
11935 if (dp
->code
== fcode
)
11936 return altivec_expand_predicate_builtin (dp
->icode
, exp
, target
);
11938 /* LV* are funky. We initialized them differently. */
11941 case ALTIVEC_BUILTIN_LVSL
:
11942 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
11943 exp
, target
, false);
11944 case ALTIVEC_BUILTIN_LVSR
:
11945 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
11946 exp
, target
, false);
11947 case ALTIVEC_BUILTIN_LVEBX
:
11948 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
11949 exp
, target
, false);
11950 case ALTIVEC_BUILTIN_LVEHX
:
11951 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
11952 exp
, target
, false);
11953 case ALTIVEC_BUILTIN_LVEWX
:
11954 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
11955 exp
, target
, false);
11956 case ALTIVEC_BUILTIN_LVXL
:
11957 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
11958 exp
, target
, false);
11959 case ALTIVEC_BUILTIN_LVX
:
11960 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si
,
11961 exp
, target
, false);
11962 case ALTIVEC_BUILTIN_LVLX
:
11963 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
11964 exp
, target
, true);
11965 case ALTIVEC_BUILTIN_LVLXL
:
11966 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
11967 exp
, target
, true);
11968 case ALTIVEC_BUILTIN_LVRX
:
11969 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
11970 exp
, target
, true);
11971 case ALTIVEC_BUILTIN_LVRXL
:
11972 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
11973 exp
, target
, true);
11974 case VSX_BUILTIN_LXVD2X_V2DF
:
11975 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df
,
11976 exp
, target
, false);
11977 case VSX_BUILTIN_LXVD2X_V2DI
:
11978 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di
,
11979 exp
, target
, false);
11980 case VSX_BUILTIN_LXVW4X_V4SF
:
11981 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf
,
11982 exp
, target
, false);
11983 case VSX_BUILTIN_LXVW4X_V4SI
:
11984 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si
,
11985 exp
, target
, false);
11986 case VSX_BUILTIN_LXVW4X_V8HI
:
11987 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi
,
11988 exp
, target
, false);
11989 case VSX_BUILTIN_LXVW4X_V16QI
:
11990 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi
,
11991 exp
, target
, false);
11995 /* Fall through. */
11998 *expandedp
= false;
12002 /* Expand the builtin in EXP and store the result in TARGET. Store
12003 true in *EXPANDEDP if we found a builtin to expand. */
12005 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
12007 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
12008 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
12009 const struct builtin_description
*d
;
12016 case PAIRED_BUILTIN_STX
:
12017 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
12018 case PAIRED_BUILTIN_LX
:
12019 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
12022 /* Fall through. */
12025 /* Expand the paired predicates. */
12026 d
= bdesc_paired_preds
;
12027 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
12028 if (d
->code
== fcode
)
12029 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
12031 *expandedp
= false;
12035 /* Binops that need to be initialized manually, but can be expanded
12036 automagically by rs6000_expand_binop_builtin. */
12037 static struct builtin_description bdesc_2arg_spe
[] =
12039 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
12040 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
12041 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
12042 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
12043 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
12044 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
12045 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
12046 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
12047 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
12048 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
12049 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
12050 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
12051 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
12052 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
12053 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
12054 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
12055 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
12056 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
12057 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
12058 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
12059 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
12060 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
12063 /* Expand the builtin in EXP and store the result in TARGET. Store
12064 true in *EXPANDEDP if we found a builtin to expand.
12066 This expands the SPE builtins that are not simple unary and binary
12069 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
12071 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
12073 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
12074 enum insn_code icode
;
12075 enum machine_mode tmode
, mode0
;
12077 struct builtin_description
*d
;
12082 /* Syntax check for a 5-bit unsigned immediate. */
12085 case SPE_BUILTIN_EVSTDD
:
12086 case SPE_BUILTIN_EVSTDH
:
12087 case SPE_BUILTIN_EVSTDW
:
12088 case SPE_BUILTIN_EVSTWHE
:
12089 case SPE_BUILTIN_EVSTWHO
:
12090 case SPE_BUILTIN_EVSTWWE
:
12091 case SPE_BUILTIN_EVSTWWO
:
12092 arg1
= CALL_EXPR_ARG (exp
, 2);
12093 if (TREE_CODE (arg1
) != INTEGER_CST
12094 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
12096 error ("argument 2 must be a 5-bit unsigned literal");
12104 /* The evsplat*i instructions are not quite generic. */
12107 case SPE_BUILTIN_EVSPLATFI
:
12108 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
12110 case SPE_BUILTIN_EVSPLATI
:
12111 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
12117 d
= (struct builtin_description
*) bdesc_2arg_spe
;
12118 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
12119 if (d
->code
== fcode
)
12120 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
12122 d
= (struct builtin_description
*) bdesc_spe_predicates
;
12123 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
12124 if (d
->code
== fcode
)
12125 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
12127 d
= (struct builtin_description
*) bdesc_spe_evsel
;
12128 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
12129 if (d
->code
== fcode
)
12130 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
12134 case SPE_BUILTIN_EVSTDDX
:
12135 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
12136 case SPE_BUILTIN_EVSTDHX
:
12137 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
12138 case SPE_BUILTIN_EVSTDWX
:
12139 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
12140 case SPE_BUILTIN_EVSTWHEX
:
12141 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
12142 case SPE_BUILTIN_EVSTWHOX
:
12143 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
12144 case SPE_BUILTIN_EVSTWWEX
:
12145 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
12146 case SPE_BUILTIN_EVSTWWOX
:
12147 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
12148 case SPE_BUILTIN_EVSTDD
:
12149 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
12150 case SPE_BUILTIN_EVSTDH
:
12151 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
12152 case SPE_BUILTIN_EVSTDW
:
12153 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
12154 case SPE_BUILTIN_EVSTWHE
:
12155 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
12156 case SPE_BUILTIN_EVSTWHO
:
12157 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
12158 case SPE_BUILTIN_EVSTWWE
:
12159 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
12160 case SPE_BUILTIN_EVSTWWO
:
12161 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
12162 case SPE_BUILTIN_MFSPEFSCR
:
12163 icode
= CODE_FOR_spe_mfspefscr
;
12164 tmode
= insn_data
[icode
].operand
[0].mode
;
12167 || GET_MODE (target
) != tmode
12168 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
12169 target
= gen_reg_rtx (tmode
);
12171 pat
= GEN_FCN (icode
) (target
);
12176 case SPE_BUILTIN_MTSPEFSCR
:
12177 icode
= CODE_FOR_spe_mtspefscr
;
12178 arg0
= CALL_EXPR_ARG (exp
, 0);
12179 op0
= expand_normal (arg0
);
12180 mode0
= insn_data
[icode
].operand
[0].mode
;
12182 if (arg0
== error_mark_node
)
12185 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
12186 op0
= copy_to_mode_reg (mode0
, op0
);
12188 pat
= GEN_FCN (icode
) (op0
);
12196 *expandedp
= false;
12201 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
12203 rtx pat
, scratch
, tmp
;
12204 tree form
= CALL_EXPR_ARG (exp
, 0);
12205 tree arg0
= CALL_EXPR_ARG (exp
, 1);
12206 tree arg1
= CALL_EXPR_ARG (exp
, 2);
12207 rtx op0
= expand_normal (arg0
);
12208 rtx op1
= expand_normal (arg1
);
12209 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
12210 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
12212 enum rtx_code code
;
12214 if (TREE_CODE (form
) != INTEGER_CST
)
12216 error ("argument 1 of __builtin_paired_predicate must be a constant");
12220 form_int
= TREE_INT_CST_LOW (form
);
12222 gcc_assert (mode0
== mode1
);
12224 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
12228 || GET_MODE (target
) != SImode
12229 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
12230 target
= gen_reg_rtx (SImode
);
12231 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
12232 op0
= copy_to_mode_reg (mode0
, op0
);
12233 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
12234 op1
= copy_to_mode_reg (mode1
, op1
);
12236 scratch
= gen_reg_rtx (CCFPmode
);
12238 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
12260 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
12263 error ("argument 1 of __builtin_paired_predicate is out of range");
12267 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
12268 emit_move_insn (target
, tmp
);
12273 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
12275 rtx pat
, scratch
, tmp
;
12276 tree form
= CALL_EXPR_ARG (exp
, 0);
12277 tree arg0
= CALL_EXPR_ARG (exp
, 1);
12278 tree arg1
= CALL_EXPR_ARG (exp
, 2);
12279 rtx op0
= expand_normal (arg0
);
12280 rtx op1
= expand_normal (arg1
);
12281 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
12282 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
12284 enum rtx_code code
;
12286 if (TREE_CODE (form
) != INTEGER_CST
)
12288 error ("argument 1 of __builtin_spe_predicate must be a constant");
12292 form_int
= TREE_INT_CST_LOW (form
);
12294 gcc_assert (mode0
== mode1
);
12296 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
12300 || GET_MODE (target
) != SImode
12301 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
12302 target
= gen_reg_rtx (SImode
);
12304 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
12305 op0
= copy_to_mode_reg (mode0
, op0
);
12306 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
12307 op1
= copy_to_mode_reg (mode1
, op1
);
12309 scratch
= gen_reg_rtx (CCmode
);
12311 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
12316 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12317 _lower_. We use one compare, but look in different bits of the
12318 CR for each variant.
12320 There are 2 elements in each SPE simd type (upper/lower). The CR
12321 bits are set as follows:
12323 BIT0 | BIT 1 | BIT 2 | BIT 3
12324 U | L | (U | L) | (U & L)
12326 So, for an "all" relationship, BIT 3 would be set.
12327 For an "any" relationship, BIT 2 would be set. Etc.
12329 Following traditional nomenclature, these bits map to:
12331 BIT0 | BIT 1 | BIT 2 | BIT 3
12334 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12339 /* All variant. OV bit. */
12341 /* We need to get to the OV bit, which is the ORDERED bit. We
12342 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12343 that's ugly and will make validate_condition_mode die.
12344 So let's just use another pattern. */
12345 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
12347 /* Any variant. EQ bit. */
12351 /* Upper variant. LT bit. */
12355 /* Lower variant. GT bit. */
12360 error ("argument 1 of __builtin_spe_predicate is out of range");
12364 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
12365 emit_move_insn (target
, tmp
);
12370 /* The evsel builtins look like this:
12372 e = __builtin_spe_evsel_OP (a, b, c, d);
12374 and work like this:
12376 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12377 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12381 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
12384 tree arg0
= CALL_EXPR_ARG (exp
, 0);
12385 tree arg1
= CALL_EXPR_ARG (exp
, 1);
12386 tree arg2
= CALL_EXPR_ARG (exp
, 2);
12387 tree arg3
= CALL_EXPR_ARG (exp
, 3);
12388 rtx op0
= expand_normal (arg0
);
12389 rtx op1
= expand_normal (arg1
);
12390 rtx op2
= expand_normal (arg2
);
12391 rtx op3
= expand_normal (arg3
);
12392 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
12393 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
12395 gcc_assert (mode0
== mode1
);
12397 if (arg0
== error_mark_node
|| arg1
== error_mark_node
12398 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
12402 || GET_MODE (target
) != mode0
12403 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
12404 target
= gen_reg_rtx (mode0
);
12406 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
12407 op0
= copy_to_mode_reg (mode0
, op0
);
12408 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
12409 op1
= copy_to_mode_reg (mode0
, op1
);
12410 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
12411 op2
= copy_to_mode_reg (mode0
, op2
);
12412 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
12413 op3
= copy_to_mode_reg (mode0
, op3
);
12415 /* Generate the compare. */
12416 scratch
= gen_reg_rtx (CCmode
);
12417 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
12422 if (mode0
== V2SImode
)
12423 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
12425 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
12430 /* Expand an expression EXP that calls a built-in function,
12431 with result going to TARGET if that's convenient
12432 (and in mode MODE if that's convenient).
12433 SUBTARGET may be used as the target for computing one of EXP's operands.
12434 IGNORE is nonzero if the value is to be ignored. */
12437 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
12438 enum machine_mode mode ATTRIBUTE_UNUSED
,
12439 int ignore ATTRIBUTE_UNUSED
)
12441 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
12442 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
12443 const struct builtin_description
*d
;
12450 case RS6000_BUILTIN_RECIP
:
12451 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
12453 case RS6000_BUILTIN_RECIPF
:
12454 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
12456 case RS6000_BUILTIN_RSQRTF
:
12457 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
12459 case RS6000_BUILTIN_RSQRT
:
12460 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2
, exp
, target
);
12462 case RS6000_BUILTIN_BSWAP_HI
:
12463 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2
, exp
, target
);
12465 case POWER7_BUILTIN_BPERMD
:
12466 return rs6000_expand_binop_builtin (((TARGET_64BIT
)
12467 ? CODE_FOR_bpermd_di
12468 : CODE_FOR_bpermd_si
), exp
, target
);
12470 case ALTIVEC_BUILTIN_MASK_FOR_LOAD
:
12471 case ALTIVEC_BUILTIN_MASK_FOR_STORE
:
12473 int icode
= (int) CODE_FOR_altivec_lvsr
;
12474 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
12475 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
12479 gcc_assert (TARGET_ALTIVEC
);
12481 arg
= CALL_EXPR_ARG (exp
, 0);
12482 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg
)));
12483 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
12484 addr
= memory_address (mode
, op
);
12485 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
12489 /* For the load case need to negate the address. */
12490 op
= gen_reg_rtx (GET_MODE (addr
));
12491 emit_insn (gen_rtx_SET (VOIDmode
, op
,
12492 gen_rtx_NEG (GET_MODE (addr
), addr
)));
12494 op
= gen_rtx_MEM (mode
, op
);
12497 || GET_MODE (target
) != tmode
12498 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
12499 target
= gen_reg_rtx (tmode
);
12501 /*pat = gen_altivec_lvsr (target, op);*/
12502 pat
= GEN_FCN (icode
) (target
, op
);
12510 case ALTIVEC_BUILTIN_VCFUX
:
12511 case ALTIVEC_BUILTIN_VCFSX
:
12512 case ALTIVEC_BUILTIN_VCTUXS
:
12513 case ALTIVEC_BUILTIN_VCTSXS
:
12514 /* FIXME: There's got to be a nicer way to handle this case than
12515 constructing a new CALL_EXPR. */
12516 if (call_expr_nargs (exp
) == 1)
12518 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
12519 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
12527 if (TARGET_ALTIVEC
)
12529 ret
= altivec_expand_builtin (exp
, target
, &success
);
12536 ret
= spe_expand_builtin (exp
, target
, &success
);
12541 if (TARGET_PAIRED_FLOAT
)
12543 ret
= paired_expand_builtin (exp
, target
, &success
);
12549 gcc_assert (TARGET_ALTIVEC
|| TARGET_VSX
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
12551 /* Handle simple unary operations. */
12552 d
= (struct builtin_description
*) bdesc_1arg
;
12553 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
12554 if (d
->code
== fcode
)
12555 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
12557 /* Handle simple binary operations. */
12558 d
= (struct builtin_description
*) bdesc_2arg
;
12559 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
12560 if (d
->code
== fcode
)
12561 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
12563 /* Handle simple ternary operations. */
12565 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
12566 if (d
->code
== fcode
)
12567 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
12569 gcc_unreachable ();
12573 rs6000_init_builtins (void)
12578 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
12579 V2SF_type_node
= build_vector_type (float_type_node
, 2);
12580 V2DI_type_node
= build_vector_type (intDI_type_node
, 2);
12581 V2DF_type_node
= build_vector_type (double_type_node
, 2);
12582 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
12583 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
12584 V4SF_type_node
= build_vector_type (float_type_node
, 4);
12585 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
12586 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
12588 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
12589 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
12590 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
12591 unsigned_V2DI_type_node
= build_vector_type (unsigned_intDI_type_node
, 2);
12593 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
12594 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
12595 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
12596 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
12598 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12599 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12600 'vector unsigned short'. */
12602 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
12603 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
12604 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
12605 bool_long_type_node
= build_distinct_type_copy (unsigned_intDI_type_node
);
12606 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
12608 long_integer_type_internal_node
= long_integer_type_node
;
12609 long_unsigned_type_internal_node
= long_unsigned_type_node
;
12610 long_long_integer_type_internal_node
= long_long_integer_type_node
;
12611 long_long_unsigned_type_internal_node
= long_long_unsigned_type_node
;
12612 intQI_type_internal_node
= intQI_type_node
;
12613 uintQI_type_internal_node
= unsigned_intQI_type_node
;
12614 intHI_type_internal_node
= intHI_type_node
;
12615 uintHI_type_internal_node
= unsigned_intHI_type_node
;
12616 intSI_type_internal_node
= intSI_type_node
;
12617 uintSI_type_internal_node
= unsigned_intSI_type_node
;
12618 intDI_type_internal_node
= intDI_type_node
;
12619 uintDI_type_internal_node
= unsigned_intDI_type_node
;
12620 float_type_internal_node
= float_type_node
;
12621 double_type_internal_node
= double_type_node
;
12622 void_type_internal_node
= void_type_node
;
12624 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12626 builtin_mode_to_type
[QImode
][0] = integer_type_node
;
12627 builtin_mode_to_type
[HImode
][0] = integer_type_node
;
12628 builtin_mode_to_type
[SImode
][0] = intSI_type_node
;
12629 builtin_mode_to_type
[SImode
][1] = unsigned_intSI_type_node
;
12630 builtin_mode_to_type
[DImode
][0] = intDI_type_node
;
12631 builtin_mode_to_type
[DImode
][1] = unsigned_intDI_type_node
;
12632 builtin_mode_to_type
[SFmode
][0] = float_type_node
;
12633 builtin_mode_to_type
[DFmode
][0] = double_type_node
;
12634 builtin_mode_to_type
[V2SImode
][0] = V2SI_type_node
;
12635 builtin_mode_to_type
[V2SFmode
][0] = V2SF_type_node
;
12636 builtin_mode_to_type
[V2DImode
][0] = V2DI_type_node
;
12637 builtin_mode_to_type
[V2DImode
][1] = unsigned_V2DI_type_node
;
12638 builtin_mode_to_type
[V2DFmode
][0] = V2DF_type_node
;
12639 builtin_mode_to_type
[V4HImode
][0] = V4HI_type_node
;
12640 builtin_mode_to_type
[V4SImode
][0] = V4SI_type_node
;
12641 builtin_mode_to_type
[V4SImode
][1] = unsigned_V4SI_type_node
;
12642 builtin_mode_to_type
[V4SFmode
][0] = V4SF_type_node
;
12643 builtin_mode_to_type
[V8HImode
][0] = V8HI_type_node
;
12644 builtin_mode_to_type
[V8HImode
][1] = unsigned_V8HI_type_node
;
12645 builtin_mode_to_type
[V16QImode
][0] = V16QI_type_node
;
12646 builtin_mode_to_type
[V16QImode
][1] = unsigned_V16QI_type_node
;
12648 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12649 get_identifier ("__bool char"),
12650 bool_char_type_node
);
12651 TYPE_NAME (bool_char_type_node
) = tdecl
;
12652 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12653 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12654 get_identifier ("__bool short"),
12655 bool_short_type_node
);
12656 TYPE_NAME (bool_short_type_node
) = tdecl
;
12657 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12658 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12659 get_identifier ("__bool int"),
12660 bool_int_type_node
);
12661 TYPE_NAME (bool_int_type_node
) = tdecl
;
12662 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12663 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
, get_identifier ("__pixel"),
12665 TYPE_NAME (pixel_type_node
) = tdecl
;
12666 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12668 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
12669 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
12670 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
12671 bool_V2DI_type_node
= build_vector_type (bool_long_type_node
, 2);
12672 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
12674 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12675 get_identifier ("__vector unsigned char"),
12676 unsigned_V16QI_type_node
);
12677 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
12678 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12679 tdecl
= build_decl (BUILTINS_LOCATION
,
12680 TYPE_DECL
, get_identifier ("__vector signed char"),
12682 TYPE_NAME (V16QI_type_node
) = tdecl
;
12683 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12684 tdecl
= build_decl (BUILTINS_LOCATION
,
12685 TYPE_DECL
, get_identifier ("__vector __bool char"),
12686 bool_V16QI_type_node
);
12687 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
12688 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12690 tdecl
= build_decl (BUILTINS_LOCATION
,
12691 TYPE_DECL
, get_identifier ("__vector unsigned short"),
12692 unsigned_V8HI_type_node
);
12693 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
12694 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12695 tdecl
= build_decl (BUILTINS_LOCATION
,
12696 TYPE_DECL
, get_identifier ("__vector signed short"),
12698 TYPE_NAME (V8HI_type_node
) = tdecl
;
12699 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12700 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12701 get_identifier ("__vector __bool short"),
12702 bool_V8HI_type_node
);
12703 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
12704 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12706 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12707 get_identifier ("__vector unsigned int"),
12708 unsigned_V4SI_type_node
);
12709 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
12710 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12711 tdecl
= build_decl (BUILTINS_LOCATION
,
12712 TYPE_DECL
, get_identifier ("__vector signed int"),
12714 TYPE_NAME (V4SI_type_node
) = tdecl
;
12715 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12716 tdecl
= build_decl (BUILTINS_LOCATION
,
12717 TYPE_DECL
, get_identifier ("__vector __bool int"),
12718 bool_V4SI_type_node
);
12719 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
12720 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12722 tdecl
= build_decl (BUILTINS_LOCATION
,
12723 TYPE_DECL
, get_identifier ("__vector float"),
12725 TYPE_NAME (V4SF_type_node
) = tdecl
;
12726 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12727 tdecl
= build_decl (BUILTINS_LOCATION
,
12728 TYPE_DECL
, get_identifier ("__vector __pixel"),
12729 pixel_V8HI_type_node
);
12730 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
12731 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12735 tdecl
= build_decl (BUILTINS_LOCATION
,
12736 TYPE_DECL
, get_identifier ("__vector double"),
12738 TYPE_NAME (V2DF_type_node
) = tdecl
;
12739 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12741 tdecl
= build_decl (BUILTINS_LOCATION
,
12742 TYPE_DECL
, get_identifier ("__vector long"),
12744 TYPE_NAME (V2DI_type_node
) = tdecl
;
12745 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12747 tdecl
= build_decl (BUILTINS_LOCATION
,
12748 TYPE_DECL
, get_identifier ("__vector unsigned long"),
12749 unsigned_V2DI_type_node
);
12750 TYPE_NAME (unsigned_V2DI_type_node
) = tdecl
;
12751 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12753 tdecl
= build_decl (BUILTINS_LOCATION
,
12754 TYPE_DECL
, get_identifier ("__vector __bool long"),
12755 bool_V2DI_type_node
);
12756 TYPE_NAME (bool_V2DI_type_node
) = tdecl
;
12757 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12760 if (TARGET_PAIRED_FLOAT
)
12761 paired_init_builtins ();
12763 spe_init_builtins ();
12764 if (TARGET_ALTIVEC
)
12765 altivec_init_builtins ();
12766 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
|| TARGET_VSX
)
12767 rs6000_common_init_builtins ();
12770 ftype
= builtin_function_type (DFmode
, DFmode
, DFmode
, VOIDmode
,
12771 RS6000_BUILTIN_RECIP
,
12772 "__builtin_recipdiv");
12773 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
12774 RS6000_BUILTIN_RECIP
);
12778 ftype
= builtin_function_type (SFmode
, SFmode
, SFmode
, VOIDmode
,
12779 RS6000_BUILTIN_RECIPF
,
12780 "__builtin_recipdivf");
12781 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
12782 RS6000_BUILTIN_RECIPF
);
12784 if (TARGET_FRSQRTE
)
12786 ftype
= builtin_function_type (DFmode
, DFmode
, VOIDmode
, VOIDmode
,
12787 RS6000_BUILTIN_RSQRT
,
12788 "__builtin_rsqrt");
12789 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrt", ftype
,
12790 RS6000_BUILTIN_RSQRT
);
12792 if (TARGET_FRSQRTES
)
12794 ftype
= builtin_function_type (SFmode
, SFmode
, VOIDmode
, VOIDmode
,
12795 RS6000_BUILTIN_RSQRTF
,
12796 "__builtin_rsqrtf");
12797 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
12798 RS6000_BUILTIN_RSQRTF
);
12800 if (TARGET_POPCNTD
)
12802 enum machine_mode mode
= (TARGET_64BIT
) ? DImode
: SImode
;
12803 tree ftype
= builtin_function_type (mode
, mode
, mode
, VOIDmode
,
12804 POWER7_BUILTIN_BPERMD
,
12805 "__builtin_bpermd");
12806 def_builtin (MASK_POPCNTD
, "__builtin_bpermd", ftype
,
12807 POWER7_BUILTIN_BPERMD
);
12809 if (TARGET_POWERPC
)
12811 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12812 tree ftype
= build_function_type_list (unsigned_intHI_type_node
,
12813 unsigned_intHI_type_node
,
12815 def_builtin (MASK_POWERPC
, "__builtin_bswap16", ftype
,
12816 RS6000_BUILTIN_BSWAP_HI
);
12820 /* AIX libm provides clog as __clog. */
12821 if (built_in_decls
[BUILT_IN_CLOG
])
12822 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
12825 #ifdef SUBTARGET_INIT_BUILTINS
12826 SUBTARGET_INIT_BUILTINS
;
12830 /* Returns the rs6000 builtin decl for CODE. */
12833 rs6000_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
12835 if (code
>= RS6000_BUILTIN_COUNT
)
12836 return error_mark_node
;
12838 return rs6000_builtin_decls
[code
];
12841 /* Search through a set of builtins and enable the mask bits.
12842 DESC is an array of builtins.
12843 SIZE is the total number of builtins.
12844 START is the builtin enum at which to start.
12845 END is the builtin enum at which to end. */
12847 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
12848 enum rs6000_builtins start
,
12849 enum rs6000_builtins end
)
12853 for (i
= 0; i
< size
; ++i
)
12854 if (desc
[i
].code
== start
)
12860 for (; i
< size
; ++i
)
12862 /* Flip all the bits on. */
12863 desc
[i
].mask
= target_flags
;
12864 if (desc
[i
].code
== end
)
12870 spe_init_builtins (void)
12872 tree endlink
= void_list_node
;
12873 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
12874 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
12875 struct builtin_description
*d
;
12878 tree v2si_ftype_4_v2si
12879 = build_function_type
12880 (opaque_V2SI_type_node
,
12881 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12882 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12883 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12884 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12887 tree v2sf_ftype_4_v2sf
12888 = build_function_type
12889 (opaque_V2SF_type_node
,
12890 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12891 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12892 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12893 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12896 tree int_ftype_int_v2si_v2si
12897 = build_function_type
12898 (integer_type_node
,
12899 tree_cons (NULL_TREE
, integer_type_node
,
12900 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12901 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12904 tree int_ftype_int_v2sf_v2sf
12905 = build_function_type
12906 (integer_type_node
,
12907 tree_cons (NULL_TREE
, integer_type_node
,
12908 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12909 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12912 tree void_ftype_v2si_puint_int
12913 = build_function_type (void_type_node
,
12914 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12915 tree_cons (NULL_TREE
, puint_type_node
,
12916 tree_cons (NULL_TREE
,
12920 tree void_ftype_v2si_puint_char
12921 = build_function_type (void_type_node
,
12922 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12923 tree_cons (NULL_TREE
, puint_type_node
,
12924 tree_cons (NULL_TREE
,
12928 tree void_ftype_v2si_pv2si_int
12929 = build_function_type (void_type_node
,
12930 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12931 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12932 tree_cons (NULL_TREE
,
12936 tree void_ftype_v2si_pv2si_char
12937 = build_function_type (void_type_node
,
12938 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12939 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12940 tree_cons (NULL_TREE
,
12944 tree void_ftype_int
12945 = build_function_type (void_type_node
,
12946 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
12948 tree int_ftype_void
12949 = build_function_type (integer_type_node
, endlink
);
12951 tree v2si_ftype_pv2si_int
12952 = build_function_type (opaque_V2SI_type_node
,
12953 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12954 tree_cons (NULL_TREE
, integer_type_node
,
12957 tree v2si_ftype_puint_int
12958 = build_function_type (opaque_V2SI_type_node
,
12959 tree_cons (NULL_TREE
, puint_type_node
,
12960 tree_cons (NULL_TREE
, integer_type_node
,
12963 tree v2si_ftype_pushort_int
12964 = build_function_type (opaque_V2SI_type_node
,
12965 tree_cons (NULL_TREE
, pushort_type_node
,
12966 tree_cons (NULL_TREE
, integer_type_node
,
12969 tree v2si_ftype_signed_char
12970 = build_function_type (opaque_V2SI_type_node
,
12971 tree_cons (NULL_TREE
, signed_char_type_node
,
12974 /* The initialization of the simple binary and unary builtins is
12975 done in rs6000_common_init_builtins, but we have to enable the
12976 mask bits here manually because we have run out of `target_flags'
12977 bits. We really need to redesign this mask business. */
12979 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
12980 ARRAY_SIZE (bdesc_2arg
),
12981 SPE_BUILTIN_EVADDW
,
12982 SPE_BUILTIN_EVXOR
);
12983 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
12984 ARRAY_SIZE (bdesc_1arg
),
12986 SPE_BUILTIN_EVSUBFUSIAAW
);
12987 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
12988 ARRAY_SIZE (bdesc_spe_predicates
),
12989 SPE_BUILTIN_EVCMPEQ
,
12990 SPE_BUILTIN_EVFSTSTLT
);
12991 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
12992 ARRAY_SIZE (bdesc_spe_evsel
),
12993 SPE_BUILTIN_EVSEL_CMPGTS
,
12994 SPE_BUILTIN_EVSEL_FSTSTEQ
);
12996 (*lang_hooks
.decls
.pushdecl
)
12997 (build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12998 get_identifier ("__ev64_opaque__"),
12999 opaque_V2SI_type_node
));
13001 /* Initialize irregular SPE builtins. */
13003 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
13004 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
13005 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
13006 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
13007 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
13008 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
13009 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
13010 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
13011 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
13012 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
13013 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
13014 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
13015 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
13016 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
13017 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
13018 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
13019 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
13020 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
13023 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
13024 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
13025 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
13026 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
13027 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
13028 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
13029 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
13030 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
13031 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
13032 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
13033 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
13034 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
13035 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
13036 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
13037 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
13038 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
13039 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
13040 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
13041 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
13042 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
13043 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
13044 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
13047 d
= (struct builtin_description
*) bdesc_spe_predicates
;
13048 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
13052 switch (insn_data
[d
->icode
].operand
[1].mode
)
13055 type
= int_ftype_int_v2si_v2si
;
13058 type
= int_ftype_int_v2sf_v2sf
;
13061 gcc_unreachable ();
13064 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13067 /* Evsel predicates. */
13068 d
= (struct builtin_description
*) bdesc_spe_evsel
;
13069 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
13073 switch (insn_data
[d
->icode
].operand
[1].mode
)
13076 type
= v2si_ftype_4_v2si
;
13079 type
= v2sf_ftype_4_v2sf
;
13082 gcc_unreachable ();
13085 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13090 paired_init_builtins (void)
13092 const struct builtin_description
*d
;
13094 tree endlink
= void_list_node
;
13096 tree int_ftype_int_v2sf_v2sf
13097 = build_function_type
13098 (integer_type_node
,
13099 tree_cons (NULL_TREE
, integer_type_node
,
13100 tree_cons (NULL_TREE
, V2SF_type_node
,
13101 tree_cons (NULL_TREE
, V2SF_type_node
,
13103 tree pcfloat_type_node
=
13104 build_pointer_type (build_qualified_type
13105 (float_type_node
, TYPE_QUAL_CONST
));
13107 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
13108 long_integer_type_node
,
13111 tree void_ftype_v2sf_long_pcfloat
=
13112 build_function_type_list (void_type_node
,
13114 long_integer_type_node
,
13119 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
13120 PAIRED_BUILTIN_LX
);
13123 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
13124 PAIRED_BUILTIN_STX
);
13127 d
= bdesc_paired_preds
;
13128 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
13132 switch (insn_data
[d
->icode
].operand
[1].mode
)
13135 type
= int_ftype_int_v2sf_v2sf
;
13138 gcc_unreachable ();
13141 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13146 altivec_init_builtins (void)
13148 const struct builtin_description
*d
;
13149 const struct builtin_description_predicates
*dp
;
13153 tree pvoid_type_node
= build_pointer_type (void_type_node
);
13155 tree pcvoid_type_node
13156 = build_pointer_type (build_qualified_type (void_type_node
,
13159 tree int_ftype_opaque
13160 = build_function_type_list (integer_type_node
,
13161 opaque_V4SI_type_node
, NULL_TREE
);
13162 tree opaque_ftype_opaque
13163 = build_function_type (integer_type_node
,
13165 tree opaque_ftype_opaque_int
13166 = build_function_type_list (opaque_V4SI_type_node
,
13167 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
13168 tree opaque_ftype_opaque_opaque_int
13169 = build_function_type_list (opaque_V4SI_type_node
,
13170 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
13171 integer_type_node
, NULL_TREE
);
13172 tree int_ftype_int_opaque_opaque
13173 = build_function_type_list (integer_type_node
,
13174 integer_type_node
, opaque_V4SI_type_node
,
13175 opaque_V4SI_type_node
, NULL_TREE
);
13176 tree int_ftype_int_v4si_v4si
13177 = build_function_type_list (integer_type_node
,
13178 integer_type_node
, V4SI_type_node
,
13179 V4SI_type_node
, NULL_TREE
);
13180 tree void_ftype_v4si
13181 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
13182 tree v8hi_ftype_void
13183 = build_function_type (V8HI_type_node
, void_list_node
);
13184 tree void_ftype_void
13185 = build_function_type (void_type_node
, void_list_node
);
13186 tree void_ftype_int
13187 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
13189 tree opaque_ftype_long_pcvoid
13190 = build_function_type_list (opaque_V4SI_type_node
,
13191 long_integer_type_node
, pcvoid_type_node
,
13193 tree v16qi_ftype_long_pcvoid
13194 = build_function_type_list (V16QI_type_node
,
13195 long_integer_type_node
, pcvoid_type_node
,
13197 tree v8hi_ftype_long_pcvoid
13198 = build_function_type_list (V8HI_type_node
,
13199 long_integer_type_node
, pcvoid_type_node
,
13201 tree v4si_ftype_long_pcvoid
13202 = build_function_type_list (V4SI_type_node
,
13203 long_integer_type_node
, pcvoid_type_node
,
13205 tree v4sf_ftype_long_pcvoid
13206 = build_function_type_list (V4SF_type_node
,
13207 long_integer_type_node
, pcvoid_type_node
,
13209 tree v2df_ftype_long_pcvoid
13210 = build_function_type_list (V2DF_type_node
,
13211 long_integer_type_node
, pcvoid_type_node
,
13213 tree v2di_ftype_long_pcvoid
13214 = build_function_type_list (V2DI_type_node
,
13215 long_integer_type_node
, pcvoid_type_node
,
13218 tree void_ftype_opaque_long_pvoid
13219 = build_function_type_list (void_type_node
,
13220 opaque_V4SI_type_node
, long_integer_type_node
,
13221 pvoid_type_node
, NULL_TREE
);
13222 tree void_ftype_v4si_long_pvoid
13223 = build_function_type_list (void_type_node
,
13224 V4SI_type_node
, long_integer_type_node
,
13225 pvoid_type_node
, NULL_TREE
);
13226 tree void_ftype_v16qi_long_pvoid
13227 = build_function_type_list (void_type_node
,
13228 V16QI_type_node
, long_integer_type_node
,
13229 pvoid_type_node
, NULL_TREE
);
13230 tree void_ftype_v8hi_long_pvoid
13231 = build_function_type_list (void_type_node
,
13232 V8HI_type_node
, long_integer_type_node
,
13233 pvoid_type_node
, NULL_TREE
);
13234 tree void_ftype_v4sf_long_pvoid
13235 = build_function_type_list (void_type_node
,
13236 V4SF_type_node
, long_integer_type_node
,
13237 pvoid_type_node
, NULL_TREE
);
13238 tree void_ftype_v2df_long_pvoid
13239 = build_function_type_list (void_type_node
,
13240 V2DF_type_node
, long_integer_type_node
,
13241 pvoid_type_node
, NULL_TREE
);
13242 tree void_ftype_v2di_long_pvoid
13243 = build_function_type_list (void_type_node
,
13244 V2DI_type_node
, long_integer_type_node
,
13245 pvoid_type_node
, NULL_TREE
);
13246 tree int_ftype_int_v8hi_v8hi
13247 = build_function_type_list (integer_type_node
,
13248 integer_type_node
, V8HI_type_node
,
13249 V8HI_type_node
, NULL_TREE
);
13250 tree int_ftype_int_v16qi_v16qi
13251 = build_function_type_list (integer_type_node
,
13252 integer_type_node
, V16QI_type_node
,
13253 V16QI_type_node
, NULL_TREE
);
13254 tree int_ftype_int_v4sf_v4sf
13255 = build_function_type_list (integer_type_node
,
13256 integer_type_node
, V4SF_type_node
,
13257 V4SF_type_node
, NULL_TREE
);
13258 tree int_ftype_int_v2df_v2df
13259 = build_function_type_list (integer_type_node
,
13260 integer_type_node
, V2DF_type_node
,
13261 V2DF_type_node
, NULL_TREE
);
13262 tree v4si_ftype_v4si
13263 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
13264 tree v8hi_ftype_v8hi
13265 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
13266 tree v16qi_ftype_v16qi
13267 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
13268 tree v4sf_ftype_v4sf
13269 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
13270 tree v2df_ftype_v2df
13271 = build_function_type_list (V2DF_type_node
, V2DF_type_node
, NULL_TREE
);
13272 tree void_ftype_pcvoid_int_int
13273 = build_function_type_list (void_type_node
,
13274 pcvoid_type_node
, integer_type_node
,
13275 integer_type_node
, NULL_TREE
);
13277 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
13278 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
13279 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
13280 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
13281 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
13282 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
13283 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
13284 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
13285 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
13286 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
13287 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
13288 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
13289 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
13290 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
13291 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
13292 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
13293 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
13294 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
13295 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
13296 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
13297 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
13298 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
13299 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
13300 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
13301 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
13302 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
13303 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
13304 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
13305 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
13306 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
13308 def_builtin (MASK_VSX
, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid
,
13309 VSX_BUILTIN_LXVD2X_V2DF
);
13310 def_builtin (MASK_VSX
, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid
,
13311 VSX_BUILTIN_LXVD2X_V2DI
);
13312 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid
,
13313 VSX_BUILTIN_LXVW4X_V4SF
);
13314 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid
,
13315 VSX_BUILTIN_LXVW4X_V4SI
);
13316 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v8hi",
13317 v8hi_ftype_long_pcvoid
, VSX_BUILTIN_LXVW4X_V8HI
);
13318 def_builtin (MASK_VSX
, "__builtin_vsx_lxvw4x_v16qi",
13319 v16qi_ftype_long_pcvoid
, VSX_BUILTIN_LXVW4X_V16QI
);
13320 def_builtin (MASK_VSX
, "__builtin_vsx_stxvd2x_v2df",
13321 void_ftype_v2df_long_pvoid
, VSX_BUILTIN_STXVD2X_V2DF
);
13322 def_builtin (MASK_VSX
, "__builtin_vsx_stxvd2x_v2di",
13323 void_ftype_v2di_long_pvoid
, VSX_BUILTIN_STXVD2X_V2DI
);
13324 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v4sf",
13325 void_ftype_v4sf_long_pvoid
, VSX_BUILTIN_STXVW4X_V4SF
);
13326 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v4si",
13327 void_ftype_v4si_long_pvoid
, VSX_BUILTIN_STXVW4X_V4SI
);
13328 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v8hi",
13329 void_ftype_v8hi_long_pvoid
, VSX_BUILTIN_STXVW4X_V8HI
);
13330 def_builtin (MASK_VSX
, "__builtin_vsx_stxvw4x_v16qi",
13331 void_ftype_v16qi_long_pvoid
, VSX_BUILTIN_STXVW4X_V16QI
);
13332 def_builtin (MASK_VSX
, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid
,
13333 VSX_BUILTIN_VEC_LD
);
13334 def_builtin (MASK_VSX
, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid
,
13335 VSX_BUILTIN_VEC_ST
);
13337 if (rs6000_cpu
== PROCESSOR_CELL
)
13339 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
13340 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
13341 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
13342 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
13344 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
13345 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
13346 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
13347 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
13349 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
13350 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
13351 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
13352 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
13354 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
13355 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
13356 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
13357 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
13359 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
13360 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
13361 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
13363 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
13364 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
13365 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
13366 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
13367 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
13368 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
13369 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
13370 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
13371 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
13372 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
13373 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
13374 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
13376 /* Add the DST variants. */
13378 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
13379 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
13381 /* Initialize the predicates. */
13382 dp
= bdesc_altivec_preds
;
13383 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
13385 enum machine_mode mode1
;
13387 bool is_overloaded
= ((dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13388 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13389 || (dp
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13390 && dp
->code
<= VSX_BUILTIN_OVERLOADED_LAST
));
13395 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
13400 type
= int_ftype_int_opaque_opaque
;
13403 type
= int_ftype_int_v4si_v4si
;
13406 type
= int_ftype_int_v8hi_v8hi
;
13409 type
= int_ftype_int_v16qi_v16qi
;
13412 type
= int_ftype_int_v4sf_v4sf
;
13415 type
= int_ftype_int_v2df_v2df
;
13418 gcc_unreachable ();
13421 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
13424 /* Initialize the abs* operators. */
13426 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
13428 enum machine_mode mode0
;
13431 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
13436 type
= v4si_ftype_v4si
;
13439 type
= v8hi_ftype_v8hi
;
13442 type
= v16qi_ftype_v16qi
;
13445 type
= v4sf_ftype_v4sf
;
13448 type
= v2df_ftype_v2df
;
13451 gcc_unreachable ();
13454 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13457 if (TARGET_ALTIVEC
)
13461 /* Initialize target builtin that implements
13462 targetm.vectorize.builtin_mask_for_load. */
13464 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
13465 v16qi_ftype_long_pcvoid
,
13466 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
13467 BUILT_IN_MD
, NULL
, NULL_TREE
);
13468 TREE_READONLY (decl
) = 1;
13469 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13470 altivec_builtin_mask_for_load
= decl
;
13473 /* Access to the vec_init patterns. */
13474 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
13475 integer_type_node
, integer_type_node
,
13476 integer_type_node
, NULL_TREE
);
13477 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
13478 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
13480 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
13481 short_integer_type_node
,
13482 short_integer_type_node
,
13483 short_integer_type_node
,
13484 short_integer_type_node
,
13485 short_integer_type_node
,
13486 short_integer_type_node
,
13487 short_integer_type_node
, NULL_TREE
);
13488 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
13489 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
13491 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
13492 char_type_node
, char_type_node
,
13493 char_type_node
, char_type_node
,
13494 char_type_node
, char_type_node
,
13495 char_type_node
, char_type_node
,
13496 char_type_node
, char_type_node
,
13497 char_type_node
, char_type_node
,
13498 char_type_node
, char_type_node
,
13499 char_type_node
, NULL_TREE
);
13500 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
13501 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
13503 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
13504 float_type_node
, float_type_node
,
13505 float_type_node
, NULL_TREE
);
13506 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
13507 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
13511 ftype
= build_function_type_list (V2DF_type_node
, double_type_node
,
13512 double_type_node
, NULL_TREE
);
13513 def_builtin (MASK_VSX
, "__builtin_vec_init_v2df", ftype
,
13514 VSX_BUILTIN_VEC_INIT_V2DF
);
13516 ftype
= build_function_type_list (V2DI_type_node
, intDI_type_node
,
13517 intDI_type_node
, NULL_TREE
);
13518 def_builtin (MASK_VSX
, "__builtin_vec_init_v2di", ftype
,
13519 VSX_BUILTIN_VEC_INIT_V2DI
);
13522 /* Access to the vec_set patterns. */
13523 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
13525 integer_type_node
, NULL_TREE
);
13526 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
13527 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
13529 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
13531 integer_type_node
, NULL_TREE
);
13532 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
13533 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
13535 ftype
= build_function_type_list (V16QI_type_node
, V16QI_type_node
,
13537 integer_type_node
, NULL_TREE
);
13538 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
13539 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
13541 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
13543 integer_type_node
, NULL_TREE
);
13544 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_set_v4sf", ftype
,
13545 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
13549 ftype
= build_function_type_list (V2DF_type_node
, V2DF_type_node
,
13551 integer_type_node
, NULL_TREE
);
13552 def_builtin (MASK_VSX
, "__builtin_vec_set_v2df", ftype
,
13553 VSX_BUILTIN_VEC_SET_V2DF
);
13555 ftype
= build_function_type_list (V2DI_type_node
, V2DI_type_node
,
13557 integer_type_node
, NULL_TREE
);
13558 def_builtin (MASK_VSX
, "__builtin_vec_set_v2di", ftype
,
13559 VSX_BUILTIN_VEC_SET_V2DI
);
13562 /* Access to the vec_extract patterns. */
13563 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
13564 integer_type_node
, NULL_TREE
);
13565 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
13566 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
13568 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
13569 integer_type_node
, NULL_TREE
);
13570 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
13571 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
13573 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
13574 integer_type_node
, NULL_TREE
);
13575 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
13576 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
13578 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
13579 integer_type_node
, NULL_TREE
);
13580 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_ext_v4sf", ftype
,
13581 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
13585 ftype
= build_function_type_list (double_type_node
, V2DF_type_node
,
13586 integer_type_node
, NULL_TREE
);
13587 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2df", ftype
,
13588 VSX_BUILTIN_VEC_EXT_V2DF
);
13590 ftype
= build_function_type_list (intDI_type_node
, V2DI_type_node
,
13591 integer_type_node
, NULL_TREE
);
13592 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2di", ftype
,
13593 VSX_BUILTIN_VEC_EXT_V2DI
);
13597 /* Hash function for builtin functions with up to 3 arguments and a return
13600 builtin_hash_function (const void *hash_entry
)
13604 const struct builtin_hash_struct
*bh
=
13605 (const struct builtin_hash_struct
*) hash_entry
;
13607 for (i
= 0; i
< 4; i
++)
13609 ret
= (ret
* (unsigned)MAX_MACHINE_MODE
) + ((unsigned)bh
->mode
[i
]);
13610 ret
= (ret
* 2) + bh
->uns_p
[i
];
13616 /* Compare builtin hash entries H1 and H2 for equivalence. */
13618 builtin_hash_eq (const void *h1
, const void *h2
)
13620 const struct builtin_hash_struct
*p1
= (const struct builtin_hash_struct
*) h1
;
13621 const struct builtin_hash_struct
*p2
= (const struct builtin_hash_struct
*) h2
;
13623 return ((p1
->mode
[0] == p2
->mode
[0])
13624 && (p1
->mode
[1] == p2
->mode
[1])
13625 && (p1
->mode
[2] == p2
->mode
[2])
13626 && (p1
->mode
[3] == p2
->mode
[3])
13627 && (p1
->uns_p
[0] == p2
->uns_p
[0])
13628 && (p1
->uns_p
[1] == p2
->uns_p
[1])
13629 && (p1
->uns_p
[2] == p2
->uns_p
[2])
13630 && (p1
->uns_p
[3] == p2
->uns_p
[3]));
13633 /* Map types for builtin functions with an explicit return type and up to 3
13634 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13635 of the argument. */
13637 builtin_function_type (enum machine_mode mode_ret
, enum machine_mode mode_arg0
,
13638 enum machine_mode mode_arg1
, enum machine_mode mode_arg2
,
13639 enum rs6000_builtins builtin
, const char *name
)
13641 struct builtin_hash_struct h
;
13642 struct builtin_hash_struct
*h2
;
13646 tree ret_type
= NULL_TREE
;
13647 tree arg_type
[3] = { NULL_TREE
, NULL_TREE
, NULL_TREE
};
13650 /* Create builtin_hash_table. */
13651 if (builtin_hash_table
== NULL
)
13652 builtin_hash_table
= htab_create_ggc (1500, builtin_hash_function
,
13653 builtin_hash_eq
, NULL
);
13655 h
.type
= NULL_TREE
;
13656 h
.mode
[0] = mode_ret
;
13657 h
.mode
[1] = mode_arg0
;
13658 h
.mode
[2] = mode_arg1
;
13659 h
.mode
[3] = mode_arg2
;
13665 /* If the builtin is a type that produces unsigned results or takes unsigned
13666 arguments, and it is returned as a decl for the vectorizer (such as
13667 widening multiplies, permute), make sure the arguments and return value
13668 are type correct. */
13671 /* unsigned 2 argument functions. */
13672 case ALTIVEC_BUILTIN_VMULEUB_UNS
:
13673 case ALTIVEC_BUILTIN_VMULEUH_UNS
:
13674 case ALTIVEC_BUILTIN_VMULOUB_UNS
:
13675 case ALTIVEC_BUILTIN_VMULOUH_UNS
:
13681 /* unsigned 3 argument functions. */
13682 case ALTIVEC_BUILTIN_VPERM_16QI_UNS
:
13683 case ALTIVEC_BUILTIN_VPERM_8HI_UNS
:
13684 case ALTIVEC_BUILTIN_VPERM_4SI_UNS
:
13685 case ALTIVEC_BUILTIN_VPERM_2DI_UNS
:
13686 case ALTIVEC_BUILTIN_VSEL_16QI_UNS
:
13687 case ALTIVEC_BUILTIN_VSEL_8HI_UNS
:
13688 case ALTIVEC_BUILTIN_VSEL_4SI_UNS
:
13689 case ALTIVEC_BUILTIN_VSEL_2DI_UNS
:
13690 case VSX_BUILTIN_VPERM_16QI_UNS
:
13691 case VSX_BUILTIN_VPERM_8HI_UNS
:
13692 case VSX_BUILTIN_VPERM_4SI_UNS
:
13693 case VSX_BUILTIN_VPERM_2DI_UNS
:
13694 case VSX_BUILTIN_XXSEL_16QI_UNS
:
13695 case VSX_BUILTIN_XXSEL_8HI_UNS
:
13696 case VSX_BUILTIN_XXSEL_4SI_UNS
:
13697 case VSX_BUILTIN_XXSEL_2DI_UNS
:
13704 /* signed permute functions with unsigned char mask. */
13705 case ALTIVEC_BUILTIN_VPERM_16QI
:
13706 case ALTIVEC_BUILTIN_VPERM_8HI
:
13707 case ALTIVEC_BUILTIN_VPERM_4SI
:
13708 case ALTIVEC_BUILTIN_VPERM_4SF
:
13709 case ALTIVEC_BUILTIN_VPERM_2DI
:
13710 case ALTIVEC_BUILTIN_VPERM_2DF
:
13711 case VSX_BUILTIN_VPERM_16QI
:
13712 case VSX_BUILTIN_VPERM_8HI
:
13713 case VSX_BUILTIN_VPERM_4SI
:
13714 case VSX_BUILTIN_VPERM_4SF
:
13715 case VSX_BUILTIN_VPERM_2DI
:
13716 case VSX_BUILTIN_VPERM_2DF
:
13720 /* unsigned args, signed return. */
13721 case VSX_BUILTIN_XVCVUXDDP_UNS
:
13722 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
:
13726 /* signed args, unsigned return. */
13727 case VSX_BUILTIN_XVCVDPUXDS_UNS
:
13728 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
:
13736 /* Figure out how many args are present. */
13737 while (num_args
> 0 && h
.mode
[num_args
] == VOIDmode
)
13741 fatal_error ("internal error: builtin function %s had no type", name
);
13743 ret_type
= builtin_mode_to_type
[h
.mode
[0]][h
.uns_p
[0]];
13744 if (!ret_type
&& h
.uns_p
[0])
13745 ret_type
= builtin_mode_to_type
[h
.mode
[0]][0];
13748 fatal_error ("internal error: builtin function %s had an unexpected "
13749 "return type %s", name
, GET_MODE_NAME (h
.mode
[0]));
13751 for (i
= 0; i
< num_args
; i
++)
13753 int m
= (int) h
.mode
[i
+1];
13754 int uns_p
= h
.uns_p
[i
+1];
13756 arg_type
[i
] = builtin_mode_to_type
[m
][uns_p
];
13757 if (!arg_type
[i
] && uns_p
)
13758 arg_type
[i
] = builtin_mode_to_type
[m
][0];
13761 fatal_error ("internal error: builtin function %s, argument %d "
13762 "had unexpected argument type %s", name
, i
,
13763 GET_MODE_NAME (m
));
13766 found
= htab_find_slot (builtin_hash_table
, &h
, INSERT
);
13767 if (*found
== NULL
)
13769 h2
= ggc_alloc_builtin_hash_struct ();
13771 *found
= (void *)h2
;
13772 args
= void_list_node
;
13774 for (i
= num_args
- 1; i
>= 0; i
--)
13775 args
= tree_cons (NULL_TREE
, arg_type
[i
], args
);
13777 h2
->type
= build_function_type (ret_type
, args
);
13780 return ((struct builtin_hash_struct
*)(*found
))->type
;
13784 rs6000_common_init_builtins (void)
13786 const struct builtin_description
*d
;
13789 tree opaque_ftype_opaque
= NULL_TREE
;
13790 tree opaque_ftype_opaque_opaque
= NULL_TREE
;
13791 tree opaque_ftype_opaque_opaque_opaque
= NULL_TREE
;
13792 tree v2si_ftype_qi
= NULL_TREE
;
13793 tree v2si_ftype_v2si_qi
= NULL_TREE
;
13794 tree v2si_ftype_int_qi
= NULL_TREE
;
13796 if (!TARGET_PAIRED_FLOAT
)
13798 builtin_mode_to_type
[V2SImode
][0] = opaque_V2SI_type_node
;
13799 builtin_mode_to_type
[V2SFmode
][0] = opaque_V2SF_type_node
;
13802 /* Add the ternary operators. */
13804 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
13807 int mask
= d
->mask
;
13809 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13810 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13813 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13814 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13815 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13816 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13818 if (! (type
= opaque_ftype_opaque_opaque_opaque
))
13819 type
= opaque_ftype_opaque_opaque_opaque
13820 = build_function_type_list (opaque_V4SI_type_node
,
13821 opaque_V4SI_type_node
,
13822 opaque_V4SI_type_node
,
13823 opaque_V4SI_type_node
,
13828 enum insn_code icode
= d
->icode
;
13829 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13832 type
= builtin_function_type (insn_data
[icode
].operand
[0].mode
,
13833 insn_data
[icode
].operand
[1].mode
,
13834 insn_data
[icode
].operand
[2].mode
,
13835 insn_data
[icode
].operand
[3].mode
,
13839 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13842 /* Add the binary operators. */
13844 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
13846 enum machine_mode mode0
, mode1
, mode2
;
13848 int mask
= d
->mask
;
13850 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13851 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13854 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13855 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13856 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13857 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13859 if (! (type
= opaque_ftype_opaque_opaque
))
13860 type
= opaque_ftype_opaque_opaque
13861 = build_function_type_list (opaque_V4SI_type_node
,
13862 opaque_V4SI_type_node
,
13863 opaque_V4SI_type_node
,
13868 enum insn_code icode
= d
->icode
;
13869 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13872 mode0
= insn_data
[icode
].operand
[0].mode
;
13873 mode1
= insn_data
[icode
].operand
[1].mode
;
13874 mode2
= insn_data
[icode
].operand
[2].mode
;
13876 if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
13878 if (! (type
= v2si_ftype_v2si_qi
))
13879 type
= v2si_ftype_v2si_qi
13880 = build_function_type_list (opaque_V2SI_type_node
,
13881 opaque_V2SI_type_node
,
13886 else if (mode0
== V2SImode
&& GET_MODE_CLASS (mode1
) == MODE_INT
13887 && mode2
== QImode
)
13889 if (! (type
= v2si_ftype_int_qi
))
13890 type
= v2si_ftype_int_qi
13891 = build_function_type_list (opaque_V2SI_type_node
,
13898 type
= builtin_function_type (mode0
, mode1
, mode2
, VOIDmode
,
13902 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13905 /* Add the simple unary operators. */
13906 d
= (struct builtin_description
*) bdesc_1arg
;
13907 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
13909 enum machine_mode mode0
, mode1
;
13911 int mask
= d
->mask
;
13913 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13914 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13917 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13918 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13919 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13920 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13922 if (! (type
= opaque_ftype_opaque
))
13923 type
= opaque_ftype_opaque
13924 = build_function_type_list (opaque_V4SI_type_node
,
13925 opaque_V4SI_type_node
,
13930 enum insn_code icode
= d
->icode
;
13931 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13934 mode0
= insn_data
[icode
].operand
[0].mode
;
13935 mode1
= insn_data
[icode
].operand
[1].mode
;
13937 if (mode0
== V2SImode
&& mode1
== QImode
)
13939 if (! (type
= v2si_ftype_qi
))
13940 type
= v2si_ftype_qi
13941 = build_function_type_list (opaque_V2SI_type_node
,
13947 type
= builtin_function_type (mode0
, mode1
, VOIDmode
, VOIDmode
,
13951 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13956 rs6000_init_libfuncs (void)
13958 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
13959 && !TARGET_POWER2
&& !TARGET_POWERPC
)
13961 /* AIX library routines for float->int conversion. */
13962 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
13963 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
13964 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
13965 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
13968 if (!TARGET_IEEEQUAD
)
13969 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13970 if (!TARGET_XL_COMPAT
)
13972 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
13973 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
13974 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
13975 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
13977 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
13979 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
13980 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
13981 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
13982 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
13983 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
13984 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
13985 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
13987 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
13988 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
13989 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
13990 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
13991 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
13992 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
13993 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
13994 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
13997 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
13998 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
14002 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
14003 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
14004 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
14005 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
14009 /* 32-bit SVR4 quad floating point routines. */
14011 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
14012 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
14013 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
14014 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
14015 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
14016 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
14017 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
14019 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
14020 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
14021 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
14022 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
14023 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
14024 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
14026 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
14027 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
14028 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
14029 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
14030 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
14031 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
14032 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
14033 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
14038 /* Expand a block clear operation, and return 1 if successful. Return 0
14039 if we should let the compiler generate normal code.
14041 operands[0] is the destination
14042 operands[1] is the length
14043 operands[3] is the alignment */
14046 expand_block_clear (rtx operands
[])
14048 rtx orig_dest
= operands
[0];
14049 rtx bytes_rtx
= operands
[1];
14050 rtx align_rtx
= operands
[3];
14051 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
14052 HOST_WIDE_INT align
;
14053 HOST_WIDE_INT bytes
;
14058 /* If this is not a fixed size move, just call memcpy */
14062 /* This must be a fixed size alignment */
14063 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
14064 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
14066 /* Anything to clear? */
14067 bytes
= INTVAL (bytes_rtx
);
14071 /* Use the builtin memset after a point, to avoid huge code bloat.
14072 When optimize_size, avoid any significant code bloat; calling
14073 memset is about 4 instructions, so allow for one instruction to
14074 load zero and three to do clearing. */
14075 if (TARGET_ALTIVEC
&& align
>= 128)
14077 else if (TARGET_POWERPC64
&& align
>= 32)
14079 else if (TARGET_SPE
&& align
>= 64)
14084 if (optimize_size
&& bytes
> 3 * clear_step
)
14086 if (! optimize_size
&& bytes
> 8 * clear_step
)
14089 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
14091 enum machine_mode mode
= BLKmode
;
14094 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
14099 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
14104 else if (bytes
>= 8 && TARGET_POWERPC64
14105 /* 64-bit loads and stores require word-aligned
14107 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
14112 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
14113 { /* move 4 bytes */
14117 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
14118 { /* move 2 bytes */
14122 else /* move 1 byte at a time */
14128 dest
= adjust_address (orig_dest
, mode
, offset
);
14130 emit_move_insn (dest
, CONST0_RTX (mode
));
14137 /* Expand a block move operation, and return 1 if successful. Return 0
14138 if we should let the compiler generate normal code.
14140 operands[0] is the destination
14141 operands[1] is the source
14142 operands[2] is the length
14143 operands[3] is the alignment */
14145 #define MAX_MOVE_REG 4
14148 expand_block_move (rtx operands
[])
14150 rtx orig_dest
= operands
[0];
14151 rtx orig_src
= operands
[1];
14152 rtx bytes_rtx
= operands
[2];
14153 rtx align_rtx
= operands
[3];
14154 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
14159 rtx stores
[MAX_MOVE_REG
];
14162 /* If this is not a fixed size move, just call memcpy */
14166 /* This must be a fixed size alignment */
14167 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
14168 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
14170 /* Anything to move? */
14171 bytes
= INTVAL (bytes_rtx
);
14175 if (bytes
> rs6000_block_move_inline_limit
)
14178 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
14181 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
14182 rtx (*mov
) (rtx
, rtx
);
14184 enum machine_mode mode
= BLKmode
;
14187 /* Altivec first, since it will be faster than a string move
14188 when it applies, and usually not significantly larger. */
14189 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
14193 gen_func
.mov
= gen_movv4si
;
14195 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
14199 gen_func
.mov
= gen_movv2si
;
14201 else if (TARGET_STRING
14202 && bytes
> 24 /* move up to 32 bytes at a time */
14208 && ! fixed_regs
[10]
14209 && ! fixed_regs
[11]
14210 && ! fixed_regs
[12])
14212 move_bytes
= (bytes
> 32) ? 32 : bytes
;
14213 gen_func
.movmemsi
= gen_movmemsi_8reg
;
14215 else if (TARGET_STRING
14216 && bytes
> 16 /* move up to 24 bytes at a time */
14222 && ! fixed_regs
[10])
14224 move_bytes
= (bytes
> 24) ? 24 : bytes
;
14225 gen_func
.movmemsi
= gen_movmemsi_6reg
;
14227 else if (TARGET_STRING
14228 && bytes
> 8 /* move up to 16 bytes at a time */
14232 && ! fixed_regs
[8])
14234 move_bytes
= (bytes
> 16) ? 16 : bytes
;
14235 gen_func
.movmemsi
= gen_movmemsi_4reg
;
14237 else if (bytes
>= 8 && TARGET_POWERPC64
14238 /* 64-bit loads and stores require word-aligned
14240 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
14244 gen_func
.mov
= gen_movdi
;
14246 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
14247 { /* move up to 8 bytes at a time */
14248 move_bytes
= (bytes
> 8) ? 8 : bytes
;
14249 gen_func
.movmemsi
= gen_movmemsi_2reg
;
14251 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
14252 { /* move 4 bytes */
14255 gen_func
.mov
= gen_movsi
;
14257 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
14258 { /* move 2 bytes */
14261 gen_func
.mov
= gen_movhi
;
14263 else if (TARGET_STRING
&& bytes
> 1)
14264 { /* move up to 4 bytes at a time */
14265 move_bytes
= (bytes
> 4) ? 4 : bytes
;
14266 gen_func
.movmemsi
= gen_movmemsi_1reg
;
14268 else /* move 1 byte at a time */
14272 gen_func
.mov
= gen_movqi
;
14275 src
= adjust_address (orig_src
, mode
, offset
);
14276 dest
= adjust_address (orig_dest
, mode
, offset
);
14278 if (mode
!= BLKmode
)
14280 rtx tmp_reg
= gen_reg_rtx (mode
);
14282 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
14283 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
14286 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
14289 for (i
= 0; i
< num_reg
; i
++)
14290 emit_insn (stores
[i
]);
14294 if (mode
== BLKmode
)
14296 /* Move the address into scratch registers. The movmemsi
14297 patterns require zero offset. */
14298 if (!REG_P (XEXP (src
, 0)))
14300 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
14301 src
= replace_equiv_address (src
, src_reg
);
14303 set_mem_size (src
, GEN_INT (move_bytes
));
14305 if (!REG_P (XEXP (dest
, 0)))
14307 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
14308 dest
= replace_equiv_address (dest
, dest_reg
);
14310 set_mem_size (dest
, GEN_INT (move_bytes
));
14312 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
14313 GEN_INT (move_bytes
& 31),
14322 /* Return a string to perform a load_multiple operation.
14323 operands[0] is the vector.
14324 operands[1] is the source address.
14325 operands[2] is the first destination register. */
14328 rs6000_output_load_multiple (rtx operands
[3])
14330 /* We have to handle the case where the pseudo used to contain the address
14331 is assigned to one of the output registers. */
14333 int words
= XVECLEN (operands
[0], 0);
14336 if (XVECLEN (operands
[0], 0) == 1)
14337 return "{l|lwz} %2,0(%1)";
14339 for (i
= 0; i
< words
; i
++)
14340 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
14341 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
14345 xop
[0] = GEN_INT (4 * (words
-1));
14346 xop
[1] = operands
[1];
14347 xop
[2] = operands
[2];
14348 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
14353 xop
[0] = GEN_INT (4 * (words
-1));
14354 xop
[1] = operands
[1];
14355 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
14356 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
);
14361 for (j
= 0; j
< words
; j
++)
14364 xop
[0] = GEN_INT (j
* 4);
14365 xop
[1] = operands
[1];
14366 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
14367 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
14369 xop
[0] = GEN_INT (i
* 4);
14370 xop
[1] = operands
[1];
14371 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
14376 return "{lsi|lswi} %2,%1,%N0";
14380 /* A validation routine: say whether CODE, a condition code, and MODE
14381 match. The other alternatives either don't make sense or should
14382 never be generated. */
14385 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
14387 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
14388 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
14389 && GET_MODE_CLASS (mode
) == MODE_CC
);
14391 /* These don't make sense. */
14392 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
14393 || mode
!= CCUNSmode
);
14395 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
14396 || mode
== CCUNSmode
);
14398 gcc_assert (mode
== CCFPmode
14399 || (code
!= ORDERED
&& code
!= UNORDERED
14400 && code
!= UNEQ
&& code
!= LTGT
14401 && code
!= UNGT
&& code
!= UNLT
14402 && code
!= UNGE
&& code
!= UNLE
));
14404 /* These should never be generated except for
14405 flag_finite_math_only. */
14406 gcc_assert (mode
!= CCFPmode
14407 || flag_finite_math_only
14408 || (code
!= LE
&& code
!= GE
14409 && code
!= UNEQ
&& code
!= LTGT
14410 && code
!= UNGT
&& code
!= UNLT
));
14412 /* These are invalid; the information is not there. */
14413 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
14417 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14418 mask required to convert the result of a rotate insn into a shift
14419 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14422 includes_lshift_p (rtx shiftop
, rtx andop
)
14424 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
14426 shift_mask
<<= INTVAL (shiftop
);
14428 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
14431 /* Similar, but for right shift. */
14434 includes_rshift_p (rtx shiftop
, rtx andop
)
14436 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
14438 shift_mask
>>= INTVAL (shiftop
);
14440 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
14443 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14444 to perform a left shift. It must have exactly SHIFTOP least
14445 significant 0's, then one or more 1's, then zero or more 0's. */
14448 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
14450 if (GET_CODE (andop
) == CONST_INT
)
14452 HOST_WIDE_INT c
, lsb
, shift_mask
;
14454 c
= INTVAL (andop
);
14455 if (c
== 0 || c
== ~0)
14459 shift_mask
<<= INTVAL (shiftop
);
14461 /* Find the least significant one bit. */
14464 /* It must coincide with the LSB of the shift mask. */
14465 if (-lsb
!= shift_mask
)
14468 /* Invert to look for the next transition (if any). */
14471 /* Remove the low group of ones (originally low group of zeros). */
14474 /* Again find the lsb, and check we have all 1's above. */
14478 else if (GET_CODE (andop
) == CONST_DOUBLE
14479 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
14481 HOST_WIDE_INT low
, high
, lsb
;
14482 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
14484 low
= CONST_DOUBLE_LOW (andop
);
14485 if (HOST_BITS_PER_WIDE_INT
< 64)
14486 high
= CONST_DOUBLE_HIGH (andop
);
14488 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
14489 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
14492 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
14494 shift_mask_high
= ~0;
14495 if (INTVAL (shiftop
) > 32)
14496 shift_mask_high
<<= INTVAL (shiftop
) - 32;
14498 lsb
= high
& -high
;
14500 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
14506 lsb
= high
& -high
;
14507 return high
== -lsb
;
14510 shift_mask_low
= ~0;
14511 shift_mask_low
<<= INTVAL (shiftop
);
14515 if (-lsb
!= shift_mask_low
)
14518 if (HOST_BITS_PER_WIDE_INT
< 64)
14523 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
14525 lsb
= high
& -high
;
14526 return high
== -lsb
;
14530 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
14536 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14537 to perform a left shift. It must have SHIFTOP or more least
14538 significant 0's, with the remainder of the word 1's. */
14541 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
14543 if (GET_CODE (andop
) == CONST_INT
)
14545 HOST_WIDE_INT c
, lsb
, shift_mask
;
14548 shift_mask
<<= INTVAL (shiftop
);
14549 c
= INTVAL (andop
);
14551 /* Find the least significant one bit. */
14554 /* It must be covered by the shift mask.
14555 This test also rejects c == 0. */
14556 if ((lsb
& shift_mask
) == 0)
14559 /* Check we have all 1's above the transition, and reject all 1's. */
14560 return c
== -lsb
&& lsb
!= 1;
14562 else if (GET_CODE (andop
) == CONST_DOUBLE
14563 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
14565 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
14567 low
= CONST_DOUBLE_LOW (andop
);
14569 if (HOST_BITS_PER_WIDE_INT
< 64)
14571 HOST_WIDE_INT high
, shift_mask_high
;
14573 high
= CONST_DOUBLE_HIGH (andop
);
14577 shift_mask_high
= ~0;
14578 if (INTVAL (shiftop
) > 32)
14579 shift_mask_high
<<= INTVAL (shiftop
) - 32;
14581 lsb
= high
& -high
;
14583 if ((lsb
& shift_mask_high
) == 0)
14586 return high
== -lsb
;
14592 shift_mask_low
= ~0;
14593 shift_mask_low
<<= INTVAL (shiftop
);
14597 if ((lsb
& shift_mask_low
) == 0)
14600 return low
== -lsb
&& lsb
!= 1;
14606 /* Return 1 if operands will generate a valid arguments to rlwimi
14607 instruction for insert with right shift in 64-bit mode. The mask may
14608 not start on the first bit or stop on the last bit because wrap-around
14609 effects of instruction do not correspond to semantics of RTL insn. */
14612 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
14614 if (INTVAL (startop
) > 32
14615 && INTVAL (startop
) < 64
14616 && INTVAL (sizeop
) > 1
14617 && INTVAL (sizeop
) + INTVAL (startop
) < 64
14618 && INTVAL (shiftop
) > 0
14619 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
14620 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
14626 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14627 for lfq and stfq insns iff the registers are hard registers. */
14630 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
14632 /* We might have been passed a SUBREG. */
14633 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
14636 /* We might have been passed non floating point registers. */
14637 if (!FP_REGNO_P (REGNO (reg1
))
14638 || !FP_REGNO_P (REGNO (reg2
)))
14641 return (REGNO (reg1
) == REGNO (reg2
) - 1);
14644 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14645 addr1 and addr2 must be in consecutive memory locations
14646 (addr2 == addr1 + 8). */
14649 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
14652 unsigned int reg1
, reg2
;
14653 int offset1
, offset2
;
14655 /* The mems cannot be volatile. */
14656 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
14659 addr1
= XEXP (mem1
, 0);
14660 addr2
= XEXP (mem2
, 0);
14662 /* Extract an offset (if used) from the first addr. */
14663 if (GET_CODE (addr1
) == PLUS
)
14665 /* If not a REG, return zero. */
14666 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
14670 reg1
= REGNO (XEXP (addr1
, 0));
14671 /* The offset must be constant! */
14672 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
14674 offset1
= INTVAL (XEXP (addr1
, 1));
14677 else if (GET_CODE (addr1
) != REG
)
14681 reg1
= REGNO (addr1
);
14682 /* This was a simple (mem (reg)) expression. Offset is 0. */
14686 /* And now for the second addr. */
14687 if (GET_CODE (addr2
) == PLUS
)
14689 /* If not a REG, return zero. */
14690 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
14694 reg2
= REGNO (XEXP (addr2
, 0));
14695 /* The offset must be constant. */
14696 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
14698 offset2
= INTVAL (XEXP (addr2
, 1));
14701 else if (GET_CODE (addr2
) != REG
)
14705 reg2
= REGNO (addr2
);
14706 /* This was a simple (mem (reg)) expression. Offset is 0. */
14710 /* Both of these must have the same base register. */
14714 /* The offset for the second addr must be 8 more than the first addr. */
14715 if (offset2
!= offset1
+ 8)
14718 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14725 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
14727 static bool eliminated
= false;
14730 if (mode
!= SDmode
)
14731 ret
= assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
14734 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
14735 gcc_assert (mem
!= NULL_RTX
);
14739 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
14740 cfun
->machine
->sdmode_stack_slot
= mem
;
14746 if (TARGET_DEBUG_ADDR
)
14748 fprintf (stderr
, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14749 GET_MODE_NAME (mode
));
14751 fprintf (stderr
, "\tNULL_RTX\n");
14760 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
14762 /* Don't walk into types. */
14763 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
14765 *walk_subtrees
= 0;
14769 switch (TREE_CODE (*tp
))
14778 case VIEW_CONVERT_EXPR
:
14779 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
14789 enum reload_reg_type
{
14791 VECTOR_REGISTER_TYPE
,
14792 OTHER_REGISTER_TYPE
14795 static enum reload_reg_type
14796 rs6000_reload_register_type (enum reg_class rclass
)
14802 return GPR_REGISTER_TYPE
;
14807 return VECTOR_REGISTER_TYPE
;
14810 return OTHER_REGISTER_TYPE
;
14814 /* Inform reload about cases where moving X with a mode MODE to a register in
14815 RCLASS requires an extra scratch or immediate register. Return the class
14816 needed for the immediate register.
14818 For VSX and Altivec, we may need a register to convert sp+offset into
14822 rs6000_secondary_reload (bool in_p
,
14824 reg_class_t rclass_i
,
14825 enum machine_mode mode
,
14826 secondary_reload_info
*sri
)
14828 enum reg_class rclass
= (enum reg_class
) rclass_i
;
14829 reg_class_t ret
= ALL_REGS
;
14830 enum insn_code icode
;
14831 bool default_p
= false;
14833 sri
->icode
= CODE_FOR_nothing
;
14835 /* Convert vector loads and stores into gprs to use an additional base
14837 icode
= rs6000_vector_reload
[mode
][in_p
!= false];
14838 if (icode
!= CODE_FOR_nothing
)
14841 sri
->icode
= CODE_FOR_nothing
;
14842 sri
->extra_cost
= 0;
14844 if (GET_CODE (x
) == MEM
)
14846 rtx addr
= XEXP (x
, 0);
14848 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14849 an extra register in that case, but it would need an extra
14850 register if the addressing is reg+reg or (reg+reg)&(-16). */
14851 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
)
14853 if (!legitimate_indirect_address_p (addr
, false)
14854 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14856 sri
->icode
= icode
;
14857 /* account for splitting the loads, and converting the
14858 address from reg+reg to reg. */
14859 sri
->extra_cost
= (((TARGET_64BIT
) ? 3 : 5)
14860 + ((GET_CODE (addr
) == AND
) ? 1 : 0));
14863 /* Loads to and stores from vector registers can only do reg+reg
14864 addressing. Altivec registers can also do (reg+reg)&(-16). */
14865 else if (rclass
== VSX_REGS
|| rclass
== ALTIVEC_REGS
14866 || rclass
== FLOAT_REGS
|| rclass
== NO_REGS
)
14868 if (!VECTOR_MEM_ALTIVEC_P (mode
)
14869 && GET_CODE (addr
) == AND
14870 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14871 && INTVAL (XEXP (addr
, 1)) == -16
14872 && (legitimate_indirect_address_p (XEXP (addr
, 0), false)
14873 || legitimate_indexed_address_p (XEXP (addr
, 0), false)))
14875 sri
->icode
= icode
;
14876 sri
->extra_cost
= ((GET_CODE (XEXP (addr
, 0)) == PLUS
)
14879 else if (!legitimate_indirect_address_p (addr
, false)
14880 && (rclass
== NO_REGS
14881 || !legitimate_indexed_address_p (addr
, false)))
14883 sri
->icode
= icode
;
14884 sri
->extra_cost
= 1;
14887 icode
= CODE_FOR_nothing
;
14889 /* Any other loads, including to pseudo registers which haven't been
14890 assigned to a register yet, default to require a scratch
14894 sri
->icode
= icode
;
14895 sri
->extra_cost
= 2;
14898 else if (REG_P (x
))
14900 int regno
= true_regnum (x
);
14902 icode
= CODE_FOR_nothing
;
14903 if (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
)
14907 enum reg_class xclass
= REGNO_REG_CLASS (regno
);
14908 enum reload_reg_type rtype1
= rs6000_reload_register_type (rclass
);
14909 enum reload_reg_type rtype2
= rs6000_reload_register_type (xclass
);
14911 /* If memory is needed, use default_secondary_reload to create the
14913 if (rtype1
!= rtype2
|| rtype1
== OTHER_REGISTER_TYPE
)
14926 ret
= default_secondary_reload (in_p
, x
, rclass
, mode
, sri
);
14928 gcc_assert (ret
!= ALL_REGS
);
14930 if (TARGET_DEBUG_ADDR
)
14933 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14935 reg_class_names
[ret
],
14936 in_p
? "true" : "false",
14937 reg_class_names
[rclass
],
14938 GET_MODE_NAME (mode
));
14941 fprintf (stderr
, ", default secondary reload");
14943 if (sri
->icode
!= CODE_FOR_nothing
)
14944 fprintf (stderr
, ", reload func = %s, extra cost = %d\n",
14945 insn_data
[sri
->icode
].name
, sri
->extra_cost
);
14947 fprintf (stderr
, "\n");
14955 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14956 to SP+reg addressing. */
14959 rs6000_secondary_reload_inner (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
14961 int regno
= true_regnum (reg
);
14962 enum machine_mode mode
= GET_MODE (reg
);
14963 enum reg_class rclass
;
14965 rtx and_op2
= NULL_RTX
;
14968 rtx scratch_or_premodify
= scratch
;
14972 if (TARGET_DEBUG_ADDR
)
14974 fprintf (stderr
, "\nrs6000_secondary_reload_inner, type = %s\n",
14975 store_p
? "store" : "load");
14976 fprintf (stderr
, "reg:\n");
14978 fprintf (stderr
, "mem:\n");
14980 fprintf (stderr
, "scratch:\n");
14981 debug_rtx (scratch
);
14984 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
14985 gcc_assert (GET_CODE (mem
) == MEM
);
14986 rclass
= REGNO_REG_CLASS (regno
);
14987 addr
= XEXP (mem
, 0);
14991 /* GPRs can handle reg + small constant, all other addresses need to use
14992 the scratch register. */
14995 if (GET_CODE (addr
) == AND
)
14997 and_op2
= XEXP (addr
, 1);
14998 addr
= XEXP (addr
, 0);
15001 if (GET_CODE (addr
) == PRE_MODIFY
)
15003 scratch_or_premodify
= XEXP (addr
, 0);
15004 gcc_assert (REG_P (scratch_or_premodify
));
15005 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
15006 addr
= XEXP (addr
, 1);
15009 if (GET_CODE (addr
) == PLUS
15010 && (!rs6000_legitimate_offset_address_p (TImode
, addr
, false)
15011 || and_op2
!= NULL_RTX
))
15013 addr_op1
= XEXP (addr
, 0);
15014 addr_op2
= XEXP (addr
, 1);
15015 gcc_assert (legitimate_indirect_address_p (addr_op1
, false));
15017 if (!REG_P (addr_op2
)
15018 && (GET_CODE (addr_op2
) != CONST_INT
15019 || !satisfies_constraint_I (addr_op2
)))
15021 if (TARGET_DEBUG_ADDR
)
15024 "\nMove plus addr to register %s, mode = %s: ",
15025 rs6000_reg_names
[REGNO (scratch
)],
15026 GET_MODE_NAME (mode
));
15027 debug_rtx (addr_op2
);
15029 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
15030 addr_op2
= scratch
;
15033 emit_insn (gen_rtx_SET (VOIDmode
,
15034 scratch_or_premodify
,
15035 gen_rtx_PLUS (Pmode
,
15039 addr
= scratch_or_premodify
;
15040 scratch_or_premodify
= scratch
;
15042 else if (!legitimate_indirect_address_p (addr
, false)
15043 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
15045 if (TARGET_DEBUG_ADDR
)
15047 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
15048 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
15049 GET_MODE_NAME (mode
));
15052 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
15053 addr
= scratch_or_premodify
;
15054 scratch_or_premodify
= scratch
;
15058 /* Float/Altivec registers can only handle reg+reg addressing. Move
15059 other addresses into a scratch register. */
15064 /* With float regs, we need to handle the AND ourselves, since we can't
15065 use the Altivec instruction with an implicit AND -16. Allow scalar
15066 loads to float registers to use reg+offset even if VSX. */
15067 if (GET_CODE (addr
) == AND
15068 && (rclass
!= ALTIVEC_REGS
|| GET_MODE_SIZE (mode
) != 16
15069 || GET_CODE (XEXP (addr
, 1)) != CONST_INT
15070 || INTVAL (XEXP (addr
, 1)) != -16
15071 || !VECTOR_MEM_ALTIVEC_P (mode
)))
15073 and_op2
= XEXP (addr
, 1);
15074 addr
= XEXP (addr
, 0);
15077 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15078 as the address later. */
15079 if (GET_CODE (addr
) == PRE_MODIFY
15080 && (!VECTOR_MEM_VSX_P (mode
)
15081 || and_op2
!= NULL_RTX
15082 || !legitimate_indexed_address_p (XEXP (addr
, 1), false)))
15084 scratch_or_premodify
= XEXP (addr
, 0);
15085 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify
,
15087 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
15088 addr
= XEXP (addr
, 1);
15091 if (legitimate_indirect_address_p (addr
, false) /* reg */
15092 || legitimate_indexed_address_p (addr
, false) /* reg+reg */
15093 || GET_CODE (addr
) == PRE_MODIFY
/* VSX pre-modify */
15094 || (GET_CODE (addr
) == AND
/* Altivec memory */
15095 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
15096 && INTVAL (XEXP (addr
, 1)) == -16
15097 && VECTOR_MEM_ALTIVEC_P (mode
))
15098 || (rclass
== FLOAT_REGS
/* legacy float mem */
15099 && GET_MODE_SIZE (mode
) == 8
15100 && and_op2
== NULL_RTX
15101 && scratch_or_premodify
== scratch
15102 && rs6000_legitimate_offset_address_p (mode
, addr
, false)))
15105 else if (GET_CODE (addr
) == PLUS
)
15107 addr_op1
= XEXP (addr
, 0);
15108 addr_op2
= XEXP (addr
, 1);
15109 gcc_assert (REG_P (addr_op1
));
15111 if (TARGET_DEBUG_ADDR
)
15113 fprintf (stderr
, "\nMove plus addr to register %s, mode = %s: ",
15114 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
15115 debug_rtx (addr_op2
);
15117 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
15118 emit_insn (gen_rtx_SET (VOIDmode
,
15119 scratch_or_premodify
,
15120 gen_rtx_PLUS (Pmode
,
15123 addr
= scratch_or_premodify
;
15124 scratch_or_premodify
= scratch
;
15127 else if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == CONST
15128 || GET_CODE (addr
) == CONST_INT
|| REG_P (addr
))
15130 if (TARGET_DEBUG_ADDR
)
15132 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
15133 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
15134 GET_MODE_NAME (mode
));
15138 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
15139 addr
= scratch_or_premodify
;
15140 scratch_or_premodify
= scratch
;
15144 gcc_unreachable ();
15149 gcc_unreachable ();
15152 /* If the original address involved a pre-modify that we couldn't use the VSX
15153 memory instruction with update, and we haven't taken care of already,
15154 store the address in the pre-modify register and use that as the
15156 if (scratch_or_premodify
!= scratch
&& scratch_or_premodify
!= addr
)
15158 emit_insn (gen_rtx_SET (VOIDmode
, scratch_or_premodify
, addr
));
15159 addr
= scratch_or_premodify
;
15162 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15163 memory instruction, recreate the AND now, including the clobber which is
15164 generated by the general ANDSI3/ANDDI3 patterns for the
15165 andi. instruction. */
15166 if (and_op2
!= NULL_RTX
)
15168 if (! legitimate_indirect_address_p (addr
, false))
15170 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, addr
));
15174 if (TARGET_DEBUG_ADDR
)
15176 fprintf (stderr
, "\nAnd addr to register %s, mode = %s: ",
15177 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
15178 debug_rtx (and_op2
);
15181 and_rtx
= gen_rtx_SET (VOIDmode
,
15183 gen_rtx_AND (Pmode
,
15187 cc_clobber
= gen_rtx_CLOBBER (CCmode
, gen_rtx_SCRATCH (CCmode
));
15188 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
15189 gen_rtvec (2, and_rtx
, cc_clobber
)));
15193 /* Adjust the address if it changed. */
15194 if (addr
!= XEXP (mem
, 0))
15196 mem
= change_address (mem
, mode
, addr
);
15197 if (TARGET_DEBUG_ADDR
)
15198 fprintf (stderr
, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15201 /* Now create the move. */
15203 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
15205 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
15210 /* Target hook to return the cover classes for Integrated Register Allocator.
15211 Cover classes is a set of non-intersected register classes covering all hard
15212 registers used for register allocation purpose. Any move between two
15213 registers of a cover class should be cheaper than load or store of the
15214 registers. The value is array of register classes with LIM_REG_CLASSES used
15217 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
15218 account for the Altivec and Floating registers being subsets of the VSX
15219 register set under VSX, but distinct register sets on pre-VSX machines. */
15221 static const reg_class_t
*
15222 rs6000_ira_cover_classes (void)
15224 static const reg_class_t cover_pre_vsx
[] = IRA_COVER_CLASSES_PRE_VSX
;
15225 static const reg_class_t cover_vsx
[] = IRA_COVER_CLASSES_VSX
;
15227 return (TARGET_VSX
) ? cover_vsx
: cover_pre_vsx
;
15230 /* Allocate a 64-bit stack slot to be used for copying SDmode
15231 values through if this function has any SDmode references. */
15234 rs6000_alloc_sdmode_stack_slot (void)
15238 gimple_stmt_iterator gsi
;
15240 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
15243 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
15245 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
15248 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
15249 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
15255 /* Check for any SDmode parameters of the function. */
15256 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= DECL_CHAIN (t
))
15258 if (TREE_TYPE (t
) == error_mark_node
)
15261 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
15262 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
15264 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
15265 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
15273 rs6000_instantiate_decls (void)
15275 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
15276 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
15279 /* Given an rtx X being reloaded into a reg required to be
15280 in class CLASS, return the class of reg to actually use.
15281 In general this is just CLASS; but on some machines
15282 in some cases it is preferable to use a more restrictive class.
15284 On the RS/6000, we have to return NO_REGS when we want to reload a
15285 floating-point CONST_DOUBLE to force it to be copied to memory.
15287 We also don't want to reload integer values into floating-point
15288 registers if we can at all help it. In fact, this can
15289 cause reload to die, if it tries to generate a reload of CTR
15290 into a FP register and discovers it doesn't have the memory location
15293 ??? Would it be a good idea to have reload do the converse, that is
15294 try to reload floating modes into FP registers if possible?
15297 static enum reg_class
15298 rs6000_preferred_reload_class (rtx x
, enum reg_class rclass
)
15300 enum machine_mode mode
= GET_MODE (x
);
15302 if (VECTOR_UNIT_VSX_P (mode
)
15303 && x
== CONST0_RTX (mode
) && VSX_REG_CLASS_P (rclass
))
15306 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
15307 && (rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
15308 && easy_vector_constant (x
, mode
))
15309 return ALTIVEC_REGS
;
15311 if (CONSTANT_P (x
) && reg_classes_intersect_p (rclass
, FLOAT_REGS
))
15314 if (GET_MODE_CLASS (mode
) == MODE_INT
&& rclass
== NON_SPECIAL_REGS
)
15315 return GENERAL_REGS
;
15317 /* For VSX, prefer the traditional registers for 64-bit values because we can
15318 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15319 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15320 prefer Altivec loads.. */
15321 if (rclass
== VSX_REGS
)
15323 if (GET_MODE_SIZE (mode
) <= 8)
15326 if (VECTOR_UNIT_ALTIVEC_P (mode
) || VECTOR_MEM_ALTIVEC_P (mode
))
15327 return ALTIVEC_REGS
;
15335 /* Debug version of rs6000_preferred_reload_class. */
15336 static enum reg_class
15337 rs6000_debug_preferred_reload_class (rtx x
, enum reg_class rclass
)
15339 enum reg_class ret
= rs6000_preferred_reload_class (x
, rclass
);
15342 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15344 reg_class_names
[ret
], reg_class_names
[rclass
],
15345 GET_MODE_NAME (GET_MODE (x
)));
15351 /* If we are copying between FP or AltiVec registers and anything else, we need
15352 a memory location. The exception is when we are targeting ppc64 and the
15353 move to/from fpr to gpr instructions are available. Also, under VSX, you
15354 can copy vector registers from the FP register set to the Altivec register
15355 set and vice versa. */
15358 rs6000_secondary_memory_needed (enum reg_class class1
,
15359 enum reg_class class2
,
15360 enum machine_mode mode
)
15362 if (class1
== class2
)
15365 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15366 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15367 between these classes. But we need memory for other things that can go in
15368 FLOAT_REGS like SFmode. */
15370 && (VECTOR_MEM_VSX_P (mode
) || VECTOR_UNIT_VSX_P (mode
))
15371 && (class1
== VSX_REGS
|| class1
== ALTIVEC_REGS
15372 || class1
== FLOAT_REGS
))
15373 return (class2
!= VSX_REGS
&& class2
!= ALTIVEC_REGS
15374 && class2
!= FLOAT_REGS
);
15376 if (class1
== VSX_REGS
|| class2
== VSX_REGS
)
15379 if (class1
== FLOAT_REGS
15380 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
15381 || ((mode
!= DFmode
)
15382 && (mode
!= DDmode
)
15383 && (mode
!= DImode
))))
15386 if (class2
== FLOAT_REGS
15387 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
15388 || ((mode
!= DFmode
)
15389 && (mode
!= DDmode
)
15390 && (mode
!= DImode
))))
15393 if (class1
== ALTIVEC_REGS
|| class2
== ALTIVEC_REGS
)
15399 /* Debug version of rs6000_secondary_memory_needed. */
15401 rs6000_debug_secondary_memory_needed (enum reg_class class1
,
15402 enum reg_class class2
,
15403 enum machine_mode mode
)
15405 bool ret
= rs6000_secondary_memory_needed (class1
, class2
, mode
);
15408 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15409 "class2 = %s, mode = %s\n",
15410 ret
? "true" : "false", reg_class_names
[class1
],
15411 reg_class_names
[class2
], GET_MODE_NAME (mode
));
15416 /* Return the register class of a scratch register needed to copy IN into
15417 or out of a register in RCLASS in MODE. If it can be done directly,
15418 NO_REGS is returned. */
15420 static enum reg_class
15421 rs6000_secondary_reload_class (enum reg_class rclass
, enum machine_mode mode
,
15426 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
15428 && MACHOPIC_INDIRECT
15432 /* We cannot copy a symbolic operand directly into anything
15433 other than BASE_REGS for TARGET_ELF. So indicate that a
15434 register from BASE_REGS is needed as an intermediate
15437 On Darwin, pic addresses require a load from memory, which
15438 needs a base register. */
15439 if (rclass
!= BASE_REGS
15440 && (GET_CODE (in
) == SYMBOL_REF
15441 || GET_CODE (in
) == HIGH
15442 || GET_CODE (in
) == LABEL_REF
15443 || GET_CODE (in
) == CONST
))
15447 if (GET_CODE (in
) == REG
)
15449 regno
= REGNO (in
);
15450 if (regno
>= FIRST_PSEUDO_REGISTER
)
15452 regno
= true_regnum (in
);
15453 if (regno
>= FIRST_PSEUDO_REGISTER
)
15457 else if (GET_CODE (in
) == SUBREG
)
15459 regno
= true_regnum (in
);
15460 if (regno
>= FIRST_PSEUDO_REGISTER
)
15466 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15468 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
15469 || (regno
>= 0 && INT_REGNO_P (regno
)))
15472 /* Constants, memory, and FP registers can go into FP registers. */
15473 if ((regno
== -1 || FP_REGNO_P (regno
))
15474 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
15475 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
15477 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15480 && (regno
== -1 || VSX_REGNO_P (regno
))
15481 && VSX_REG_CLASS_P (rclass
))
15484 /* Memory, and AltiVec registers can go into AltiVec registers. */
15485 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
15486 && rclass
== ALTIVEC_REGS
)
15489 /* We can copy among the CR registers. */
15490 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
15491 && regno
>= 0 && CR_REGNO_P (regno
))
15494 /* Otherwise, we need GENERAL_REGS. */
15495 return GENERAL_REGS
;
15498 /* Debug version of rs6000_secondary_reload_class. */
15499 static enum reg_class
15500 rs6000_debug_secondary_reload_class (enum reg_class rclass
,
15501 enum machine_mode mode
, rtx in
)
15503 enum reg_class ret
= rs6000_secondary_reload_class (rclass
, mode
, in
);
15505 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15506 "mode = %s, input rtx:\n",
15507 reg_class_names
[ret
], reg_class_names
[rclass
],
15508 GET_MODE_NAME (mode
));
15514 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15517 rs6000_cannot_change_mode_class (enum machine_mode from
,
15518 enum machine_mode to
,
15519 enum reg_class rclass
)
15521 unsigned from_size
= GET_MODE_SIZE (from
);
15522 unsigned to_size
= GET_MODE_SIZE (to
);
15524 if (from_size
!= to_size
)
15526 enum reg_class xclass
= (TARGET_VSX
) ? VSX_REGS
: FLOAT_REGS
;
15527 return ((from_size
< 8 || to_size
< 8 || TARGET_IEEEQUAD
)
15528 && reg_classes_intersect_p (xclass
, rclass
));
15531 if (TARGET_E500_DOUBLE
15532 && ((((to
) == DFmode
) + ((from
) == DFmode
)) == 1
15533 || (((to
) == TFmode
) + ((from
) == TFmode
)) == 1
15534 || (((to
) == DDmode
) + ((from
) == DDmode
)) == 1
15535 || (((to
) == TDmode
) + ((from
) == TDmode
)) == 1
15536 || (((to
) == DImode
) + ((from
) == DImode
)) == 1))
15539 /* Since the VSX register set includes traditional floating point registers
15540 and altivec registers, just check for the size being different instead of
15541 trying to check whether the modes are vector modes. Otherwise it won't
15542 allow say DF and DI to change classes. */
15543 if (TARGET_VSX
&& VSX_REG_CLASS_P (rclass
))
15544 return (from_size
!= 8 && from_size
!= 16);
15546 if (TARGET_ALTIVEC
&& rclass
== ALTIVEC_REGS
15547 && (ALTIVEC_VECTOR_MODE (from
) + ALTIVEC_VECTOR_MODE (to
)) == 1)
15550 if (TARGET_SPE
&& (SPE_VECTOR_MODE (from
) + SPE_VECTOR_MODE (to
)) == 1
15551 && reg_classes_intersect_p (GENERAL_REGS
, rclass
))
15557 /* Debug version of rs6000_cannot_change_mode_class. */
15559 rs6000_debug_cannot_change_mode_class (enum machine_mode from
,
15560 enum machine_mode to
,
15561 enum reg_class rclass
)
15563 bool ret
= rs6000_cannot_change_mode_class (from
, to
, rclass
);
15566 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15567 "to = %s, rclass = %s\n",
15568 ret
? "true" : "false",
15569 GET_MODE_NAME (from
), GET_MODE_NAME (to
),
15570 reg_class_names
[rclass
]);
15575 /* Given a comparison operation, return the bit number in CCR to test. We
15576 know this is a valid comparison.
15578 SCC_P is 1 if this is for an scc. That means that %D will have been
15579 used instead of %C, so the bits will be in different places.
15581 Return -1 if OP isn't a valid comparison for some reason. */
15584 ccr_bit (rtx op
, int scc_p
)
15586 enum rtx_code code
= GET_CODE (op
);
15587 enum machine_mode cc_mode
;
15592 if (!COMPARISON_P (op
))
15595 reg
= XEXP (op
, 0);
15597 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
15599 cc_mode
= GET_MODE (reg
);
15600 cc_regnum
= REGNO (reg
);
15601 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
15603 validate_condition_mode (code
, cc_mode
);
15605 /* When generating a sCOND operation, only positive conditions are
15608 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
15609 || code
== GTU
|| code
== LTU
);
15614 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
15616 return base_bit
+ 2;
15617 case GT
: case GTU
: case UNLE
:
15618 return base_bit
+ 1;
15619 case LT
: case LTU
: case UNGE
:
15621 case ORDERED
: case UNORDERED
:
15622 return base_bit
+ 3;
15625 /* If scc, we will have done a cror to put the bit in the
15626 unordered position. So test that bit. For integer, this is ! LT
15627 unless this is an scc insn. */
15628 return scc_p
? base_bit
+ 3 : base_bit
;
15631 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
15634 gcc_unreachable ();
15638 /* Return the GOT register. */
15641 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
15643 /* The second flow pass currently (June 1999) can't update
15644 regs_ever_live without disturbing other parts of the compiler, so
15645 update it here to make the prolog/epilogue code happy. */
15646 if (!can_create_pseudo_p ()
15647 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
15648 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
15650 crtl
->uses_pic_offset_table
= 1;
15652 return pic_offset_table_rtx
;
15655 static rs6000_stack_t stack_info
;
15657 /* Function to init struct machine_function.
15658 This will be called, via a pointer variable,
15659 from push_function_context. */
15661 static struct machine_function
*
15662 rs6000_init_machine_status (void)
15664 stack_info
.reload_completed
= 0;
15665 return ggc_alloc_cleared_machine_function ();
15668 /* These macros test for integers and extract the low-order bits. */
15670 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15671 && GET_MODE (X) == VOIDmode)
15673 #define INT_LOWPART(X) \
15674 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15677 extract_MB (rtx op
)
15680 unsigned long val
= INT_LOWPART (op
);
15682 /* If the high bit is zero, the value is the first 1 bit we find
15684 if ((val
& 0x80000000) == 0)
15686 gcc_assert (val
& 0xffffffff);
15689 while (((val
<<= 1) & 0x80000000) == 0)
15694 /* If the high bit is set and the low bit is not, or the mask is all
15695 1's, the value is zero. */
15696 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
15699 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15702 while (((val
>>= 1) & 1) != 0)
15709 extract_ME (rtx op
)
15712 unsigned long val
= INT_LOWPART (op
);
15714 /* If the low bit is zero, the value is the first 1 bit we find from
15716 if ((val
& 1) == 0)
15718 gcc_assert (val
& 0xffffffff);
15721 while (((val
>>= 1) & 1) == 0)
15727 /* If the low bit is set and the high bit is not, or the mask is all
15728 1's, the value is 31. */
15729 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
15732 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15735 while (((val
<<= 1) & 0x80000000) != 0)
15741 /* Locate some local-dynamic symbol still in use by this function
15742 so that we can print its name in some tls_ld pattern. */
15744 static const char *
15745 rs6000_get_some_local_dynamic_name (void)
15749 if (cfun
->machine
->some_ld_name
)
15750 return cfun
->machine
->some_ld_name
;
15752 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15754 && for_each_rtx (&PATTERN (insn
),
15755 rs6000_get_some_local_dynamic_name_1
, 0))
15756 return cfun
->machine
->some_ld_name
;
15758 gcc_unreachable ();
15761 /* Helper function for rs6000_get_some_local_dynamic_name. */
15764 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
15768 if (GET_CODE (x
) == SYMBOL_REF
)
15770 const char *str
= XSTR (x
, 0);
15771 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
15773 cfun
->machine
->some_ld_name
= str
;
15781 /* Write out a function code label. */
15784 rs6000_output_function_entry (FILE *file
, const char *fname
)
15786 if (fname
[0] != '.')
15788 switch (DEFAULT_ABI
)
15791 gcc_unreachable ();
15797 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
15806 RS6000_OUTPUT_BASENAME (file
, fname
);
15809 /* Print an operand. Recognize special options, documented below. */
15812 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15813 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15815 #define SMALL_DATA_RELOC "sda21"
15816 #define SMALL_DATA_REG 0
15820 print_operand (FILE *file
, rtx x
, int code
)
15824 unsigned HOST_WIDE_INT uval
;
15829 /* Write out an instruction after the call which may be replaced
15830 with glue code by the loader. This depends on the AIX version. */
15831 asm_fprintf (file
, RS6000_CALL_GLUE
);
15834 /* %a is output_address. */
15837 /* If X is a constant integer whose low-order 5 bits are zero,
15838 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15839 in the AIX assembler where "sri" with a zero shift count
15840 writes a trash instruction. */
15841 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
15848 /* If constant, low-order 16 bits of constant, unsigned.
15849 Otherwise, write normally. */
15851 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
15853 print_operand (file
, x
, 0);
15857 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15858 for 64-bit mask direction. */
15859 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
15862 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15866 /* X is a CR register. Print the number of the GT bit of the CR. */
15867 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15868 output_operand_lossage ("invalid %%c value");
15870 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
15874 /* Like 'J' but get to the GT bit only. */
15875 gcc_assert (GET_CODE (x
) == REG
);
15877 /* Bit 1 is GT bit. */
15878 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
15880 /* Add one for shift count in rlinm for scc. */
15881 fprintf (file
, "%d", i
+ 1);
15885 /* X is a CR register. Print the number of the EQ bit of the CR */
15886 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15887 output_operand_lossage ("invalid %%E value");
15889 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
15893 /* X is a CR register. Print the shift count needed to move it
15894 to the high-order four bits. */
15895 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15896 output_operand_lossage ("invalid %%f value");
15898 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
15902 /* Similar, but print the count for the rotate in the opposite
15904 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15905 output_operand_lossage ("invalid %%F value");
15907 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
15911 /* X is a constant integer. If it is negative, print "m",
15912 otherwise print "z". This is to make an aze or ame insn. */
15913 if (GET_CODE (x
) != CONST_INT
)
15914 output_operand_lossage ("invalid %%G value");
15915 else if (INTVAL (x
) >= 0)
15922 /* If constant, output low-order five bits. Otherwise, write
15925 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
15927 print_operand (file
, x
, 0);
15931 /* If constant, output low-order six bits. Otherwise, write
15934 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
15936 print_operand (file
, x
, 0);
15940 /* Print `i' if this is a constant, else nothing. */
15946 /* Write the bit number in CCR for jump. */
15947 i
= ccr_bit (x
, 0);
15949 output_operand_lossage ("invalid %%j code");
15951 fprintf (file
, "%d", i
);
15955 /* Similar, but add one for shift count in rlinm for scc and pass
15956 scc flag to `ccr_bit'. */
15957 i
= ccr_bit (x
, 1);
15959 output_operand_lossage ("invalid %%J code");
15961 /* If we want bit 31, write a shift count of zero, not 32. */
15962 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15966 /* X must be a constant. Write the 1's complement of the
15969 output_operand_lossage ("invalid %%k value");
15971 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
15975 /* X must be a symbolic constant on ELF. Write an
15976 expression suitable for an 'addi' that adds in the low 16
15977 bits of the MEM. */
15978 if (GET_CODE (x
) == CONST
)
15980 if (GET_CODE (XEXP (x
, 0)) != PLUS
15981 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
15982 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
15983 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
15984 output_operand_lossage ("invalid %%K value");
15986 print_operand_address (file
, x
);
15987 fputs ("@l", file
);
15990 /* %l is output_asm_label. */
15993 /* Write second word of DImode or DFmode reference. Works on register
15994 or non-indexed memory only. */
15995 if (GET_CODE (x
) == REG
)
15996 fputs (reg_names
[REGNO (x
) + 1], file
);
15997 else if (GET_CODE (x
) == MEM
)
15999 /* Handle possible auto-increment. Since it is pre-increment and
16000 we have already done it, we can just use an offset of word. */
16001 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16002 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16003 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
16005 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16006 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
16009 output_address (XEXP (adjust_address_nv (x
, SImode
,
16013 if (small_data_operand (x
, GET_MODE (x
)))
16014 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16015 reg_names
[SMALL_DATA_REG
]);
16020 /* MB value for a mask operand. */
16021 if (! mask_operand (x
, SImode
))
16022 output_operand_lossage ("invalid %%m value");
16024 fprintf (file
, "%d", extract_MB (x
));
16028 /* ME value for a mask operand. */
16029 if (! mask_operand (x
, SImode
))
16030 output_operand_lossage ("invalid %%M value");
16032 fprintf (file
, "%d", extract_ME (x
));
16035 /* %n outputs the negative of its operand. */
16038 /* Write the number of elements in the vector times 4. */
16039 if (GET_CODE (x
) != PARALLEL
)
16040 output_operand_lossage ("invalid %%N value");
16042 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
16046 /* Similar, but subtract 1 first. */
16047 if (GET_CODE (x
) != PARALLEL
)
16048 output_operand_lossage ("invalid %%O value");
16050 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
16054 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16056 || INT_LOWPART (x
) < 0
16057 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
16058 output_operand_lossage ("invalid %%p value");
16060 fprintf (file
, "%d", i
);
16064 /* The operand must be an indirect memory reference. The result
16065 is the register name. */
16066 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
16067 || REGNO (XEXP (x
, 0)) >= 32)
16068 output_operand_lossage ("invalid %%P value");
16070 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
16074 /* This outputs the logical code corresponding to a boolean
16075 expression. The expression may have one or both operands
16076 negated (if one, only the first one). For condition register
16077 logical operations, it will also treat the negated
16078 CR codes as NOTs, but not handle NOTs of them. */
16080 const char *const *t
= 0;
16082 enum rtx_code code
= GET_CODE (x
);
16083 static const char * const tbl
[3][3] = {
16084 { "and", "andc", "nor" },
16085 { "or", "orc", "nand" },
16086 { "xor", "eqv", "xor" } };
16090 else if (code
== IOR
)
16092 else if (code
== XOR
)
16095 output_operand_lossage ("invalid %%q value");
16097 if (GET_CODE (XEXP (x
, 0)) != NOT
)
16101 if (GET_CODE (XEXP (x
, 1)) == NOT
)
16119 /* X is a CR register. Print the mask for `mtcrf'. */
16120 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
16121 output_operand_lossage ("invalid %%R value");
16123 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
16127 /* Low 5 bits of 32 - value */
16129 output_operand_lossage ("invalid %%s value");
16131 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
16135 /* PowerPC64 mask position. All 0's is excluded.
16136 CONST_INT 32-bit mask is considered sign-extended so any
16137 transition must occur within the CONST_INT, not on the boundary. */
16138 if (! mask64_operand (x
, DImode
))
16139 output_operand_lossage ("invalid %%S value");
16141 uval
= INT_LOWPART (x
);
16143 if (uval
& 1) /* Clear Left */
16145 #if HOST_BITS_PER_WIDE_INT > 64
16146 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
16150 else /* Clear Right */
16153 #if HOST_BITS_PER_WIDE_INT > 64
16154 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
16160 gcc_assert (i
>= 0);
16161 fprintf (file
, "%d", i
);
16165 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16166 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
16168 /* Bit 3 is OV bit. */
16169 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
16171 /* If we want bit 31, write a shift count of zero, not 32. */
16172 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
16176 /* Print the symbolic name of a branch target register. */
16177 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
16178 && REGNO (x
) != CTR_REGNO
))
16179 output_operand_lossage ("invalid %%T value");
16180 else if (REGNO (x
) == LR_REGNO
)
16181 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
16183 fputs ("ctr", file
);
16187 /* High-order 16 bits of constant for use in unsigned operand. */
16189 output_operand_lossage ("invalid %%u value");
16191 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
16192 (INT_LOWPART (x
) >> 16) & 0xffff);
16196 /* High-order 16 bits of constant for use in signed operand. */
16198 output_operand_lossage ("invalid %%v value");
16200 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
16201 (INT_LOWPART (x
) >> 16) & 0xffff);
16205 /* Print `u' if this has an auto-increment or auto-decrement. */
16206 if (GET_CODE (x
) == MEM
16207 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
16208 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
16209 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
16214 /* Print the trap code for this operand. */
16215 switch (GET_CODE (x
))
16218 fputs ("eq", file
); /* 4 */
16221 fputs ("ne", file
); /* 24 */
16224 fputs ("lt", file
); /* 16 */
16227 fputs ("le", file
); /* 20 */
16230 fputs ("gt", file
); /* 8 */
16233 fputs ("ge", file
); /* 12 */
16236 fputs ("llt", file
); /* 2 */
16239 fputs ("lle", file
); /* 6 */
16242 fputs ("lgt", file
); /* 1 */
16245 fputs ("lge", file
); /* 5 */
16248 gcc_unreachable ();
16253 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16256 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
16257 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
16259 print_operand (file
, x
, 0);
16263 /* MB value for a PowerPC64 rldic operand. */
16264 val
= (GET_CODE (x
) == CONST_INT
16265 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
16270 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
16271 if ((val
<<= 1) < 0)
16274 #if HOST_BITS_PER_WIDE_INT == 32
16275 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
16276 i
+= 32; /* zero-extend high-part was all 0's */
16277 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
16279 val
= CONST_DOUBLE_LOW (x
);
16285 for ( ; i
< 64; i
++)
16286 if ((val
<<= 1) < 0)
16291 fprintf (file
, "%d", i
+ 1);
16295 /* X is a FPR or Altivec register used in a VSX context. */
16296 if (GET_CODE (x
) != REG
|| !VSX_REGNO_P (REGNO (x
)))
16297 output_operand_lossage ("invalid %%x value");
16300 int reg
= REGNO (x
);
16301 int vsx_reg
= (FP_REGNO_P (reg
)
16303 : reg
- FIRST_ALTIVEC_REGNO
+ 32);
16305 #ifdef TARGET_REGNAMES
16306 if (TARGET_REGNAMES
)
16307 fprintf (file
, "%%vs%d", vsx_reg
);
16310 fprintf (file
, "%d", vsx_reg
);
16315 if (GET_CODE (x
) == MEM
16316 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
16317 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
16318 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
16323 /* Like 'L', for third word of TImode */
16324 if (GET_CODE (x
) == REG
)
16325 fputs (reg_names
[REGNO (x
) + 2], file
);
16326 else if (GET_CODE (x
) == MEM
)
16328 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16329 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16330 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
16331 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16332 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
16334 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
16335 if (small_data_operand (x
, GET_MODE (x
)))
16336 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16337 reg_names
[SMALL_DATA_REG
]);
16342 /* X is a SYMBOL_REF. Write out the name preceded by a
16343 period and without any trailing data in brackets. Used for function
16344 names. If we are configured for System V (or the embedded ABI) on
16345 the PowerPC, do not emit the period, since those systems do not use
16346 TOCs and the like. */
16347 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
16349 /* Mark the decl as referenced so that cgraph will output the
16351 if (SYMBOL_REF_DECL (x
))
16352 mark_decl_referenced (SYMBOL_REF_DECL (x
));
16354 /* For macho, check to see if we need a stub. */
16357 const char *name
= XSTR (x
, 0);
16359 if (darwin_emit_branch_islands
16360 && MACHOPIC_INDIRECT
16361 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
16362 name
= machopic_indirection_name (x
, /*stub_p=*/true);
16364 assemble_name (file
, name
);
16366 else if (!DOT_SYMBOLS
)
16367 assemble_name (file
, XSTR (x
, 0));
16369 rs6000_output_function_entry (file
, XSTR (x
, 0));
16373 /* Like 'L', for last word of TImode. */
16374 if (GET_CODE (x
) == REG
)
16375 fputs (reg_names
[REGNO (x
) + 3], file
);
16376 else if (GET_CODE (x
) == MEM
)
16378 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16379 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16380 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
16381 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16382 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
16384 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
16385 if (small_data_operand (x
, GET_MODE (x
)))
16386 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16387 reg_names
[SMALL_DATA_REG
]);
16391 /* Print AltiVec or SPE memory operand. */
16396 gcc_assert (GET_CODE (x
) == MEM
);
16400 /* Ugly hack because %y is overloaded. */
16401 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
16402 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
16403 || GET_MODE (x
) == TFmode
16404 || GET_MODE (x
) == TImode
))
16406 /* Handle [reg]. */
16407 if (GET_CODE (tmp
) == REG
)
16409 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
16412 /* Handle [reg+UIMM]. */
16413 else if (GET_CODE (tmp
) == PLUS
&&
16414 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
16418 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
16420 x
= INTVAL (XEXP (tmp
, 1));
16421 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
16425 /* Fall through. Must be [reg+reg]. */
16427 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x
))
16428 && GET_CODE (tmp
) == AND
16429 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
16430 && INTVAL (XEXP (tmp
, 1)) == -16)
16431 tmp
= XEXP (tmp
, 0);
16432 else if (VECTOR_MEM_VSX_P (GET_MODE (x
))
16433 && GET_CODE (tmp
) == PRE_MODIFY
)
16434 tmp
= XEXP (tmp
, 1);
16435 if (GET_CODE (tmp
) == REG
)
16436 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
16439 if (!GET_CODE (tmp
) == PLUS
16440 || !REG_P (XEXP (tmp
, 0))
16441 || !REG_P (XEXP (tmp
, 1)))
16443 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16447 if (REGNO (XEXP (tmp
, 0)) == 0)
16448 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
16449 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
16451 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
16452 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
16458 if (GET_CODE (x
) == REG
)
16459 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
16460 else if (GET_CODE (x
) == MEM
)
16462 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16463 know the width from the mode. */
16464 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
16465 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
16466 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
16467 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16468 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
16469 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
16470 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16471 output_address (XEXP (XEXP (x
, 0), 1));
16473 output_address (XEXP (x
, 0));
16477 if (toc_relative_expr_p (x
))
16478 /* This hack along with a corresponding hack in
16479 rs6000_output_addr_const_extra arranges to output addends
16480 where the assembler expects to find them. eg.
16481 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16482 without this hack would be output as "x@toc+4". We
16484 output_addr_const (file
, tocrel_base
);
16486 output_addr_const (file
, x
);
16491 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
16495 output_operand_lossage ("invalid %%xn code");
16499 /* Print the address of an operand. */
16502 print_operand_address (FILE *file
, rtx x
)
16504 if (GET_CODE (x
) == REG
)
16505 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
16506 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
16507 || GET_CODE (x
) == LABEL_REF
)
16509 output_addr_const (file
, x
);
16510 if (small_data_operand (x
, GET_MODE (x
)))
16511 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16512 reg_names
[SMALL_DATA_REG
]);
16514 gcc_assert (!TARGET_TOC
);
16516 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
16518 gcc_assert (REG_P (XEXP (x
, 0)));
16519 if (REGNO (XEXP (x
, 0)) == 0)
16520 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
16521 reg_names
[ REGNO (XEXP (x
, 0)) ]);
16523 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
16524 reg_names
[ REGNO (XEXP (x
, 1)) ]);
16526 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
16527 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
16528 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
16530 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16531 && CONSTANT_P (XEXP (x
, 1)))
16533 fprintf (file
, "lo16(");
16534 output_addr_const (file
, XEXP (x
, 1));
16535 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16538 else if (legitimate_constant_pool_address_p (x
, QImode
, true))
16540 /* This hack along with a corresponding hack in
16541 rs6000_output_addr_const_extra arranges to output addends
16542 where the assembler expects to find them. eg.
16544 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16545 without this hack would be output as "x@toc+8@l(9)". We
16546 want "x+8@toc@l(9)". */
16547 output_addr_const (file
, tocrel_base
);
16548 if (GET_CODE (x
) == LO_SUM
)
16549 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16551 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
16554 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16555 && CONSTANT_P (XEXP (x
, 1)))
16557 output_addr_const (file
, XEXP (x
, 1));
16558 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16562 gcc_unreachable ();
16565 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16568 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
16570 if (GET_CODE (x
) == UNSPEC
)
16571 switch (XINT (x
, 1))
16573 case UNSPEC_TOCREL
:
16574 gcc_assert (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
);
16575 output_addr_const (file
, XVECEXP (x
, 0, 0));
16576 if (x
== tocrel_base
&& tocrel_offset
!= const0_rtx
)
16578 if (INTVAL (tocrel_offset
) >= 0)
16579 fprintf (file
, "+");
16580 output_addr_const (file
, tocrel_offset
);
16582 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
16585 assemble_name (file
, toc_label_name
);
16587 else if (TARGET_ELF
)
16588 fputs ("@toc", file
);
16592 case UNSPEC_MACHOPIC_OFFSET
:
16593 output_addr_const (file
, XVECEXP (x
, 0, 0));
16595 machopic_output_function_base_name (file
);
16602 /* Target hook for assembling integer objects. The PowerPC version has
16603 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16604 is defined. It also needs to handle DI-mode objects on 64-bit
16608 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
16610 #ifdef RELOCATABLE_NEEDS_FIXUP
16611 /* Special handling for SI values. */
16612 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
16614 static int recurse
= 0;
16616 /* For -mrelocatable, we mark all addresses that need to be fixed up
16617 in the .fixup section. */
16618 if (TARGET_RELOCATABLE
16619 && in_section
!= toc_section
16620 && in_section
!= text_section
16621 && !unlikely_text_section_p (in_section
)
16623 && GET_CODE (x
) != CONST_INT
16624 && GET_CODE (x
) != CONST_DOUBLE
16630 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
16632 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
16633 fprintf (asm_out_file
, "\t.long\t(");
16634 output_addr_const (asm_out_file
, x
);
16635 fprintf (asm_out_file
, ")@fixup\n");
16636 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
16637 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
16638 fprintf (asm_out_file
, "\t.long\t");
16639 assemble_name (asm_out_file
, buf
);
16640 fprintf (asm_out_file
, "\n\t.previous\n");
16644 /* Remove initial .'s to turn a -mcall-aixdesc function
16645 address into the address of the descriptor, not the function
16647 else if (GET_CODE (x
) == SYMBOL_REF
16648 && XSTR (x
, 0)[0] == '.'
16649 && DEFAULT_ABI
== ABI_AIX
)
16651 const char *name
= XSTR (x
, 0);
16652 while (*name
== '.')
16655 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
16659 #endif /* RELOCATABLE_NEEDS_FIXUP */
16660 return default_assemble_integer (x
, size
, aligned_p
);
16663 #ifdef HAVE_GAS_HIDDEN
16664 /* Emit an assembler directive to set symbol visibility for DECL to
16665 VISIBILITY_TYPE. */
16668 rs6000_assemble_visibility (tree decl
, int vis
)
16670 /* Functions need to have their entry point symbol visibility set as
16671 well as their descriptor symbol visibility. */
16672 if (DEFAULT_ABI
== ABI_AIX
16674 && TREE_CODE (decl
) == FUNCTION_DECL
)
16676 static const char * const visibility_types
[] = {
16677 NULL
, "internal", "hidden", "protected"
16680 const char *name
, *type
;
16682 name
= ((* targetm
.strip_name_encoding
)
16683 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
16684 type
= visibility_types
[vis
];
16686 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
16687 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
16690 default_assemble_visibility (decl
, vis
);
16695 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
16697 /* Reversal of FP compares takes care -- an ordered compare
16698 becomes an unordered compare and vice versa. */
16699 if (mode
== CCFPmode
16700 && (!flag_finite_math_only
16701 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
16702 || code
== UNEQ
|| code
== LTGT
))
16703 return reverse_condition_maybe_unordered (code
);
16705 return reverse_condition (code
);
16708 /* Generate a compare for CODE. Return a brand-new rtx that
16709 represents the result of the compare. */
16712 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
16714 enum machine_mode comp_mode
;
16715 rtx compare_result
;
16716 enum rtx_code code
= GET_CODE (cmp
);
16717 rtx op0
= XEXP (cmp
, 0);
16718 rtx op1
= XEXP (cmp
, 1);
16720 if (FLOAT_MODE_P (mode
))
16721 comp_mode
= CCFPmode
;
16722 else if (code
== GTU
|| code
== LTU
16723 || code
== GEU
|| code
== LEU
)
16724 comp_mode
= CCUNSmode
;
16725 else if ((code
== EQ
|| code
== NE
)
16726 && GET_CODE (op0
) == SUBREG
16727 && GET_CODE (op1
) == SUBREG
16728 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
16729 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
16730 /* These are unsigned values, perhaps there will be a later
16731 ordering compare that can be shared with this one.
16732 Unfortunately we cannot detect the signedness of the operands
16733 for non-subregs. */
16734 comp_mode
= CCUNSmode
;
16736 comp_mode
= CCmode
;
16738 /* First, the compare. */
16739 compare_result
= gen_reg_rtx (comp_mode
);
16741 /* E500 FP compare instructions on the GPRs. Yuck! */
16742 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16743 && FLOAT_MODE_P (mode
))
16745 rtx cmp
, or_result
, compare_result2
;
16746 enum machine_mode op_mode
= GET_MODE (op0
);
16748 if (op_mode
== VOIDmode
)
16749 op_mode
= GET_MODE (op1
);
16751 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16752 This explains the following mess. */
16756 case EQ
: case UNEQ
: case NE
: case LTGT
:
16760 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16761 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
16762 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
16766 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16767 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
16768 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
16772 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16773 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
16774 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
16778 gcc_unreachable ();
16782 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
16786 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16787 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
16788 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
16792 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16793 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
16794 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
16798 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16799 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
16800 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
16804 gcc_unreachable ();
16808 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
16812 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16813 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
16814 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
16818 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16819 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
16820 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
16824 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16825 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
16826 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
16830 gcc_unreachable ();
16834 gcc_unreachable ();
16837 /* Synthesize LE and GE from LT/GT || EQ. */
16838 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
16844 case LE
: code
= LT
; break;
16845 case GE
: code
= GT
; break;
16846 case LEU
: code
= LT
; break;
16847 case GEU
: code
= GT
; break;
16848 default: gcc_unreachable ();
16851 compare_result2
= gen_reg_rtx (CCFPmode
);
16857 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16858 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
16859 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
16863 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16864 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
16865 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
16869 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16870 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
16871 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
16875 gcc_unreachable ();
16879 /* OR them together. */
16880 or_result
= gen_reg_rtx (CCFPmode
);
16881 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
16883 compare_result
= or_result
;
16888 if (code
== NE
|| code
== LTGT
)
16898 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16899 CLOBBERs to match cmptf_internal2 pattern. */
16900 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
16901 && GET_MODE (op0
) == TFmode
16902 && !TARGET_IEEEQUAD
16903 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
16904 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
16906 gen_rtx_SET (VOIDmode
,
16908 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
16909 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16910 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16911 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16912 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16913 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16914 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16915 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16916 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16917 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (Pmode
)))));
16918 else if (GET_CODE (op1
) == UNSPEC
16919 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
16921 rtx op1b
= XVECEXP (op1
, 0, 0);
16922 comp_mode
= CCEQmode
;
16923 compare_result
= gen_reg_rtx (CCEQmode
);
16925 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
16927 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
16930 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
16931 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
16934 /* Some kinds of FP comparisons need an OR operation;
16935 under flag_finite_math_only we don't bother. */
16936 if (FLOAT_MODE_P (mode
)
16937 && !flag_finite_math_only
16938 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
16939 && (code
== LE
|| code
== GE
16940 || code
== UNEQ
|| code
== LTGT
16941 || code
== UNGT
|| code
== UNLT
))
16943 enum rtx_code or1
, or2
;
16944 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
16945 rtx or_result
= gen_reg_rtx (CCEQmode
);
16949 case LE
: or1
= LT
; or2
= EQ
; break;
16950 case GE
: or1
= GT
; or2
= EQ
; break;
16951 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
16952 case LTGT
: or1
= LT
; or2
= GT
; break;
16953 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
16954 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
16955 default: gcc_unreachable ();
16957 validate_condition_mode (or1
, comp_mode
);
16958 validate_condition_mode (or2
, comp_mode
);
16959 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
16960 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
16961 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
16962 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
16964 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
16966 compare_result
= or_result
;
16970 validate_condition_mode (code
, GET_MODE (compare_result
));
16972 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
16976 /* Emit the RTL for an sISEL pattern. */
16979 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx operands
[])
16981 rs6000_emit_int_cmove (operands
[0], operands
[1], const1_rtx
, const0_rtx
);
16985 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
16988 enum machine_mode op_mode
;
16989 enum rtx_code cond_code
;
16990 rtx result
= operands
[0];
16992 if (TARGET_ISEL
&& (mode
== SImode
|| mode
== DImode
))
16994 rs6000_emit_sISEL (mode
, operands
);
16998 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
16999 cond_code
= GET_CODE (condition_rtx
);
17001 if (FLOAT_MODE_P (mode
)
17002 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
17006 PUT_MODE (condition_rtx
, SImode
);
17007 t
= XEXP (condition_rtx
, 0);
17009 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
17011 if (cond_code
== NE
)
17012 emit_insn (gen_e500_flip_gt_bit (t
, t
));
17014 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
17018 if (cond_code
== NE
17019 || cond_code
== GE
|| cond_code
== LE
17020 || cond_code
== GEU
|| cond_code
== LEU
17021 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
17023 rtx not_result
= gen_reg_rtx (CCEQmode
);
17024 rtx not_op
, rev_cond_rtx
;
17025 enum machine_mode cc_mode
;
17027 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
17029 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
17030 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
17031 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
17032 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
17033 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
17036 op_mode
= GET_MODE (XEXP (operands
[1], 0));
17037 if (op_mode
== VOIDmode
)
17038 op_mode
= GET_MODE (XEXP (operands
[1], 1));
17040 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
17042 PUT_MODE (condition_rtx
, DImode
);
17043 convert_move (result
, condition_rtx
, 0);
17047 PUT_MODE (condition_rtx
, SImode
);
17048 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
17052 /* Emit a branch of kind CODE to location LOC. */
17055 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
17057 rtx condition_rtx
, loc_ref
;
17059 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
17060 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
17061 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
17062 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
17063 loc_ref
, pc_rtx
)));
17066 /* Return the string to output a conditional branch to LABEL, which is
17067 the operand number of the label, or -1 if the branch is really a
17068 conditional return.
17070 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17071 condition code register and its mode specifies what kind of
17072 comparison we made.
17074 REVERSED is nonzero if we should reverse the sense of the comparison.
17076 INSN is the insn. */
17079 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
17081 static char string
[64];
17082 enum rtx_code code
= GET_CODE (op
);
17083 rtx cc_reg
= XEXP (op
, 0);
17084 enum machine_mode mode
= GET_MODE (cc_reg
);
17085 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
17086 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
17087 int really_reversed
= reversed
^ need_longbranch
;
17093 validate_condition_mode (code
, mode
);
17095 /* Work out which way this really branches. We could use
17096 reverse_condition_maybe_unordered here always but this
17097 makes the resulting assembler clearer. */
17098 if (really_reversed
)
17100 /* Reversal of FP compares takes care -- an ordered compare
17101 becomes an unordered compare and vice versa. */
17102 if (mode
== CCFPmode
)
17103 code
= reverse_condition_maybe_unordered (code
);
17105 code
= reverse_condition (code
);
17108 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
17110 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17115 /* Opposite of GT. */
17124 gcc_unreachable ();
17130 /* Not all of these are actually distinct opcodes, but
17131 we distinguish them for clarity of the resulting assembler. */
17132 case NE
: case LTGT
:
17133 ccode
= "ne"; break;
17134 case EQ
: case UNEQ
:
17135 ccode
= "eq"; break;
17137 ccode
= "ge"; break;
17138 case GT
: case GTU
: case UNGT
:
17139 ccode
= "gt"; break;
17141 ccode
= "le"; break;
17142 case LT
: case LTU
: case UNLT
:
17143 ccode
= "lt"; break;
17144 case UNORDERED
: ccode
= "un"; break;
17145 case ORDERED
: ccode
= "nu"; break;
17146 case UNGE
: ccode
= "nl"; break;
17147 case UNLE
: ccode
= "ng"; break;
17149 gcc_unreachable ();
17152 /* Maybe we have a guess as to how likely the branch is.
17153 The old mnemonics don't have a way to specify this information. */
17155 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
17156 if (note
!= NULL_RTX
)
17158 /* PROB is the difference from 50%. */
17159 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
17161 /* Only hint for highly probable/improbable branches on newer
17162 cpus as static prediction overrides processor dynamic
17163 prediction. For older cpus we may as well always hint, but
17164 assume not taken for branches that are very close to 50% as a
17165 mispredicted taken branch is more expensive than a
17166 mispredicted not-taken branch. */
17167 if (rs6000_always_hint
17168 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
17169 && br_prob_note_reliable_p (note
)))
17171 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
17172 && ((prob
> 0) ^ need_longbranch
))
17180 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
17182 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
17184 /* We need to escape any '%' characters in the reg_names string.
17185 Assume they'd only be the first character.... */
17186 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
17188 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
17192 /* If the branch distance was too far, we may have to use an
17193 unconditional branch to go the distance. */
17194 if (need_longbranch
)
17195 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
17197 s
+= sprintf (s
, ",%s", label
);
17203 /* Return the string to flip the GT bit on a CR. */
17205 output_e500_flip_gt_bit (rtx dst
, rtx src
)
17207 static char string
[64];
17210 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
17211 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
17214 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
17215 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
17217 sprintf (string
, "crnot %d,%d", a
, b
);
17221 /* Return insn for VSX or Altivec comparisons. */
17224 rs6000_emit_vector_compare_inner (enum rtx_code code
, rtx op0
, rtx op1
)
17227 enum machine_mode mode
= GET_MODE (op0
);
17235 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
17241 mask
= gen_reg_rtx (mode
);
17242 emit_insn (gen_rtx_SET (VOIDmode
,
17244 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17251 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17252 DMODE is expected destination mode. This is a recursive function. */
17255 rs6000_emit_vector_compare (enum rtx_code rcode
,
17257 enum machine_mode dmode
)
17260 bool swap_operands
= false;
17261 bool try_again
= false;
17263 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode
));
17264 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
17266 /* See if the comparison works as is. */
17267 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
17275 swap_operands
= true;
17280 swap_operands
= true;
17288 /* Invert condition and try again.
17289 e.g., A != B becomes ~(A==B). */
17291 enum rtx_code rev_code
;
17292 enum insn_code nor_code
;
17295 rev_code
= reverse_condition_maybe_unordered (rcode
);
17296 if (rev_code
== UNKNOWN
)
17299 nor_code
= optab_handler (one_cmpl_optab
, dmode
);
17300 if (nor_code
== CODE_FOR_nothing
)
17303 mask2
= rs6000_emit_vector_compare (rev_code
, op0
, op1
, dmode
);
17307 mask
= gen_reg_rtx (dmode
);
17308 emit_insn (GEN_FCN (nor_code
) (mask
, mask2
));
17316 /* Try GT/GTU/LT/LTU OR EQ */
17319 enum insn_code ior_code
;
17320 enum rtx_code new_code
;
17341 gcc_unreachable ();
17344 ior_code
= optab_handler (ior_optab
, dmode
);
17345 if (ior_code
== CODE_FOR_nothing
)
17348 c_rtx
= rs6000_emit_vector_compare (new_code
, op0
, op1
, dmode
);
17352 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
, dmode
);
17356 mask
= gen_reg_rtx (dmode
);
17357 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
17375 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
17380 /* You only get two chances. */
17384 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17385 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17386 operands for the relation operation COND. */
17389 rs6000_emit_vector_cond_expr (rtx dest
, rtx op_true
, rtx op_false
,
17390 rtx cond
, rtx cc_op0
, rtx cc_op1
)
17392 enum machine_mode dest_mode
= GET_MODE (dest
);
17393 enum rtx_code rcode
= GET_CODE (cond
);
17394 enum machine_mode cc_mode
= CCmode
;
17398 bool invert_move
= false;
17400 if (VECTOR_UNIT_NONE_P (dest_mode
))
17405 /* Swap operands if we can, and fall back to doing the operation as
17406 specified, and doing a NOR to invert the test. */
17412 /* Invert condition and try again.
17413 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17414 invert_move
= true;
17415 rcode
= reverse_condition_maybe_unordered (rcode
);
17416 if (rcode
== UNKNOWN
)
17420 /* Mark unsigned tests with CCUNSmode. */
17425 cc_mode
= CCUNSmode
;
17432 /* Get the vector mask for the given relational operations. */
17433 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
17441 op_true
= op_false
;
17445 cond2
= gen_rtx_fmt_ee (NE
, cc_mode
, mask
, const0_rtx
);
17446 emit_insn (gen_rtx_SET (VOIDmode
,
17448 gen_rtx_IF_THEN_ELSE (dest_mode
,
17455 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17456 operands of the last comparison is nonzero/true, FALSE_COND if it
17457 is zero/false. Return 0 if the hardware has no such operation. */
17460 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17462 enum rtx_code code
= GET_CODE (op
);
17463 rtx op0
= XEXP (op
, 0);
17464 rtx op1
= XEXP (op
, 1);
17465 REAL_VALUE_TYPE c1
;
17466 enum machine_mode compare_mode
= GET_MODE (op0
);
17467 enum machine_mode result_mode
= GET_MODE (dest
);
17469 bool is_against_zero
;
17471 /* These modes should always match. */
17472 if (GET_MODE (op1
) != compare_mode
17473 /* In the isel case however, we can use a compare immediate, so
17474 op1 may be a small constant. */
17475 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
17477 if (GET_MODE (true_cond
) != result_mode
)
17479 if (GET_MODE (false_cond
) != result_mode
)
17482 /* First, work out if the hardware can do this at all, or
17483 if it's too slow.... */
17484 if (!FLOAT_MODE_P (compare_mode
))
17487 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
17490 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
17491 && SCALAR_FLOAT_MODE_P (compare_mode
))
17494 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
17496 /* A floating-point subtract might overflow, underflow, or produce
17497 an inexact result, thus changing the floating-point flags, so it
17498 can't be generated if we care about that. It's safe if one side
17499 of the construct is zero, since then no subtract will be
17501 if (SCALAR_FLOAT_MODE_P (compare_mode
)
17502 && flag_trapping_math
&& ! is_against_zero
)
17505 /* Eliminate half of the comparisons by switching operands, this
17506 makes the remaining code simpler. */
17507 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
17508 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
17510 code
= reverse_condition_maybe_unordered (code
);
17512 true_cond
= false_cond
;
17516 /* UNEQ and LTGT take four instructions for a comparison with zero,
17517 it'll probably be faster to use a branch here too. */
17518 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
17521 if (GET_CODE (op1
) == CONST_DOUBLE
)
17522 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
17524 /* We're going to try to implement comparisons by performing
17525 a subtract, then comparing against zero. Unfortunately,
17526 Inf - Inf is NaN which is not zero, and so if we don't
17527 know that the operand is finite and the comparison
17528 would treat EQ different to UNORDERED, we can't do it. */
17529 if (HONOR_INFINITIES (compare_mode
)
17530 && code
!= GT
&& code
!= UNGE
17531 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
17532 /* Constructs of the form (a OP b ? a : b) are safe. */
17533 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
17534 || (! rtx_equal_p (op0
, true_cond
)
17535 && ! rtx_equal_p (op1
, true_cond
))))
17538 /* At this point we know we can use fsel. */
17540 /* Reduce the comparison to a comparison against zero. */
17541 if (! is_against_zero
)
17543 temp
= gen_reg_rtx (compare_mode
);
17544 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17545 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
17547 op1
= CONST0_RTX (compare_mode
);
17550 /* If we don't care about NaNs we can reduce some of the comparisons
17551 down to faster ones. */
17552 if (! HONOR_NANS (compare_mode
))
17558 true_cond
= false_cond
;
17571 /* Now, reduce everything down to a GE. */
17578 temp
= gen_reg_rtx (compare_mode
);
17579 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17584 temp
= gen_reg_rtx (compare_mode
);
17585 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
17590 temp
= gen_reg_rtx (compare_mode
);
17591 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17592 gen_rtx_NEG (compare_mode
,
17593 gen_rtx_ABS (compare_mode
, op0
))));
17598 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17599 temp
= gen_reg_rtx (result_mode
);
17600 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17601 gen_rtx_IF_THEN_ELSE (result_mode
,
17602 gen_rtx_GE (VOIDmode
,
17604 true_cond
, false_cond
)));
17605 false_cond
= true_cond
;
17608 temp
= gen_reg_rtx (compare_mode
);
17609 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17614 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17615 temp
= gen_reg_rtx (result_mode
);
17616 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17617 gen_rtx_IF_THEN_ELSE (result_mode
,
17618 gen_rtx_GE (VOIDmode
,
17620 true_cond
, false_cond
)));
17621 true_cond
= false_cond
;
17624 temp
= gen_reg_rtx (compare_mode
);
17625 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17630 gcc_unreachable ();
17633 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
17634 gen_rtx_IF_THEN_ELSE (result_mode
,
17635 gen_rtx_GE (VOIDmode
,
17637 true_cond
, false_cond
)));
17641 /* Same as above, but for ints (isel). */
17644 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17646 rtx condition_rtx
, cr
;
17647 enum machine_mode mode
= GET_MODE (dest
);
17648 enum rtx_code cond_code
;
17649 rtx (*isel_func
) (rtx
, rtx
, rtx
, rtx
, rtx
);
17652 if (mode
!= SImode
&& (!TARGET_POWERPC64
|| mode
!= DImode
))
17655 /* We still have to do the compare, because isel doesn't do a
17656 compare, it just looks at the CRx bits set by a previous compare
17658 condition_rtx
= rs6000_generate_compare (op
, mode
);
17659 cond_code
= GET_CODE (condition_rtx
);
17660 cr
= XEXP (condition_rtx
, 0);
17661 signedp
= GET_MODE (cr
) == CCmode
;
17663 isel_func
= (mode
== SImode
17664 ? (signedp
? gen_isel_signed_si
: gen_isel_unsigned_si
)
17665 : (signedp
? gen_isel_signed_di
: gen_isel_unsigned_di
));
17669 case LT
: case GT
: case LTU
: case GTU
: case EQ
:
17670 /* isel handles these directly. */
17674 /* We need to swap the sense of the comparison. */
17677 true_cond
= false_cond
;
17679 PUT_CODE (condition_rtx
, reverse_condition (cond_code
));
17684 false_cond
= force_reg (mode
, false_cond
);
17685 if (true_cond
!= const0_rtx
)
17686 true_cond
= force_reg (mode
, true_cond
);
17688 emit_insn (isel_func (dest
, condition_rtx
, true_cond
, false_cond
, cr
));
17694 output_isel (rtx
*operands
)
17696 enum rtx_code code
;
17698 code
= GET_CODE (operands
[1]);
17700 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
17702 gcc_assert (GET_CODE (operands
[2]) == REG
17703 && GET_CODE (operands
[3]) == REG
);
17704 PUT_CODE (operands
[1], reverse_condition (code
));
17705 return "isel %0,%3,%2,%j1";
17708 return "isel %0,%2,%3,%j1";
17712 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
17714 enum machine_mode mode
= GET_MODE (op0
);
17718 /* VSX/altivec have direct min/max insns. */
17719 if ((code
== SMAX
|| code
== SMIN
)
17720 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
17721 || (mode
== SFmode
&& VECTOR_UNIT_VSX_P (DFmode
))))
17723 emit_insn (gen_rtx_SET (VOIDmode
,
17725 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17729 if (code
== SMAX
|| code
== SMIN
)
17734 if (code
== SMAX
|| code
== UMAX
)
17735 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17736 op0
, op1
, mode
, 0);
17738 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17739 op1
, op0
, mode
, 0);
17740 gcc_assert (target
);
17741 if (target
!= dest
)
17742 emit_move_insn (dest
, target
);
17745 /* Emit instructions to perform a load-reserved/store-conditional operation.
17746 The operation performed is an atomic
17747 (set M (CODE:MODE M OP))
17748 If not NULL, BEFORE is atomically set to M before the operation, and
17749 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17750 If SYNC_P then a memory barrier is emitted before the operation.
17751 Either OP or M may be wrapped in a NOT operation. */
17754 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
17755 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
17758 enum machine_mode used_mode
;
17759 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
17762 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17763 rtx shift
= NULL_RTX
;
17766 emit_insn (gen_lwsync ());
17770 /* If this is smaller than SImode, we'll have to use SImode with
17772 if (mode
== QImode
|| mode
== HImode
)
17776 if (MEM_ALIGN (used_m
) >= 32)
17779 if (BYTES_BIG_ENDIAN
)
17780 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
17782 shift
= GEN_INT (ishift
);
17783 used_m
= change_address (used_m
, SImode
, 0);
17787 rtx addrSI
, aligned_addr
;
17788 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
17790 addrSI
= gen_lowpart_common (SImode
,
17791 force_reg (Pmode
, XEXP (used_m
, 0)));
17792 addrSI
= force_reg (SImode
, addrSI
);
17793 shift
= gen_reg_rtx (SImode
);
17795 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
17796 GEN_INT (shift_mask
)));
17797 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
17799 aligned_addr
= expand_binop (Pmode
, and_optab
,
17801 GEN_INT (-4), NULL_RTX
,
17802 1, OPTAB_LIB_WIDEN
);
17803 used_m
= change_address (used_m
, SImode
, aligned_addr
);
17804 set_mem_align (used_m
, 32);
17806 /* It's safe to keep the old alias set of USED_M, because
17807 the operation is atomic and only affects the original
17811 if (GET_CODE (op
) == NOT
)
17813 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
17814 oldop
= gen_rtx_NOT (SImode
, oldop
);
17817 oldop
= lowpart_subreg (SImode
, op
, mode
);
17823 newop
= expand_binop (SImode
, and_optab
,
17824 oldop
, GEN_INT (imask
), NULL_RTX
,
17825 1, OPTAB_LIB_WIDEN
);
17826 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17829 case NOT
: /* NAND */
17830 newop
= expand_binop (SImode
, ior_optab
,
17831 oldop
, GEN_INT (~imask
), NULL_RTX
,
17832 1, OPTAB_LIB_WIDEN
);
17833 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17837 newop
= expand_binop (SImode
, ior_optab
,
17838 oldop
, GEN_INT (~imask
), NULL_RTX
,
17839 1, OPTAB_LIB_WIDEN
);
17840 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17848 newop
= expand_binop (SImode
, and_optab
,
17849 oldop
, GEN_INT (imask
), NULL_RTX
,
17850 1, OPTAB_LIB_WIDEN
);
17851 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17853 mask
= gen_reg_rtx (SImode
);
17854 emit_move_insn (mask
, GEN_INT (imask
));
17855 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
17858 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
17860 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
17861 newop
= gen_rtx_AND (SImode
, newop
, mask
);
17862 newop
= gen_rtx_IOR (SImode
, newop
,
17863 gen_rtx_AND (SImode
,
17864 gen_rtx_NOT (SImode
, mask
),
17870 gcc_unreachable ();
17874 used_mode
= SImode
;
17875 before
= gen_reg_rtx (used_mode
);
17876 after
= gen_reg_rtx (used_mode
);
17881 before
= before_param
;
17882 after
= after_param
;
17884 if (before
== NULL_RTX
)
17885 before
= gen_reg_rtx (used_mode
);
17886 if (after
== NULL_RTX
)
17887 after
= gen_reg_rtx (used_mode
);
17890 if ((code
== PLUS
|| code
== MINUS
)
17891 && used_mode
!= mode
)
17892 the_op
= op
; /* Computed above. */
17893 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
17894 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
17895 else if (code
== NOT
)
17896 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
17897 gen_rtx_NOT (used_mode
, m
),
17898 gen_rtx_NOT (used_mode
, op
));
17900 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
17902 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
17903 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
17904 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
17905 gen_rtx_UNSPEC (used_mode
,
17906 gen_rtvec (1, the_op
),
17908 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
17910 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
17911 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
17912 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
17914 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
17915 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
17917 /* Shift and mask the return values properly. */
17918 if (used_mode
!= mode
&& before_param
)
17920 emit_insn (gen_lshrsi3 (before
, before
, shift
));
17921 convert_move (before_param
, before
, 1);
17924 if (used_mode
!= mode
&& after_param
)
17926 emit_insn (gen_lshrsi3 (after
, after
, shift
));
17927 convert_move (after_param
, after
, 1);
17930 /* The previous sequence will end with a branch that's dependent on
17931 the conditional store, so placing an isync will ensure that no
17932 other instructions (especially, no load or store instructions)
17933 can start before the atomic operation completes. */
17935 emit_insn (gen_isync ());
17938 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17939 COND is true. Mark the jump as unlikely to be taken. */
17942 emit_unlikely_jump (rtx cond
, rtx label
)
17944 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
17947 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
17948 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
17949 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
17952 /* A subroutine of the atomic operation splitters. Emit a load-locked
17953 instruction in MODE. */
17956 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
17958 rtx (*fn
) (rtx
, rtx
) = NULL
;
17959 if (mode
== SImode
)
17960 fn
= gen_load_locked_si
;
17961 else if (mode
== DImode
)
17962 fn
= gen_load_locked_di
;
17963 emit_insn (fn (reg
, mem
));
17966 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17967 instruction in MODE. */
17970 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
17972 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
17973 if (mode
== SImode
)
17974 fn
= gen_store_conditional_si
;
17975 else if (mode
== DImode
)
17976 fn
= gen_store_conditional_di
;
17978 /* Emit sync before stwcx. to address PPC405 Erratum. */
17979 if (PPC405_ERRATUM77
)
17980 emit_insn (gen_memory_barrier ());
17982 emit_insn (fn (res
, mem
, val
));
17985 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17986 to perform. MEM is the memory on which to operate. VAL is the second
17987 operand of the binary operator. BEFORE and AFTER are optional locations to
17988 return the value of MEM either before of after the operation. SCRATCH is
17989 a scratch register. */
17992 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
17993 rtx before
, rtx after
, rtx scratch
)
17995 enum machine_mode mode
= GET_MODE (mem
);
17996 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17998 emit_insn (gen_lwsync ());
18000 label
= gen_label_rtx ();
18001 emit_label (label
);
18002 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
18004 if (before
== NULL_RTX
)
18006 emit_load_locked (mode
, before
, mem
);
18009 x
= gen_rtx_IOR (mode
,
18010 gen_rtx_NOT (mode
, before
),
18011 gen_rtx_NOT (mode
, val
));
18012 else if (code
== AND
)
18013 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
18015 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
18017 if (after
!= NULL_RTX
)
18018 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
18019 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
18021 emit_store_conditional (mode
, cond
, mem
, scratch
);
18023 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18024 emit_unlikely_jump (x
, label
);
18026 emit_insn (gen_isync ());
18029 /* Expand an atomic compare and swap operation. MEM is the memory on which
18030 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18031 value to be stored. SCRATCH is a scratch GPR. */
18034 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
18037 enum machine_mode mode
= GET_MODE (mem
);
18038 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18040 emit_insn (gen_lwsync ());
18042 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18043 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18044 emit_label (XEXP (label1
, 0));
18046 emit_load_locked (mode
, retval
, mem
);
18048 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
18049 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
18051 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18052 emit_unlikely_jump (x
, label2
);
18054 emit_move_insn (scratch
, newval
);
18055 emit_store_conditional (mode
, cond
, mem
, scratch
);
18057 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18058 emit_unlikely_jump (x
, label1
);
18060 emit_insn (gen_isync ());
18061 emit_label (XEXP (label2
, 0));
18064 /* Expand an atomic test and set operation. MEM is the memory on which
18065 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18068 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
18070 enum machine_mode mode
= GET_MODE (mem
);
18071 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18073 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18074 emit_label (XEXP (label
, 0));
18076 emit_load_locked (mode
, retval
, mem
);
18077 emit_move_insn (scratch
, val
);
18078 emit_store_conditional (mode
, cond
, mem
, scratch
);
18080 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18081 emit_unlikely_jump (x
, label
);
18083 emit_insn (gen_isync ());
18087 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
18089 enum machine_mode mode
= GET_MODE (mem
);
18090 rtx addrSI
, align
, wdst
, shift
, mask
;
18091 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
18092 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
18094 /* Shift amount for subword relative to aligned word. */
18095 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
18096 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
18097 shift
= gen_reg_rtx (SImode
);
18098 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
18099 GEN_INT (shift_mask
)));
18100 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
18102 /* Shift and mask old value into position within word. */
18103 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
18104 oldval
= expand_binop (SImode
, and_optab
,
18105 oldval
, GEN_INT (imask
), NULL_RTX
,
18106 1, OPTAB_LIB_WIDEN
);
18107 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
18109 /* Shift and mask new value into position within word. */
18110 newval
= convert_modes (SImode
, mode
, newval
, 1);
18111 newval
= expand_binop (SImode
, and_optab
,
18112 newval
, GEN_INT (imask
), NULL_RTX
,
18113 1, OPTAB_LIB_WIDEN
);
18114 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
18116 /* Mask for insertion. */
18117 mask
= gen_reg_rtx (SImode
);
18118 emit_move_insn (mask
, GEN_INT (imask
));
18119 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
18121 /* Address of aligned word containing subword. */
18122 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
18123 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
18124 mem
= change_address (mem
, SImode
, align
);
18125 set_mem_align (mem
, 32);
18126 MEM_VOLATILE_P (mem
) = 1;
18128 wdst
= gen_reg_rtx (SImode
);
18129 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
18130 oldval
, newval
, mem
));
18132 /* Shift the result back. */
18133 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
18135 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
18139 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
18140 rtx oldval
, rtx newval
, rtx mem
,
18143 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18145 emit_insn (gen_lwsync ());
18146 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18147 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18148 emit_label (XEXP (label1
, 0));
18150 emit_load_locked (SImode
, scratch
, mem
);
18152 /* Mask subword within loaded value for comparison with oldval.
18153 Use UNSPEC_AND to avoid clobber.*/
18154 emit_insn (gen_rtx_SET (SImode
, dest
,
18155 gen_rtx_UNSPEC (SImode
,
18156 gen_rtvec (2, scratch
, mask
),
18159 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
18160 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
18162 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18163 emit_unlikely_jump (x
, label2
);
18165 /* Clear subword within loaded value for insertion of new value. */
18166 emit_insn (gen_rtx_SET (SImode
, scratch
,
18167 gen_rtx_AND (SImode
,
18168 gen_rtx_NOT (SImode
, mask
), scratch
)));
18169 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
18170 emit_store_conditional (SImode
, cond
, mem
, scratch
);
18172 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18173 emit_unlikely_jump (x
, label1
);
18175 emit_insn (gen_isync ());
18176 emit_label (XEXP (label2
, 0));
18180 /* Emit instructions to move SRC to DST. Called by splitters for
18181 multi-register moves. It will emit at most one instruction for
18182 each register that is accessed; that is, it won't emit li/lis pairs
18183 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18187 rs6000_split_multireg_move (rtx dst
, rtx src
)
18189 /* The register number of the first register being moved. */
18191 /* The mode that is to be moved. */
18192 enum machine_mode mode
;
18193 /* The mode that the move is being done in, and its size. */
18194 enum machine_mode reg_mode
;
18196 /* The number of registers that will be moved. */
18199 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
18200 mode
= GET_MODE (dst
);
18201 nregs
= hard_regno_nregs
[reg
][mode
];
18202 if (FP_REGNO_P (reg
))
18203 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
18204 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
18205 else if (ALTIVEC_REGNO_P (reg
))
18206 reg_mode
= V16QImode
;
18207 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
18210 reg_mode
= word_mode
;
18211 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
18213 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
18215 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
18217 /* Move register range backwards, if we might have destructive
18220 for (i
= nregs
- 1; i
>= 0; i
--)
18221 emit_insn (gen_rtx_SET (VOIDmode
,
18222 simplify_gen_subreg (reg_mode
, dst
, mode
,
18223 i
* reg_mode_size
),
18224 simplify_gen_subreg (reg_mode
, src
, mode
,
18225 i
* reg_mode_size
)));
18231 bool used_update
= false;
18232 rtx restore_basereg
= NULL_RTX
;
18234 if (MEM_P (src
) && INT_REGNO_P (reg
))
18238 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
18239 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
18242 breg
= XEXP (XEXP (src
, 0), 0);
18243 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
18244 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
18245 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
18246 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
18247 src
= replace_equiv_address (src
, breg
);
18249 else if (! rs6000_offsettable_memref_p (src
))
18251 if (GET_CODE (XEXP (src
, 0)) == PRE_MODIFY
)
18253 rtx basereg
= XEXP (XEXP (src
, 0), 0);
18256 rtx ndst
= simplify_gen_subreg (reg_mode
, dst
, mode
, 0);
18257 emit_insn (gen_rtx_SET (VOIDmode
, ndst
,
18258 gen_rtx_MEM (reg_mode
, XEXP (src
, 0))));
18259 used_update
= true;
18262 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
18263 XEXP (XEXP (src
, 0), 1)));
18264 src
= replace_equiv_address (src
, basereg
);
18268 rtx basereg
= gen_rtx_REG (Pmode
, reg
);
18269 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
18270 src
= replace_equiv_address (src
, basereg
);
18274 breg
= XEXP (src
, 0);
18275 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
18276 breg
= XEXP (breg
, 0);
18278 /* If the base register we are using to address memory is
18279 also a destination reg, then change that register last. */
18281 && REGNO (breg
) >= REGNO (dst
)
18282 && REGNO (breg
) < REGNO (dst
) + nregs
)
18283 j
= REGNO (breg
) - REGNO (dst
);
18285 else if (MEM_P (dst
) && INT_REGNO_P (reg
))
18289 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
18290 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
18293 breg
= XEXP (XEXP (dst
, 0), 0);
18294 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
18295 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
18296 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
18298 /* We have to update the breg before doing the store.
18299 Use store with update, if available. */
18303 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
18304 emit_insn (TARGET_32BIT
18305 ? (TARGET_POWERPC64
18306 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
18307 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
18308 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
18309 used_update
= true;
18312 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
18313 dst
= replace_equiv_address (dst
, breg
);
18315 else if (!rs6000_offsettable_memref_p (dst
)
18316 && GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
18318 if (GET_CODE (XEXP (dst
, 0)) == PRE_MODIFY
)
18320 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
18323 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
18324 emit_insn (gen_rtx_SET (VOIDmode
,
18325 gen_rtx_MEM (reg_mode
, XEXP (dst
, 0)), nsrc
));
18326 used_update
= true;
18329 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
18330 XEXP (XEXP (dst
, 0), 1)));
18331 dst
= replace_equiv_address (dst
, basereg
);
18335 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
18336 rtx offsetreg
= XEXP (XEXP (dst
, 0), 1);
18337 gcc_assert (GET_CODE (XEXP (dst
, 0)) == PLUS
18339 && REG_P (offsetreg
)
18340 && REGNO (basereg
) != REGNO (offsetreg
));
18341 if (REGNO (basereg
) == 0)
18343 rtx tmp
= offsetreg
;
18344 offsetreg
= basereg
;
18347 emit_insn (gen_add3_insn (basereg
, basereg
, offsetreg
));
18348 restore_basereg
= gen_sub3_insn (basereg
, basereg
, offsetreg
);
18349 dst
= replace_equiv_address (dst
, basereg
);
18352 else if (GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
18353 gcc_assert (rs6000_offsettable_memref_p (dst
));
18356 for (i
= 0; i
< nregs
; i
++)
18358 /* Calculate index to next subword. */
18363 /* If compiler already emitted move of first word by
18364 store with update, no need to do anything. */
18365 if (j
== 0 && used_update
)
18368 emit_insn (gen_rtx_SET (VOIDmode
,
18369 simplify_gen_subreg (reg_mode
, dst
, mode
,
18370 j
* reg_mode_size
),
18371 simplify_gen_subreg (reg_mode
, src
, mode
,
18372 j
* reg_mode_size
)));
18374 if (restore_basereg
!= NULL_RTX
)
18375 emit_insn (restore_basereg
);
18380 /* This page contains routines that are used to determine what the
18381 function prologue and epilogue code will do and write them out. */
18383 /* Return the first fixed-point register that is required to be
18384 saved. 32 if none. */
18387 first_reg_to_save (void)
18391 /* Find lowest numbered live register. */
18392 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
18393 if (df_regs_ever_live_p (first_reg
)
18394 && (! call_used_regs
[first_reg
]
18395 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
18396 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
18397 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
18398 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
18403 && crtl
->uses_pic_offset_table
18404 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18405 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
18411 /* Similar, for FP regs. */
18414 first_fp_reg_to_save (void)
18418 /* Find lowest numbered live register. */
18419 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
18420 if (df_regs_ever_live_p (first_reg
))
18426 /* Similar, for AltiVec regs. */
18429 first_altivec_reg_to_save (void)
18433 /* Stack frame remains as is unless we are in AltiVec ABI. */
18434 if (! TARGET_ALTIVEC_ABI
)
18435 return LAST_ALTIVEC_REGNO
+ 1;
18437 /* On Darwin, the unwind routines are compiled without
18438 TARGET_ALTIVEC, and use save_world to save/restore the
18439 altivec registers when necessary. */
18440 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
18441 && ! TARGET_ALTIVEC
)
18442 return FIRST_ALTIVEC_REGNO
+ 20;
18444 /* Find lowest numbered live register. */
18445 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
18446 if (df_regs_ever_live_p (i
))
18452 /* Return a 32-bit mask of the AltiVec registers we need to set in
18453 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18454 the 32-bit word is 0. */
18456 static unsigned int
18457 compute_vrsave_mask (void)
18459 unsigned int i
, mask
= 0;
18461 /* On Darwin, the unwind routines are compiled without
18462 TARGET_ALTIVEC, and use save_world to save/restore the
18463 call-saved altivec registers when necessary. */
18464 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
18465 && ! TARGET_ALTIVEC
)
18468 /* First, find out if we use _any_ altivec registers. */
18469 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
18470 if (df_regs_ever_live_p (i
))
18471 mask
|= ALTIVEC_REG_BIT (i
);
18476 /* Next, remove the argument registers from the set. These must
18477 be in the VRSAVE mask set by the caller, so we don't need to add
18478 them in again. More importantly, the mask we compute here is
18479 used to generate CLOBBERs in the set_vrsave insn, and we do not
18480 wish the argument registers to die. */
18481 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
18482 mask
&= ~ALTIVEC_REG_BIT (i
);
18484 /* Similarly, remove the return value from the set. */
18487 diddle_return_value (is_altivec_return_reg
, &yes
);
18489 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
18495 /* For a very restricted set of circumstances, we can cut down the
18496 size of prologues/epilogues by calling our own save/restore-the-world
18500 compute_save_world_info (rs6000_stack_t
*info_ptr
)
18502 info_ptr
->world_save_p
= 1;
18503 info_ptr
->world_save_p
18504 = (WORLD_SAVE_P (info_ptr
)
18505 && DEFAULT_ABI
== ABI_DARWIN
18506 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
18507 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
18508 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
18509 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
18510 && info_ptr
->cr_save_p
);
18512 /* This will not work in conjunction with sibcalls. Make sure there
18513 are none. (This check is expensive, but seldom executed.) */
18514 if (WORLD_SAVE_P (info_ptr
))
18517 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
18518 if ( GET_CODE (insn
) == CALL_INSN
18519 && SIBLING_CALL_P (insn
))
18521 info_ptr
->world_save_p
= 0;
18526 if (WORLD_SAVE_P (info_ptr
))
18528 /* Even if we're not touching VRsave, make sure there's room on the
18529 stack for it, if it looks like we're calling SAVE_WORLD, which
18530 will attempt to save it. */
18531 info_ptr
->vrsave_size
= 4;
18533 /* If we are going to save the world, we need to save the link register too. */
18534 info_ptr
->lr_save_p
= 1;
18536 /* "Save" the VRsave register too if we're saving the world. */
18537 if (info_ptr
->vrsave_mask
== 0)
18538 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18540 /* Because the Darwin register save/restore routines only handle
18541 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18543 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
18544 && (info_ptr
->first_altivec_reg_save
18545 >= FIRST_SAVED_ALTIVEC_REGNO
));
18552 is_altivec_return_reg (rtx reg
, void *xyes
)
18554 bool *yes
= (bool *) xyes
;
18555 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
18560 /* Determine the strategy for savings/restoring registers. */
18563 SAVRES_MULTIPLE
= 0x1,
18564 SAVE_INLINE_FPRS
= 0x2,
18565 SAVE_INLINE_GPRS
= 0x4,
18566 REST_INLINE_FPRS
= 0x8,
18567 REST_INLINE_GPRS
= 0x10,
18568 SAVE_NOINLINE_GPRS_SAVES_LR
= 0x20,
18569 SAVE_NOINLINE_FPRS_SAVES_LR
= 0x40,
18570 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
= 0x80
18574 rs6000_savres_strategy (rs6000_stack_t
*info
,
18575 bool using_static_chain_p
)
18579 if (TARGET_MULTIPLE
18580 && !TARGET_POWERPC64
18581 && !(TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
)
18582 && info
->first_gp_reg_save
< 31
18583 && no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true))
18584 strategy
|= SAVRES_MULTIPLE
;
18586 if (crtl
->calls_eh_return
18587 || cfun
->machine
->ra_need_lr
18588 || info
->total_size
> 32767)
18589 strategy
|= (SAVE_INLINE_FPRS
| REST_INLINE_FPRS
18590 | SAVE_INLINE_GPRS
| REST_INLINE_GPRS
);
18592 if (info
->first_fp_reg_save
== 64
18593 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
18594 /* The out-of-line FP routines use double-precision stores;
18595 we can't use those routines if we don't have such stores. */
18596 || (TARGET_HARD_FLOAT
&& !TARGET_DOUBLE_FLOAT
)
18597 || !no_global_regs_above (info
->first_fp_reg_save
, /*gpr=*/false))
18598 strategy
|= SAVE_INLINE_FPRS
| REST_INLINE_FPRS
;
18600 if (info
->first_gp_reg_save
== 32
18601 || GP_SAVE_INLINE (info
->first_gp_reg_save
)
18602 || !((strategy
& SAVRES_MULTIPLE
)
18603 || no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true)))
18604 strategy
|= SAVE_INLINE_GPRS
| REST_INLINE_GPRS
;
18606 /* Don't bother to try to save things out-of-line if r11 is occupied
18607 by the static chain. It would require too much fiddling and the
18608 static chain is rarely used anyway. */
18609 if (using_static_chain_p
)
18610 strategy
|= SAVE_INLINE_FPRS
| SAVE_INLINE_GPRS
;
18612 /* If we are going to use store multiple, then don't even bother
18613 with the out-of-line routines, since the store-multiple
18614 instruction will always be smaller. */
18615 if ((strategy
& SAVRES_MULTIPLE
))
18616 strategy
|= SAVE_INLINE_GPRS
;
18618 /* The situation is more complicated with load multiple. We'd
18619 prefer to use the out-of-line routines for restores, since the
18620 "exit" out-of-line routines can handle the restore of LR and the
18621 frame teardown. However if doesn't make sense to use the
18622 out-of-line routine if that is the only reason we'd need to save
18623 LR, and we can't use the "exit" out-of-line gpr restore if we
18624 have saved some fprs; In those cases it is advantageous to use
18625 load multiple when available. */
18626 if ((strategy
& SAVRES_MULTIPLE
)
18627 && (!info
->lr_save_p
18628 || info
->first_fp_reg_save
!= 64))
18629 strategy
|= REST_INLINE_GPRS
;
18631 /* We can only use load multiple or the out-of-line routines to
18632 restore if we've used store multiple or out-of-line routines
18633 in the prologue, i.e. if we've saved all the registers from
18634 first_gp_reg_save. Otherwise, we risk loading garbage. */
18635 if ((strategy
& (SAVE_INLINE_GPRS
| SAVRES_MULTIPLE
)) == SAVE_INLINE_GPRS
)
18636 strategy
|= REST_INLINE_GPRS
;
18638 /* Saving CR interferes with the exit routines used on the SPE, so
18641 && info
->spe_64bit_regs_used
18642 && info
->cr_save_p
)
18643 strategy
|= REST_INLINE_GPRS
;
18645 #ifdef POWERPC_LINUX
18648 if (!(strategy
& SAVE_INLINE_FPRS
))
18649 strategy
|= SAVE_NOINLINE_FPRS_SAVES_LR
;
18650 else if (!(strategy
& SAVE_INLINE_GPRS
)
18651 && info
->first_fp_reg_save
== 64)
18652 strategy
|= SAVE_NOINLINE_GPRS_SAVES_LR
;
18655 if (TARGET_AIX
&& !(strategy
& REST_INLINE_FPRS
))
18656 strategy
|= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
;
18661 /* Calculate the stack information for the current function. This is
18662 complicated by having two separate calling sequences, the AIX calling
18663 sequence and the V.4 calling sequence.
18665 AIX (and Darwin/Mac OS X) stack frames look like:
18667 SP----> +---------------------------------------+
18668 | back chain to caller | 0 0
18669 +---------------------------------------+
18670 | saved CR | 4 8 (8-11)
18671 +---------------------------------------+
18673 +---------------------------------------+
18674 | reserved for compilers | 12 24
18675 +---------------------------------------+
18676 | reserved for binders | 16 32
18677 +---------------------------------------+
18678 | saved TOC pointer | 20 40
18679 +---------------------------------------+
18680 | Parameter save area (P) | 24 48
18681 +---------------------------------------+
18682 | Alloca space (A) | 24+P etc.
18683 +---------------------------------------+
18684 | Local variable space (L) | 24+P+A
18685 +---------------------------------------+
18686 | Float/int conversion temporary (X) | 24+P+A+L
18687 +---------------------------------------+
18688 | Save area for AltiVec registers (W) | 24+P+A+L+X
18689 +---------------------------------------+
18690 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18691 +---------------------------------------+
18692 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18693 +---------------------------------------+
18694 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18695 +---------------------------------------+
18696 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18697 +---------------------------------------+
18698 old SP->| back chain to caller's caller |
18699 +---------------------------------------+
18701 The required alignment for AIX configurations is two words (i.e., 8
18705 V.4 stack frames look like:
18707 SP----> +---------------------------------------+
18708 | back chain to caller | 0
18709 +---------------------------------------+
18710 | caller's saved LR | 4
18711 +---------------------------------------+
18712 | Parameter save area (P) | 8
18713 +---------------------------------------+
18714 | Alloca space (A) | 8+P
18715 +---------------------------------------+
18716 | Varargs save area (V) | 8+P+A
18717 +---------------------------------------+
18718 | Local variable space (L) | 8+P+A+V
18719 +---------------------------------------+
18720 | Float/int conversion temporary (X) | 8+P+A+V+L
18721 +---------------------------------------+
18722 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18723 +---------------------------------------+
18724 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18725 +---------------------------------------+
18726 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18727 +---------------------------------------+
18728 | SPE: area for 64-bit GP registers |
18729 +---------------------------------------+
18730 | SPE alignment padding |
18731 +---------------------------------------+
18732 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18733 +---------------------------------------+
18734 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18735 +---------------------------------------+
18736 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18737 +---------------------------------------+
18738 old SP->| back chain to caller's caller |
18739 +---------------------------------------+
18741 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18742 given. (But note below and in sysv4.h that we require only 8 and
18743 may round up the size of our stack frame anyways. The historical
18744 reason is early versions of powerpc-linux which didn't properly
18745 align the stack at program startup. A happy side-effect is that
18746 -mno-eabi libraries can be used with -meabi programs.)
18748 The EABI configuration defaults to the V.4 layout. However,
18749 the stack alignment requirements may differ. If -mno-eabi is not
18750 given, the required stack alignment is 8 bytes; if -mno-eabi is
18751 given, the required alignment is 16 bytes. (But see V.4 comment
18754 #ifndef ABI_STACK_BOUNDARY
18755 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18758 static rs6000_stack_t
*
18759 rs6000_stack_info (void)
18761 #ifdef ENABLE_CHECKING
18762 static rs6000_stack_t info_save
;
18764 rs6000_stack_t
*info_ptr
= &stack_info
;
18765 int reg_size
= TARGET_32BIT
? 4 : 8;
18769 HOST_WIDE_INT non_fixed_size
;
18770 bool using_static_chain_p
;
18772 #ifdef ENABLE_CHECKING
18773 memcpy (&info_save
, &stack_info
, sizeof stack_info
);
18775 if (reload_completed
&& info_ptr
->reload_completed
)
18779 memset (&stack_info
, 0, sizeof (stack_info
));
18780 info_ptr
->reload_completed
= reload_completed
;
18784 /* Cache value so we don't rescan instruction chain over and over. */
18785 if (cfun
->machine
->insn_chain_scanned_p
== 0)
18786 cfun
->machine
->insn_chain_scanned_p
18787 = spe_func_has_64bit_regs_p () + 1;
18788 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
18791 /* Select which calling sequence. */
18792 info_ptr
->abi
= DEFAULT_ABI
;
18794 /* Calculate which registers need to be saved & save area size. */
18795 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
18796 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18797 even if it currently looks like we won't. Reload may need it to
18798 get at a constant; if so, it will have already created a constant
18799 pool entry for it. */
18800 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
18801 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
18802 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
18803 && crtl
->uses_const_pool
18804 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18805 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
18807 first_gp
= info_ptr
->first_gp_reg_save
;
18809 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
18811 /* For the SPE, we have an additional upper 32-bits on each GPR.
18812 Ideally we should save the entire 64-bits only when the upper
18813 half is used in SIMD instructions. Since we only record
18814 registers live (not the size they are used in), this proves
18815 difficult because we'd have to traverse the instruction chain at
18816 the right time, taking reload into account. This is a real pain,
18817 so we opt to save the GPRs in 64-bits always if but one register
18818 gets used in 64-bits. Otherwise, all the registers in the frame
18819 get saved in 32-bits.
18821 So... since when we save all GPRs (except the SP) in 64-bits, the
18822 traditional GP save area will be empty. */
18823 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18824 info_ptr
->gp_size
= 0;
18826 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
18827 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
18829 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
18830 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
18831 - info_ptr
->first_altivec_reg_save
);
18833 /* Does this function call anything? */
18834 info_ptr
->calls_p
= (! current_function_is_leaf
18835 || cfun
->machine
->ra_needs_full_frame
);
18837 /* Determine if we need to save the condition code registers. */
18838 if (df_regs_ever_live_p (CR2_REGNO
)
18839 || df_regs_ever_live_p (CR3_REGNO
)
18840 || df_regs_ever_live_p (CR4_REGNO
))
18842 info_ptr
->cr_save_p
= 1;
18843 if (DEFAULT_ABI
== ABI_V4
)
18844 info_ptr
->cr_size
= reg_size
;
18847 /* If the current function calls __builtin_eh_return, then we need
18848 to allocate stack space for registers that will hold data for
18849 the exception handler. */
18850 if (crtl
->calls_eh_return
)
18853 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
18856 /* SPE saves EH registers in 64-bits. */
18857 ehrd_size
= i
* (TARGET_SPE_ABI
18858 && info_ptr
->spe_64bit_regs_used
!= 0
18859 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
18864 /* Determine various sizes. */
18865 info_ptr
->reg_size
= reg_size
;
18866 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
18867 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
18868 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
18869 TARGET_ALTIVEC
? 16 : 8);
18870 if (FRAME_GROWS_DOWNWARD
)
18871 info_ptr
->vars_size
18872 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
18873 + info_ptr
->parm_size
,
18874 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
18875 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
18876 + info_ptr
->parm_size
);
18878 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18879 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
18881 info_ptr
->spe_gp_size
= 0;
18883 if (TARGET_ALTIVEC_ABI
)
18884 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18886 info_ptr
->vrsave_mask
= 0;
18888 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
18889 info_ptr
->vrsave_size
= 4;
18891 info_ptr
->vrsave_size
= 0;
18893 compute_save_world_info (info_ptr
);
18895 /* Calculate the offsets. */
18896 switch (DEFAULT_ABI
)
18900 gcc_unreachable ();
18904 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18905 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18907 if (TARGET_ALTIVEC_ABI
)
18909 info_ptr
->vrsave_save_offset
18910 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
18912 /* Align stack so vector save area is on a quadword boundary.
18913 The padding goes above the vectors. */
18914 if (info_ptr
->altivec_size
!= 0)
18915 info_ptr
->altivec_padding_size
18916 = info_ptr
->vrsave_save_offset
& 0xF;
18918 info_ptr
->altivec_padding_size
= 0;
18920 info_ptr
->altivec_save_offset
18921 = info_ptr
->vrsave_save_offset
18922 - info_ptr
->altivec_padding_size
18923 - info_ptr
->altivec_size
;
18924 gcc_assert (info_ptr
->altivec_size
== 0
18925 || info_ptr
->altivec_save_offset
% 16 == 0);
18927 /* Adjust for AltiVec case. */
18928 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
18931 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
18932 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
18933 info_ptr
->lr_save_offset
= 2*reg_size
;
18937 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18938 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18939 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
18941 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18943 /* Align stack so SPE GPR save area is aligned on a
18944 double-word boundary. */
18945 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
18946 info_ptr
->spe_padding_size
18947 = 8 - (-info_ptr
->cr_save_offset
% 8);
18949 info_ptr
->spe_padding_size
= 0;
18951 info_ptr
->spe_gp_save_offset
18952 = info_ptr
->cr_save_offset
18953 - info_ptr
->spe_padding_size
18954 - info_ptr
->spe_gp_size
;
18956 /* Adjust for SPE case. */
18957 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
18959 else if (TARGET_ALTIVEC_ABI
)
18961 info_ptr
->vrsave_save_offset
18962 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
18964 /* Align stack so vector save area is on a quadword boundary. */
18965 if (info_ptr
->altivec_size
!= 0)
18966 info_ptr
->altivec_padding_size
18967 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
18969 info_ptr
->altivec_padding_size
= 0;
18971 info_ptr
->altivec_save_offset
18972 = info_ptr
->vrsave_save_offset
18973 - info_ptr
->altivec_padding_size
18974 - info_ptr
->altivec_size
;
18976 /* Adjust for AltiVec case. */
18977 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
18980 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
18981 info_ptr
->ehrd_offset
-= ehrd_size
;
18982 info_ptr
->lr_save_offset
= reg_size
;
18986 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
18987 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
18988 + info_ptr
->gp_size
18989 + info_ptr
->altivec_size
18990 + info_ptr
->altivec_padding_size
18991 + info_ptr
->spe_gp_size
18992 + info_ptr
->spe_padding_size
18994 + info_ptr
->cr_size
18995 + info_ptr
->vrsave_size
,
18998 non_fixed_size
= (info_ptr
->vars_size
18999 + info_ptr
->parm_size
19000 + info_ptr
->save_size
);
19002 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
19003 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
19005 /* Determine if we need to save the link register. */
19006 if (info_ptr
->calls_p
19007 || (DEFAULT_ABI
== ABI_AIX
19009 && !TARGET_PROFILE_KERNEL
)
19010 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
19011 #ifdef TARGET_RELOCATABLE
19012 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
19014 || rs6000_ra_ever_killed ())
19015 info_ptr
->lr_save_p
= 1;
19017 using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
19018 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
19019 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
19020 info_ptr
->savres_strategy
= rs6000_savres_strategy (info_ptr
,
19021 using_static_chain_p
);
19023 if (!(info_ptr
->savres_strategy
& SAVE_INLINE_GPRS
)
19024 || !(info_ptr
->savres_strategy
& SAVE_INLINE_FPRS
)
19025 || !(info_ptr
->savres_strategy
& REST_INLINE_GPRS
)
19026 || !(info_ptr
->savres_strategy
& REST_INLINE_FPRS
))
19027 info_ptr
->lr_save_p
= 1;
19029 if (info_ptr
->lr_save_p
)
19030 df_set_regs_ever_live (LR_REGNO
, true);
19032 /* Determine if we need to allocate any stack frame:
19034 For AIX we need to push the stack if a frame pointer is needed
19035 (because the stack might be dynamically adjusted), if we are
19036 debugging, if we make calls, or if the sum of fp_save, gp_save,
19037 and local variables are more than the space needed to save all
19038 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19039 + 18*8 = 288 (GPR13 reserved).
19041 For V.4 we don't have the stack cushion that AIX uses, but assume
19042 that the debugger can handle stackless frames. */
19044 if (info_ptr
->calls_p
)
19045 info_ptr
->push_p
= 1;
19047 else if (DEFAULT_ABI
== ABI_V4
)
19048 info_ptr
->push_p
= non_fixed_size
!= 0;
19050 else if (frame_pointer_needed
)
19051 info_ptr
->push_p
= 1;
19053 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
19054 info_ptr
->push_p
= 1;
19057 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
19059 /* Zero offsets if we're not saving those registers. */
19060 if (info_ptr
->fp_size
== 0)
19061 info_ptr
->fp_save_offset
= 0;
19063 if (info_ptr
->gp_size
== 0)
19064 info_ptr
->gp_save_offset
= 0;
19066 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
19067 info_ptr
->altivec_save_offset
= 0;
19069 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
19070 info_ptr
->vrsave_save_offset
= 0;
19072 if (! TARGET_SPE_ABI
19073 || info_ptr
->spe_64bit_regs_used
== 0
19074 || info_ptr
->spe_gp_size
== 0)
19075 info_ptr
->spe_gp_save_offset
= 0;
19077 if (! info_ptr
->lr_save_p
)
19078 info_ptr
->lr_save_offset
= 0;
19080 if (! info_ptr
->cr_save_p
)
19081 info_ptr
->cr_save_offset
= 0;
19083 #ifdef ENABLE_CHECKING
19084 gcc_assert (!(reload_completed
&& info_save
.reload_completed
)
19085 || memcmp (&info_save
, &stack_info
, sizeof stack_info
) == 0);
19090 /* Return true if the current function uses any GPRs in 64-bit SIMD
19094 spe_func_has_64bit_regs_p (void)
19098 /* Functions that save and restore all the call-saved registers will
19099 need to save/restore the registers in 64-bits. */
19100 if (crtl
->calls_eh_return
19101 || cfun
->calls_setjmp
19102 || crtl
->has_nonlocal_goto
)
19105 insns
= get_insns ();
19107 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
19113 /* FIXME: This should be implemented with attributes...
19115 (set_attr "spe64" "true")....then,
19116 if (get_spe64(insn)) return true;
19118 It's the only reliable way to do the stuff below. */
19120 i
= PATTERN (insn
);
19121 if (GET_CODE (i
) == SET
)
19123 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
19125 if (SPE_VECTOR_MODE (mode
))
19127 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
19137 debug_stack_info (rs6000_stack_t
*info
)
19139 const char *abi_string
;
19142 info
= rs6000_stack_info ();
19144 fprintf (stderr
, "\nStack information for function %s:\n",
19145 ((current_function_decl
&& DECL_NAME (current_function_decl
))
19146 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
19151 default: abi_string
= "Unknown"; break;
19152 case ABI_NONE
: abi_string
= "NONE"; break;
19153 case ABI_AIX
: abi_string
= "AIX"; break;
19154 case ABI_DARWIN
: abi_string
= "Darwin"; break;
19155 case ABI_V4
: abi_string
= "V.4"; break;
19158 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
19160 if (TARGET_ALTIVEC_ABI
)
19161 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
19163 if (TARGET_SPE_ABI
)
19164 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
19166 if (info
->first_gp_reg_save
!= 32)
19167 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
19169 if (info
->first_fp_reg_save
!= 64)
19170 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
19172 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
19173 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
19174 info
->first_altivec_reg_save
);
19176 if (info
->lr_save_p
)
19177 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
19179 if (info
->cr_save_p
)
19180 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
19182 if (info
->vrsave_mask
)
19183 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
19186 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
19189 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
19191 if (info
->gp_save_offset
)
19192 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
19194 if (info
->fp_save_offset
)
19195 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
19197 if (info
->altivec_save_offset
)
19198 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
19199 info
->altivec_save_offset
);
19201 if (info
->spe_gp_save_offset
)
19202 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
19203 info
->spe_gp_save_offset
);
19205 if (info
->vrsave_save_offset
)
19206 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
19207 info
->vrsave_save_offset
);
19209 if (info
->lr_save_offset
)
19210 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
19212 if (info
->cr_save_offset
)
19213 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
19215 if (info
->varargs_save_offset
)
19216 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
19218 if (info
->total_size
)
19219 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
19222 if (info
->vars_size
)
19223 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
19226 if (info
->parm_size
)
19227 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
19229 if (info
->fixed_size
)
19230 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
19233 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
19235 if (info
->spe_gp_size
)
19236 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
19239 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
19241 if (info
->altivec_size
)
19242 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
19244 if (info
->vrsave_size
)
19245 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
19247 if (info
->altivec_padding_size
)
19248 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
19249 info
->altivec_padding_size
);
19251 if (info
->spe_padding_size
)
19252 fprintf (stderr
, "\tspe_padding_size = %5d\n",
19253 info
->spe_padding_size
);
19256 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
19258 if (info
->save_size
)
19259 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
19261 if (info
->reg_size
!= 4)
19262 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
19264 fprintf (stderr
, "\n");
19268 rs6000_return_addr (int count
, rtx frame
)
19270 /* Currently we don't optimize very well between prolog and body
19271 code and for PIC code the code can be actually quite bad, so
19272 don't try to be too clever here. */
19273 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
19275 cfun
->machine
->ra_needs_full_frame
= 1;
19282 plus_constant (copy_to_reg
19283 (gen_rtx_MEM (Pmode
,
19284 memory_address (Pmode
, frame
))),
19285 RETURN_ADDRESS_OFFSET
)));
19288 cfun
->machine
->ra_need_lr
= 1;
19289 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
19292 /* Say whether a function is a candidate for sibcall handling or not.
19293 We do not allow indirect calls to be optimized into sibling calls.
19294 Also, we can't do it if there are any vector parameters; there's
19295 nowhere to put the VRsave code so it works; note that functions with
19296 vector parameters are required to have a prototype, so the argument
19297 type info must be available here. (The tail recursion case can work
19298 with vector parameters, but there's no way to distinguish here.) */
19300 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
19305 if (TARGET_ALTIVEC_VRSAVE
)
19307 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
19308 type
; type
= TREE_CHAIN (type
))
19310 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
19314 if (DEFAULT_ABI
== ABI_DARWIN
19315 || ((*targetm
.binds_local_p
) (decl
)
19316 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
19318 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
19320 if (!lookup_attribute ("longcall", attr_list
)
19321 || lookup_attribute ("shortcall", attr_list
))
19328 /* NULL if INSN insn is valid within a low-overhead loop.
19329 Otherwise return why doloop cannot be applied.
19330 PowerPC uses the COUNT register for branch on table instructions. */
19332 static const char *
19333 rs6000_invalid_within_doloop (const_rtx insn
)
19336 return "Function call in the loop.";
19339 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
19340 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
19341 return "Computed branch in the loop.";
19347 rs6000_ra_ever_killed (void)
19353 if (cfun
->is_thunk
)
19356 if (cfun
->machine
->lr_save_state
)
19357 return cfun
->machine
->lr_save_state
- 1;
19359 /* regs_ever_live has LR marked as used if any sibcalls are present,
19360 but this should not force saving and restoring in the
19361 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19362 clobbers LR, so that is inappropriate. */
19364 /* Also, the prologue can generate a store into LR that
19365 doesn't really count, like this:
19368 bcl to set PIC register
19372 When we're called from the epilogue, we need to avoid counting
19373 this as a store. */
19375 push_topmost_sequence ();
19376 top
= get_insns ();
19377 pop_topmost_sequence ();
19378 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
19380 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
19386 if (!SIBLING_CALL_P (insn
))
19389 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
19391 else if (set_of (reg
, insn
) != NULL_RTX
19392 && !prologue_epilogue_contains (insn
))
19399 /* Emit instructions needed to load the TOC register.
19400 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19401 a constant pool; or for SVR4 -fpic. */
19404 rs6000_emit_load_toc_table (int fromprolog
)
19407 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
19409 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
19412 rtx lab
, tmp1
, tmp2
, got
;
19414 lab
= gen_label_rtx ();
19415 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (lab
));
19416 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19418 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
19420 got
= rs6000_got_sym ();
19421 tmp1
= tmp2
= dest
;
19424 tmp1
= gen_reg_rtx (Pmode
);
19425 tmp2
= gen_reg_rtx (Pmode
);
19427 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
19428 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
19429 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
19430 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
19432 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
19434 emit_insn (gen_load_toc_v4_pic_si ());
19435 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19437 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
19440 rtx temp0
= (fromprolog
19441 ? gen_rtx_REG (Pmode
, 0)
19442 : gen_reg_rtx (Pmode
));
19448 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
19449 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19451 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
19452 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19454 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
19455 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19456 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
19462 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
19463 lab
= gen_label_rtx ();
19464 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
, lab
));
19465 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19466 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
19468 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
19470 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
19472 /* This is for AIX code running in non-PIC ELF32. */
19475 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
19476 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19478 emit_insn (gen_elf_high (dest
, realsym
));
19479 emit_insn (gen_elf_low (dest
, dest
, realsym
));
19483 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
19486 emit_insn (gen_load_toc_aix_si (dest
));
19488 emit_insn (gen_load_toc_aix_di (dest
));
19492 /* Emit instructions to restore the link register after determining where
19493 its value has been stored. */
19496 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
19498 rs6000_stack_t
*info
= rs6000_stack_info ();
19501 operands
[0] = source
;
19502 operands
[1] = scratch
;
19504 if (info
->lr_save_p
)
19506 rtx frame_rtx
= stack_pointer_rtx
;
19507 HOST_WIDE_INT sp_offset
= 0;
19510 if (frame_pointer_needed
19511 || cfun
->calls_alloca
19512 || info
->total_size
> 32767)
19514 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
19515 emit_move_insn (operands
[1], tmp
);
19516 frame_rtx
= operands
[1];
19518 else if (info
->push_p
)
19519 sp_offset
= info
->total_size
;
19521 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
19522 tmp
= gen_frame_mem (Pmode
, tmp
);
19523 emit_move_insn (tmp
, operands
[0]);
19526 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
19528 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19529 state of lr_save_p so any change from here on would be a bug. In
19530 particular, stop rs6000_ra_ever_killed from considering the SET
19531 of lr we may have added just above. */
19532 cfun
->machine
->lr_save_state
= info
->lr_save_p
+ 1;
19535 static GTY(()) alias_set_type set
= -1;
19538 get_TOC_alias_set (void)
19541 set
= new_alias_set ();
19545 /* This returns nonzero if the current function uses the TOC. This is
19546 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19547 is generated by the ABI_V4 load_toc_* patterns. */
19554 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
19557 rtx pat
= PATTERN (insn
);
19560 if (GET_CODE (pat
) == PARALLEL
)
19561 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19563 rtx sub
= XVECEXP (pat
, 0, i
);
19564 if (GET_CODE (sub
) == USE
)
19566 sub
= XEXP (sub
, 0);
19567 if (GET_CODE (sub
) == UNSPEC
19568 && XINT (sub
, 1) == UNSPEC_TOC
)
19578 create_TOC_reference (rtx symbol
, rtx largetoc_reg
)
19580 rtx tocrel
, tocreg
;
19582 if (TARGET_DEBUG_ADDR
)
19584 if (GET_CODE (symbol
) == SYMBOL_REF
)
19585 fprintf (stderr
, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19589 fprintf (stderr
, "\ncreate_TOC_reference, code %s:\n",
19590 GET_RTX_NAME (GET_CODE (symbol
)));
19591 debug_rtx (symbol
);
19595 if (!can_create_pseudo_p ())
19596 df_set_regs_ever_live (TOC_REGISTER
, true);
19598 tocrel
= gen_rtx_CONST (Pmode
,
19599 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
),
19601 tocreg
= gen_rtx_REG (Pmode
, TOC_REGISTER
);
19602 if (TARGET_CMODEL
!= CMODEL_SMALL
)
19604 rtx hi
= gen_rtx_PLUS (Pmode
, tocreg
, gen_rtx_HIGH (Pmode
, tocrel
));
19605 if (largetoc_reg
!= NULL
)
19607 emit_move_insn (largetoc_reg
, hi
);
19610 return gen_rtx_LO_SUM (Pmode
, hi
, copy_rtx (tocrel
));
19613 return gen_rtx_PLUS (Pmode
, tocreg
, tocrel
);
19616 /* Issue assembly directives that create a reference to the given DWARF
19617 FRAME_TABLE_LABEL from the current function section. */
19619 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label
)
19621 fprintf (asm_out_file
, "\t.ref %s\n",
19622 TARGET_STRIP_NAME_ENCODING (frame_table_label
));
19625 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19626 and the change to the stack pointer. */
19629 rs6000_emit_stack_tie (void)
19631 rtx mem
= gen_frame_mem (BLKmode
,
19632 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
19634 emit_insn (gen_stack_tie (mem
));
19637 /* Emit the correct code for allocating stack space, as insns.
19638 If COPY_REG, make sure a copy of the old frame is left there.
19639 The generated code may use hard register 0 as a temporary. */
19642 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, rtx copy_reg
)
19645 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19646 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
19647 rtx todec
= gen_int_mode (-size
, Pmode
);
19650 if (INTVAL (todec
) != -size
)
19652 warning (0, "stack frame too large");
19653 emit_insn (gen_trap ());
19657 if (crtl
->limit_stack
)
19659 if (REG_P (stack_limit_rtx
)
19660 && REGNO (stack_limit_rtx
) > 1
19661 && REGNO (stack_limit_rtx
) <= 31)
19663 emit_insn (gen_add3_insn (tmp_reg
, stack_limit_rtx
, GEN_INT (size
)));
19664 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19667 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
19669 && DEFAULT_ABI
== ABI_V4
)
19671 rtx toload
= gen_rtx_CONST (VOIDmode
,
19672 gen_rtx_PLUS (Pmode
,
19676 emit_insn (gen_elf_high (tmp_reg
, toload
));
19677 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
19678 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19682 warning (0, "stack limit expression is not supported");
19686 emit_move_insn (copy_reg
, stack_reg
);
19690 /* Need a note here so that try_split doesn't get confused. */
19691 if (get_last_insn () == NULL_RTX
)
19692 emit_note (NOTE_INSN_DELETED
);
19693 insn
= emit_move_insn (tmp_reg
, todec
);
19694 try_split (PATTERN (insn
), insn
, 0);
19698 insn
= emit_insn (TARGET_32BIT
19699 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
19701 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
19702 todec
, stack_reg
));
19703 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19704 it now and set the alias set/attributes. The above gen_*_update
19705 calls will generate a PARALLEL with the MEM set being the first
19707 par
= PATTERN (insn
);
19708 gcc_assert (GET_CODE (par
) == PARALLEL
);
19709 set
= XVECEXP (par
, 0, 0);
19710 gcc_assert (GET_CODE (set
) == SET
);
19711 mem
= SET_DEST (set
);
19712 gcc_assert (MEM_P (mem
));
19713 MEM_NOTRAP_P (mem
) = 1;
19714 set_mem_alias_set (mem
, get_frame_alias_set ());
19716 RTX_FRAME_RELATED_P (insn
) = 1;
19717 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
19718 gen_rtx_SET (VOIDmode
, stack_reg
,
19719 gen_rtx_PLUS (Pmode
, stack_reg
,
19720 GEN_INT (-size
))));
19723 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19725 #if PROBE_INTERVAL > 32768
19726 #error Cannot use indexed addressing mode for stack probing
19729 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19730 inclusive. These are offsets from the current stack pointer. */
19733 rs6000_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
19735 /* See if we have a constant small number of probes to generate. If so,
19736 that's the easy case. */
19737 if (first
+ size
<= 32768)
19741 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19742 it exceeds SIZE. If only one probe is needed, this will not
19743 generate any code. Then probe at FIRST + SIZE. */
19744 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
19745 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ i
)));
19747 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ size
)));
19750 /* Otherwise, do the same as above, but in a loop. Note that we must be
19751 extra careful with variables wrapping around because we might be at
19752 the very top (or the very bottom) of the address space and we have
19753 to be able to handle this case properly; in particular, we use an
19754 equality test for the loop condition. */
19757 HOST_WIDE_INT rounded_size
;
19758 rtx r12
= gen_rtx_REG (Pmode
, 12);
19759 rtx r0
= gen_rtx_REG (Pmode
, 0);
19761 /* Sanity check for the addressing mode we're going to use. */
19762 gcc_assert (first
<= 32768);
19764 /* Step 1: round SIZE to the previous multiple of the interval. */
19766 rounded_size
= size
& -PROBE_INTERVAL
;
19769 /* Step 2: compute initial and final value of the loop counter. */
19771 /* TEST_ADDR = SP + FIRST. */
19772 emit_insn (gen_rtx_SET (VOIDmode
, r12
,
19773 plus_constant (stack_pointer_rtx
, -first
)));
19775 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19776 if (rounded_size
> 32768)
19778 emit_move_insn (r0
, GEN_INT (-rounded_size
));
19779 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19780 gen_rtx_PLUS (Pmode
, r12
, r0
)));
19783 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19784 plus_constant (r12
, -rounded_size
)));
19787 /* Step 3: the loop
19789 while (TEST_ADDR != LAST_ADDR)
19791 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19795 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19796 until it is equal to ROUNDED_SIZE. */
19799 emit_insn (gen_probe_stack_rangedi (r12
, r12
, r0
));
19801 emit_insn (gen_probe_stack_rangesi (r12
, r12
, r0
));
19804 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19805 that SIZE is equal to ROUNDED_SIZE. */
19807 if (size
!= rounded_size
)
19808 emit_stack_probe (plus_constant (r12
, rounded_size
- size
));
19812 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19813 absolute addresses. */
19816 output_probe_stack_range (rtx reg1
, rtx reg2
)
19818 static int labelno
= 0;
19819 char loop_lab
[32], end_lab
[32];
19822 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
);
19823 ASM_GENERATE_INTERNAL_LABEL (end_lab
, "LPSRE", labelno
++);
19825 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
19827 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19831 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops
);
19833 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops
);
19835 fputs ("\tbeq 0,", asm_out_file
);
19836 assemble_name_raw (asm_out_file
, end_lab
);
19837 fputc ('\n', asm_out_file
);
19839 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19840 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
19841 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops
);
19843 /* Probe at TEST_ADDR and branch. */
19844 output_asm_insn ("{st|stw} 0,0(%0)", xops
);
19845 fprintf (asm_out_file
, "\tb ");
19846 assemble_name_raw (asm_out_file
, loop_lab
);
19847 fputc ('\n', asm_out_file
);
19849 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, end_lab
);
19854 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19855 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19856 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19857 deduce these equivalences by itself so it wasn't necessary to hold
19858 its hand so much. */
19861 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
19862 rtx reg2
, rtx rreg
)
19866 /* copy_rtx will not make unique copies of registers, so we need to
19867 ensure we don't have unwanted sharing here. */
19869 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19872 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19874 real
= copy_rtx (PATTERN (insn
));
19876 if (reg2
!= NULL_RTX
)
19877 real
= replace_rtx (real
, reg2
, rreg
);
19879 real
= replace_rtx (real
, reg
,
19880 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
19881 STACK_POINTER_REGNUM
),
19884 /* We expect that 'real' is either a SET or a PARALLEL containing
19885 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19886 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19888 if (GET_CODE (real
) == SET
)
19892 temp
= simplify_rtx (SET_SRC (set
));
19894 SET_SRC (set
) = temp
;
19895 temp
= simplify_rtx (SET_DEST (set
));
19897 SET_DEST (set
) = temp
;
19898 if (GET_CODE (SET_DEST (set
)) == MEM
)
19900 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19902 XEXP (SET_DEST (set
), 0) = temp
;
19909 gcc_assert (GET_CODE (real
) == PARALLEL
);
19910 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
19911 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
19913 rtx set
= XVECEXP (real
, 0, i
);
19915 temp
= simplify_rtx (SET_SRC (set
));
19917 SET_SRC (set
) = temp
;
19918 temp
= simplify_rtx (SET_DEST (set
));
19920 SET_DEST (set
) = temp
;
19921 if (GET_CODE (SET_DEST (set
)) == MEM
)
19923 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19925 XEXP (SET_DEST (set
), 0) = temp
;
19927 RTX_FRAME_RELATED_P (set
) = 1;
19931 RTX_FRAME_RELATED_P (insn
) = 1;
19932 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
19935 /* Returns an insn that has a vrsave set operation with the
19936 appropriate CLOBBERs. */
19939 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
19942 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
19943 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
19946 = gen_rtx_SET (VOIDmode
,
19948 gen_rtx_UNSPEC_VOLATILE (SImode
,
19949 gen_rtvec (2, reg
, vrsave
),
19950 UNSPECV_SET_VRSAVE
));
19954 /* We need to clobber the registers in the mask so the scheduler
19955 does not move sets to VRSAVE before sets of AltiVec registers.
19957 However, if the function receives nonlocal gotos, reload will set
19958 all call saved registers live. We will end up with:
19960 (set (reg 999) (mem))
19961 (parallel [ (set (reg vrsave) (unspec blah))
19962 (clobber (reg 999))])
19964 The clobber will cause the store into reg 999 to be dead, and
19965 flow will attempt to delete an epilogue insn. In this case, we
19966 need an unspec use/set of the register. */
19968 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
19969 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
19971 if (!epiloguep
|| call_used_regs
[i
])
19972 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
19973 gen_rtx_REG (V4SImode
, i
));
19976 rtx reg
= gen_rtx_REG (V4SImode
, i
);
19979 = gen_rtx_SET (VOIDmode
,
19981 gen_rtx_UNSPEC (V4SImode
,
19982 gen_rtvec (1, reg
), 27));
19986 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
19988 for (i
= 0; i
< nclobs
; ++i
)
19989 XVECEXP (insn
, 0, i
) = clobs
[i
];
19994 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19995 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19998 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
19999 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
20001 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
20002 rtx replacea
, replaceb
;
20004 int_rtx
= GEN_INT (offset
);
20006 /* Some cases that need register indexed addressing. */
20007 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
20008 || (TARGET_VSX
&& VSX_VECTOR_MODE (mode
))
20009 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
20011 && SPE_VECTOR_MODE (mode
)
20012 && !SPE_CONST_OFFSET_OK (offset
)))
20014 /* Whomever calls us must make sure r11 is available in the
20015 flow path of instructions in the prologue. */
20016 offset_rtx
= gen_rtx_REG (Pmode
, 11);
20017 emit_move_insn (offset_rtx
, int_rtx
);
20019 replacea
= offset_rtx
;
20020 replaceb
= int_rtx
;
20024 offset_rtx
= int_rtx
;
20025 replacea
= NULL_RTX
;
20026 replaceb
= NULL_RTX
;
20029 reg
= gen_rtx_REG (mode
, regno
);
20030 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
20031 mem
= gen_frame_mem (mode
, addr
);
20033 insn
= emit_move_insn (mem
, reg
);
20035 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
20038 /* Emit an offset memory reference suitable for a frame store, while
20039 converting to a valid addressing mode. */
20042 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
20044 rtx int_rtx
, offset_rtx
;
20046 int_rtx
= GEN_INT (offset
);
20048 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
20049 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
20051 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
20052 emit_move_insn (offset_rtx
, int_rtx
);
20055 offset_rtx
= int_rtx
;
20057 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
20060 /* Look for user-defined global regs. We should not save and restore these,
20061 and cannot use stmw/lmw if there are any in its range. */
20064 no_global_regs_above (int first
, bool gpr
)
20067 int last
= gpr
? 32 : 64;
20068 for (i
= first
; i
< last
; i
++)
20069 if (global_regs
[i
])
20074 #ifndef TARGET_FIX_AND_CONTINUE
20075 #define TARGET_FIX_AND_CONTINUE 0
20078 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20079 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20080 #define LAST_SAVRES_REGISTER 31
20081 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20083 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
20085 /* Temporary holding space for an out-of-line register save/restore
20087 static char savres_routine_name
[30];
20089 /* Return the name for an out-of-line register save/restore routine.
20090 We are saving/restoring GPRs if GPR is true. */
20093 rs6000_savres_routine_name (rs6000_stack_t
*info
, int regno
,
20094 bool savep
, bool gpr
, bool lr
)
20096 const char *prefix
= "";
20097 const char *suffix
= "";
20099 /* Different targets are supposed to define
20100 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20101 routine name could be defined with:
20103 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20105 This is a nice idea in practice, but in reality, things are
20106 complicated in several ways:
20108 - ELF targets have save/restore routines for GPRs.
20110 - SPE targets use different prefixes for 32/64-bit registers, and
20111 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20113 - PPC64 ELF targets have routines for save/restore of GPRs that
20114 differ in what they do with the link register, so having a set
20115 prefix doesn't work. (We only use one of the save routines at
20116 the moment, though.)
20118 - PPC32 elf targets have "exit" versions of the restore routines
20119 that restore the link register and can save some extra space.
20120 These require an extra suffix. (There are also "tail" versions
20121 of the restore routines and "GOT" versions of the save routines,
20122 but we don't generate those at present. Same problems apply,
20125 We deal with all this by synthesizing our own prefix/suffix and
20126 using that for the simple sprintf call shown above. */
20129 /* No floating point saves on the SPE. */
20133 prefix
= info
->spe_64bit_regs_used
? "_save64gpr_" : "_save32gpr_";
20135 prefix
= info
->spe_64bit_regs_used
? "_rest64gpr_" : "_rest32gpr_";
20140 else if (DEFAULT_ABI
== ABI_V4
)
20146 prefix
= savep
? "_savegpr_" : "_restgpr_";
20148 prefix
= savep
? "_savefpr_" : "_restfpr_";
20153 else if (DEFAULT_ABI
== ABI_AIX
)
20155 #ifndef POWERPC_LINUX
20156 /* No out-of-line save/restore routines for GPRs on AIX. */
20157 gcc_assert (!TARGET_AIX
|| !gpr
);
20163 ? (lr
? "_savegpr0_" : "_savegpr1_")
20164 : (lr
? "_restgpr0_" : "_restgpr1_"));
20165 #ifdef POWERPC_LINUX
20167 prefix
= (savep
? "_savefpr_" : "_restfpr_");
20171 prefix
= savep
? SAVE_FP_PREFIX
: RESTORE_FP_PREFIX
;
20172 suffix
= savep
? SAVE_FP_SUFFIX
: RESTORE_FP_SUFFIX
;
20175 else if (DEFAULT_ABI
== ABI_DARWIN
)
20176 sorry ("out-of-line save/restore routines not supported on Darwin");
20178 sprintf (savres_routine_name
, "%s%d%s", prefix
, regno
, suffix
);
20180 return savres_routine_name
;
20183 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20184 We are saving/restoring GPRs if GPR is true. */
20187 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
,
20190 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
20192 int select
= ((savep
? 1 : 0) << 2
20194 /* On the SPE, we never have any FPRs, but we do have
20195 32/64-bit versions of the routines. */
20196 ? (info
->spe_64bit_regs_used
? 1 : 0)
20197 : (gpr
? 1 : 0)) << 1)
20200 /* Don't generate bogus routine names. */
20201 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
20202 && regno
<= LAST_SAVRES_REGISTER
);
20204 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
20210 name
= rs6000_savres_routine_name (info
, regno
, savep
, gpr
, lr
);
20212 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
20213 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
20214 SYMBOL_REF_FLAGS (sym
) |= SYMBOL_FLAG_FUNCTION
;
20220 /* Emit a sequence of insns, including a stack tie if needed, for
20221 resetting the stack pointer. If SAVRES is true, then don't reset the
20222 stack pointer, but move the base of the frame into r11 for use by
20223 out-of-line register restore routines. */
20226 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
20227 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
20228 int sp_offset
, bool savres
)
20230 /* This blockage is needed so that sched doesn't decide to move
20231 the sp change before the register restores. */
20232 if (frame_reg_rtx
!= sp_reg_rtx
20234 && info
->spe_64bit_regs_used
!= 0
20235 && info
->first_gp_reg_save
!= 32))
20236 rs6000_emit_stack_tie ();
20238 if (frame_reg_rtx
!= sp_reg_rtx
)
20240 if (sp_offset
!= 0)
20242 rtx dest_reg
= savres
? gen_rtx_REG (Pmode
, 11) : sp_reg_rtx
;
20243 return emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
,
20244 GEN_INT (sp_offset
)));
20247 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
20249 else if (sp_offset
!= 0)
20251 /* If we are restoring registers out-of-line, we will be using the
20252 "exit" variants of the restore routines, which will reset the
20253 stack for us. But we do need to point r11 into the right place
20254 for those routines. */
20255 rtx dest_reg
= (savres
20256 ? gen_rtx_REG (Pmode
, 11)
20259 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
20260 GEN_INT (sp_offset
)));
20267 /* Construct a parallel rtx describing the effect of a call to an
20268 out-of-line register save/restore routine. */
20271 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
20272 rtx frame_reg_rtx
, int save_area_offset
,
20273 enum machine_mode reg_mode
,
20274 bool savep
, bool gpr
, bool lr
)
20277 int offset
, start_reg
, end_reg
, n_regs
;
20278 int reg_size
= GET_MODE_SIZE (reg_mode
);
20284 ? info
->first_gp_reg_save
20285 : info
->first_fp_reg_save
);
20286 end_reg
= gpr
? 32 : 64;
20287 n_regs
= end_reg
- start_reg
;
20288 p
= rtvec_alloc ((lr
? 4 : 3) + n_regs
);
20291 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
20293 RTVEC_ELT (p
, offset
++)
20294 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
20296 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, lr
);
20297 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
20298 RTVEC_ELT (p
, offset
++)
20299 = gen_rtx_USE (VOIDmode
,
20300 gen_rtx_REG (Pmode
, DEFAULT_ABI
!= ABI_AIX
? 11
20304 for (i
= 0; i
< end_reg
- start_reg
; i
++)
20306 rtx addr
, reg
, mem
;
20307 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
20308 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20309 GEN_INT (save_area_offset
+ reg_size
*i
));
20310 mem
= gen_frame_mem (reg_mode
, addr
);
20312 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
20314 savep
? reg
: mem
);
20319 rtx addr
, reg
, mem
;
20320 reg
= gen_rtx_REG (Pmode
, 0);
20321 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20322 GEN_INT (info
->lr_save_offset
));
20323 mem
= gen_frame_mem (Pmode
, addr
);
20324 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20327 return gen_rtx_PARALLEL (VOIDmode
, p
);
20330 /* Determine whether the gp REG is really used. */
20333 rs6000_reg_live_or_pic_offset_p (int reg
)
20335 /* If the function calls eh_return, claim used all the registers that would
20336 be checked for liveness otherwise. This is required for the PIC offset
20337 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20338 register allocation purposes in this case. */
20340 return (((crtl
->calls_eh_return
|| df_regs_ever_live_p (reg
))
20341 && (!call_used_regs
[reg
]
20342 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
20343 && !TARGET_SINGLE_PIC_BASE
20344 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
20345 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
20346 && !TARGET_SINGLE_PIC_BASE
20347 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
20348 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
20351 /* Emit function prologue as insns. */
20354 rs6000_emit_prologue (void)
20356 rs6000_stack_t
*info
= rs6000_stack_info ();
20357 enum machine_mode reg_mode
= Pmode
;
20358 int reg_size
= TARGET_32BIT
? 4 : 8;
20359 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
20360 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
20361 rtx frame_reg_rtx
= sp_reg_rtx
;
20362 rtx cr_save_rtx
= NULL_RTX
;
20365 int saving_FPRs_inline
;
20366 int saving_GPRs_inline
;
20367 int using_store_multiple
;
20368 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
20369 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
20370 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
20371 HOST_WIDE_INT sp_offset
= 0;
20373 if (flag_stack_usage
)
20374 current_function_static_stack_size
= info
->total_size
;
20376 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
&& info
->total_size
)
20377 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT
, info
->total_size
);
20379 if (TARGET_FIX_AND_CONTINUE
)
20381 /* gdb on darwin arranges to forward a function from the old
20382 address by modifying the first 5 instructions of the function
20383 to branch to the overriding function. This is necessary to
20384 permit function pointers that point to the old function to
20385 actually forward to the new function. */
20386 emit_insn (gen_nop ());
20387 emit_insn (gen_nop ());
20388 emit_insn (gen_nop ());
20389 emit_insn (gen_nop ());
20390 emit_insn (gen_nop ());
20393 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
20395 reg_mode
= V2SImode
;
20399 strategy
= info
->savres_strategy
;
20400 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
20401 saving_FPRs_inline
= strategy
& SAVE_INLINE_FPRS
;
20402 saving_GPRs_inline
= strategy
& SAVE_INLINE_GPRS
;
20404 /* For V.4, update stack before we do any saving and set back pointer. */
20405 if (! WORLD_SAVE_P (info
)
20407 && (DEFAULT_ABI
== ABI_V4
20408 || crtl
->calls_eh_return
))
20410 bool need_r11
= (TARGET_SPE
20411 ? (!saving_GPRs_inline
20412 && info
->spe_64bit_regs_used
== 0)
20413 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
20414 rtx copy_reg
= need_r11
? gen_rtx_REG (Pmode
, 11) : NULL
;
20416 if (info
->total_size
< 32767)
20417 sp_offset
= info
->total_size
;
20419 frame_reg_rtx
= copy_reg
;
20420 else if (info
->cr_save_p
20422 || info
->first_fp_reg_save
< 64
20423 || info
->first_gp_reg_save
< 32
20424 || info
->altivec_size
!= 0
20425 || info
->vrsave_mask
!= 0
20426 || crtl
->calls_eh_return
)
20428 copy_reg
= frame_ptr_rtx
;
20429 frame_reg_rtx
= copy_reg
;
20433 /* The prologue won't be saving any regs so there is no need
20434 to set up a frame register to access any frame save area.
20435 We also won't be using sp_offset anywhere below, but set
20436 the correct value anyway to protect against future
20437 changes to this function. */
20438 sp_offset
= info
->total_size
;
20440 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20441 if (frame_reg_rtx
!= sp_reg_rtx
)
20442 rs6000_emit_stack_tie ();
20445 /* Handle world saves specially here. */
20446 if (WORLD_SAVE_P (info
))
20453 /* save_world expects lr in r0. */
20454 reg0
= gen_rtx_REG (Pmode
, 0);
20455 if (info
->lr_save_p
)
20457 insn
= emit_move_insn (reg0
,
20458 gen_rtx_REG (Pmode
, LR_REGNO
));
20459 RTX_FRAME_RELATED_P (insn
) = 1;
20462 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20463 assumptions about the offsets of various bits of the stack
20465 gcc_assert (info
->gp_save_offset
== -220
20466 && info
->fp_save_offset
== -144
20467 && info
->lr_save_offset
== 8
20468 && info
->cr_save_offset
== 4
20471 && (!crtl
->calls_eh_return
20472 || info
->ehrd_offset
== -432)
20473 && info
->vrsave_save_offset
== -224
20474 && info
->altivec_save_offset
== -416);
20476 treg
= gen_rtx_REG (SImode
, 11);
20477 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
20479 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20480 in R11. It also clobbers R12, so beware! */
20482 /* Preserve CR2 for save_world prologues */
20484 sz
+= 32 - info
->first_gp_reg_save
;
20485 sz
+= 64 - info
->first_fp_reg_save
;
20486 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
20487 p
= rtvec_alloc (sz
);
20489 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
20490 gen_rtx_REG (SImode
,
20492 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
20493 gen_rtx_SYMBOL_REF (Pmode
,
20495 /* We do floats first so that the instruction pattern matches
20497 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20499 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20500 ? DFmode
: SFmode
),
20501 info
->first_fp_reg_save
+ i
);
20502 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20503 GEN_INT (info
->fp_save_offset
20504 + sp_offset
+ 8 * i
));
20505 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20506 ? DFmode
: SFmode
), addr
);
20508 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20510 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
20512 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
20513 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20514 GEN_INT (info
->altivec_save_offset
20515 + sp_offset
+ 16 * i
));
20516 rtx mem
= gen_frame_mem (V4SImode
, addr
);
20518 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20520 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20522 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20523 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20524 GEN_INT (info
->gp_save_offset
20525 + sp_offset
+ reg_size
* i
));
20526 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20528 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20532 /* CR register traditionally saved as CR2. */
20533 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
20534 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20535 GEN_INT (info
->cr_save_offset
20537 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20539 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20541 /* Explain about use of R0. */
20542 if (info
->lr_save_p
)
20544 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20545 GEN_INT (info
->lr_save_offset
20547 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20549 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
20551 /* Explain what happens to the stack pointer. */
20553 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
20554 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
20557 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20558 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20559 treg
, GEN_INT (-info
->total_size
));
20560 sp_offset
= info
->total_size
;
20563 /* If we use the link register, get it into r0. */
20564 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
20566 rtx addr
, reg
, mem
;
20568 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
20569 gen_rtx_REG (Pmode
, LR_REGNO
));
20570 RTX_FRAME_RELATED_P (insn
) = 1;
20572 if (!(strategy
& (SAVE_NOINLINE_GPRS_SAVES_LR
20573 | SAVE_NOINLINE_FPRS_SAVES_LR
)))
20575 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20576 GEN_INT (info
->lr_save_offset
+ sp_offset
));
20577 reg
= gen_rtx_REG (Pmode
, 0);
20578 mem
= gen_rtx_MEM (Pmode
, addr
);
20579 /* This should not be of rs6000_sr_alias_set, because of
20580 __builtin_return_address. */
20582 insn
= emit_move_insn (mem
, reg
);
20583 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20584 NULL_RTX
, NULL_RTX
);
20588 /* If we need to save CR, put it into r12 or r11. */
20589 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
20594 = gen_rtx_REG (SImode
, DEFAULT_ABI
== ABI_AIX
&& !saving_GPRs_inline
20596 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20597 RTX_FRAME_RELATED_P (insn
) = 1;
20598 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20599 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20600 But that's OK. All we have to do is specify that _one_ condition
20601 code register is saved in this stack slot. The thrower's epilogue
20602 will then restore all the call-saved registers.
20603 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20604 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
20605 gen_rtx_REG (SImode
, CR2_REGNO
));
20606 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20609 /* Do any required saving of fpr's. If only one or two to save, do
20610 it ourselves. Otherwise, call function. */
20611 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
20614 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20615 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
20616 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
20617 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
20618 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20620 info
->first_fp_reg_save
+ i
,
20621 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
20624 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
20628 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20629 info
->fp_save_offset
+ sp_offset
,
20631 /*savep=*/true, /*gpr=*/false,
20633 & SAVE_NOINLINE_FPRS_SAVES_LR
)
20635 insn
= emit_insn (par
);
20636 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20637 NULL_RTX
, NULL_RTX
);
20640 /* Save GPRs. This is done as a PARALLEL if we are using
20641 the store-multiple instructions. */
20642 if (!WORLD_SAVE_P (info
)
20644 && info
->spe_64bit_regs_used
!= 0
20645 && info
->first_gp_reg_save
!= 32)
20648 rtx spe_save_area_ptr
;
20650 /* Determine whether we can address all of the registers that need
20651 to be saved with an offset from the stack pointer that fits in
20652 the small const field for SPE memory instructions. */
20653 int spe_regs_addressable_via_sp
20654 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
20655 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
20656 && saving_GPRs_inline
);
20659 if (spe_regs_addressable_via_sp
)
20661 spe_save_area_ptr
= frame_reg_rtx
;
20662 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
20666 /* Make r11 point to the start of the SPE save area. We need
20667 to be careful here if r11 is holding the static chain. If
20668 it is, then temporarily save it in r0. We would use r0 as
20669 our base register here, but using r0 as a base register in
20670 loads and stores means something different from what we
20672 int ool_adjust
= (saving_GPRs_inline
20674 : (info
->first_gp_reg_save
20675 - (FIRST_SAVRES_REGISTER
+1))*8);
20676 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
20677 + sp_offset
- ool_adjust
);
20679 if (using_static_chain_p
)
20681 rtx r0
= gen_rtx_REG (Pmode
, 0);
20682 gcc_assert (info
->first_gp_reg_save
> 11);
20684 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
20687 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
20688 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
20690 GEN_INT (offset
)));
20691 /* We need to make sure the move to r11 gets noted for
20692 properly outputting unwind information. */
20693 if (!saving_GPRs_inline
)
20694 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
20695 NULL_RTX
, NULL_RTX
);
20699 if (saving_GPRs_inline
)
20701 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20702 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20704 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20705 rtx offset
, addr
, mem
;
20707 /* We're doing all this to ensure that the offset fits into
20708 the immediate offset of 'evstdd'. */
20709 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
20711 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
20712 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
20713 mem
= gen_rtx_MEM (V2SImode
, addr
);
20715 insn
= emit_move_insn (mem
, reg
);
20717 rs6000_frame_related (insn
, spe_save_area_ptr
,
20718 info
->spe_gp_save_offset
20719 + sp_offset
+ reg_size
* i
,
20720 offset
, const0_rtx
);
20727 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
20729 /*savep=*/true, /*gpr=*/true,
20731 insn
= emit_insn (par
);
20732 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20733 NULL_RTX
, NULL_RTX
);
20737 /* Move the static chain pointer back. */
20738 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
20739 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
20741 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
20745 /* Need to adjust r11 (r12) if we saved any FPRs. */
20746 if (info
->first_fp_reg_save
!= 64)
20748 rtx dest_reg
= gen_rtx_REG (reg_mode
, DEFAULT_ABI
== ABI_AIX
20750 rtx offset
= GEN_INT (sp_offset
20751 + (-8 * (64-info
->first_fp_reg_save
)));
20752 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
20755 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20756 info
->gp_save_offset
+ sp_offset
,
20758 /*savep=*/true, /*gpr=*/true,
20760 & SAVE_NOINLINE_GPRS_SAVES_LR
)
20762 insn
= emit_insn (par
);
20763 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20764 NULL_RTX
, NULL_RTX
);
20766 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
20770 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
20771 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20773 rtx addr
, reg
, mem
;
20774 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20775 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20776 GEN_INT (info
->gp_save_offset
20779 mem
= gen_frame_mem (reg_mode
, addr
);
20781 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20783 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20784 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20785 NULL_RTX
, NULL_RTX
);
20787 else if (!WORLD_SAVE_P (info
))
20790 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20791 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20793 rtx addr
, reg
, mem
;
20794 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20796 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20797 GEN_INT (info
->gp_save_offset
20800 mem
= gen_frame_mem (reg_mode
, addr
);
20802 insn
= emit_move_insn (mem
, reg
);
20803 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20804 NULL_RTX
, NULL_RTX
);
20808 /* ??? There's no need to emit actual instructions here, but it's the
20809 easiest way to get the frame unwind information emitted. */
20810 if (crtl
->calls_eh_return
)
20812 unsigned int i
, regno
;
20816 regno
= EH_RETURN_DATA_REGNO (i
);
20817 if (regno
== INVALID_REGNUM
)
20820 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
20821 info
->ehrd_offset
+ sp_offset
20822 + reg_size
* (int) i
,
20827 /* In AIX ABI we need to make sure r2 is really saved. */
20828 if (TARGET_AIX
&& crtl
->calls_eh_return
)
20830 rtx tmp_reg
, tmp_reg_si
, hi
, lo
, compare_result
, toc_save_done
, jump
;
20831 long toc_restore_insn
;
20833 gcc_assert (frame_reg_rtx
== frame_ptr_rtx
20834 || frame_reg_rtx
== sp_reg_rtx
);
20835 tmp_reg
= gen_rtx_REG (Pmode
, 11);
20836 tmp_reg_si
= gen_rtx_REG (SImode
, 11);
20837 if (using_static_chain_p
)
20838 emit_move_insn (gen_rtx_REG (Pmode
, 0), tmp_reg
);
20839 gcc_assert (saving_GPRs_inline
&& saving_FPRs_inline
);
20840 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, LR_REGNO
));
20841 /* Peek at instruction to which this function returns. If it's
20842 restoring r2, then we know we've already saved r2. We can't
20843 unconditionally save r2 because the value we have will already
20844 be updated if we arrived at this function via a plt call or
20845 toc adjusting stub. */
20846 emit_move_insn (tmp_reg_si
, gen_rtx_MEM (SImode
, tmp_reg
));
20847 toc_restore_insn
= TARGET_32BIT
? 0x80410014 : 0xE8410028;
20848 hi
= gen_int_mode (toc_restore_insn
& ~0xffff, SImode
);
20849 emit_insn (gen_xorsi3 (tmp_reg_si
, tmp_reg_si
, hi
));
20850 compare_result
= gen_rtx_REG (CCUNSmode
, CR0_REGNO
);
20851 validate_condition_mode (EQ
, CCUNSmode
);
20852 lo
= gen_int_mode (toc_restore_insn
& 0xffff, SImode
);
20853 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
20854 gen_rtx_COMPARE (CCUNSmode
, tmp_reg_si
, lo
)));
20855 toc_save_done
= gen_label_rtx ();
20856 jump
= gen_rtx_IF_THEN_ELSE (VOIDmode
,
20857 gen_rtx_EQ (VOIDmode
, compare_result
,
20859 gen_rtx_LABEL_REF (VOIDmode
, toc_save_done
),
20861 jump
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, jump
));
20862 JUMP_LABEL (jump
) = toc_save_done
;
20863 LABEL_NUSES (toc_save_done
) += 1;
20865 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, 2,
20866 sp_offset
+ 5 * reg_size
, info
->total_size
);
20867 emit_label (toc_save_done
);
20868 if (using_static_chain_p
)
20869 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, 0));
20872 /* Save CR if we use any that must be preserved. */
20873 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
20875 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20876 GEN_INT (info
->cr_save_offset
+ sp_offset
));
20877 rtx mem
= gen_frame_mem (SImode
, addr
);
20878 /* See the large comment above about why CR2_REGNO is used. */
20879 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
20881 /* If r12 was used to hold the original sp, copy cr into r0 now
20883 if (REGNO (frame_reg_rtx
) == 12)
20887 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
20888 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20889 RTX_FRAME_RELATED_P (insn
) = 1;
20890 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
20891 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20893 insn
= emit_move_insn (mem
, cr_save_rtx
);
20895 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20896 NULL_RTX
, NULL_RTX
);
20899 /* Update stack and set back pointer unless this is V.4,
20900 for which it was done previously. */
20901 if (!WORLD_SAVE_P (info
) && info
->push_p
20902 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
20904 rtx copy_reg
= NULL
;
20906 if (info
->total_size
< 32767)
20907 sp_offset
= info
->total_size
;
20908 else if (info
->altivec_size
!= 0
20909 || info
->vrsave_mask
!= 0)
20911 copy_reg
= frame_ptr_rtx
;
20912 frame_reg_rtx
= copy_reg
;
20915 sp_offset
= info
->total_size
;
20916 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20917 if (frame_reg_rtx
!= sp_reg_rtx
)
20918 rs6000_emit_stack_tie ();
20921 /* Set frame pointer, if needed. */
20922 if (frame_pointer_needed
)
20924 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
20926 RTX_FRAME_RELATED_P (insn
) = 1;
20929 /* Save AltiVec registers if needed. Save here because the red zone does
20930 not include AltiVec registers. */
20931 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
20935 /* There should be a non inline version of this, for when we
20936 are saving lots of vector registers. */
20937 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20938 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20940 rtx areg
, savereg
, mem
;
20943 offset
= info
->altivec_save_offset
+ sp_offset
20944 + 16 * (i
- info
->first_altivec_reg_save
);
20946 savereg
= gen_rtx_REG (V4SImode
, i
);
20948 areg
= gen_rtx_REG (Pmode
, 0);
20949 emit_move_insn (areg
, GEN_INT (offset
));
20951 /* AltiVec addressing mode is [reg+reg]. */
20952 mem
= gen_frame_mem (V4SImode
,
20953 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
20955 insn
= emit_move_insn (mem
, savereg
);
20957 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20958 areg
, GEN_INT (offset
));
20962 /* VRSAVE is a bit vector representing which AltiVec registers
20963 are used. The OS uses this to determine which vector
20964 registers to save on a context switch. We need to save
20965 VRSAVE on the stack frame, add whatever AltiVec registers we
20966 used in this function, and do the corresponding magic in the
20969 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
20970 && info
->vrsave_mask
!= 0)
20972 rtx reg
, mem
, vrsave
;
20975 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20976 as frame_reg_rtx and r11 as the static chain pointer for
20977 nested functions. */
20978 reg
= gen_rtx_REG (SImode
, 0);
20979 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
20981 emit_insn (gen_get_vrsave_internal (reg
));
20983 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
20985 if (!WORLD_SAVE_P (info
))
20988 offset
= info
->vrsave_save_offset
+ sp_offset
;
20989 mem
= gen_frame_mem (SImode
,
20990 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20991 GEN_INT (offset
)));
20992 insn
= emit_move_insn (mem
, reg
);
20995 /* Include the registers in the mask. */
20996 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
20998 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
21001 if (TARGET_SINGLE_PIC_BASE
)
21002 return; /* Do not set PIC register */
21004 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
21005 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
21006 || (DEFAULT_ABI
== ABI_V4
21007 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
21008 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
21010 /* If emit_load_toc_table will use the link register, we need to save
21011 it. We use R12 for this purpose because emit_load_toc_table
21012 can use register 0. This allows us to use a plain 'blr' to return
21013 from the procedure more often. */
21014 int save_LR_around_toc_setup
= (TARGET_ELF
21015 && DEFAULT_ABI
!= ABI_AIX
21017 && ! info
->lr_save_p
21018 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
21019 if (save_LR_around_toc_setup
)
21021 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
21023 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
21024 RTX_FRAME_RELATED_P (insn
) = 1;
21026 rs6000_emit_load_toc_table (TRUE
);
21028 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
21029 RTX_FRAME_RELATED_P (insn
) = 1;
21032 rs6000_emit_load_toc_table (TRUE
);
21036 if (DEFAULT_ABI
== ABI_DARWIN
21037 && flag_pic
&& crtl
->uses_pic_offset_table
)
21039 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
21040 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
21042 /* Save and restore LR locally around this call (in R0). */
21043 if (!info
->lr_save_p
)
21044 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
21046 emit_insn (gen_load_macho_picbase (src
));
21048 emit_move_insn (gen_rtx_REG (Pmode
,
21049 RS6000_PIC_OFFSET_TABLE_REGNUM
),
21052 if (!info
->lr_save_p
)
21053 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
21058 /* Write function prologue. */
21061 rs6000_output_function_prologue (FILE *file
,
21062 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
21064 rs6000_stack_t
*info
= rs6000_stack_info ();
21066 if (TARGET_DEBUG_STACK
)
21067 debug_stack_info (info
);
21069 /* Write .extern for any function we will call to save and restore
21071 if (info
->first_fp_reg_save
< 64)
21074 int regno
= info
->first_fp_reg_save
- 32;
21076 if ((info
->savres_strategy
& SAVE_INLINE_FPRS
) == 0)
21078 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/true,
21079 /*gpr=*/false, /*lr=*/false);
21080 fprintf (file
, "\t.extern %s\n", name
);
21082 if ((info
->savres_strategy
& REST_INLINE_FPRS
) == 0)
21084 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/false,
21085 /*gpr=*/false, /*lr=*/true);
21086 fprintf (file
, "\t.extern %s\n", name
);
21090 /* Write .extern for AIX common mode routines, if needed. */
21091 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
21093 fputs ("\t.extern __mulh\n", file
);
21094 fputs ("\t.extern __mull\n", file
);
21095 fputs ("\t.extern __divss\n", file
);
21096 fputs ("\t.extern __divus\n", file
);
21097 fputs ("\t.extern __quoss\n", file
);
21098 fputs ("\t.extern __quous\n", file
);
21099 common_mode_defined
= 1;
21102 if (! HAVE_prologue
)
21108 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21109 the "toplevel" insn chain. */
21110 emit_note (NOTE_INSN_DELETED
);
21111 rs6000_emit_prologue ();
21112 emit_note (NOTE_INSN_DELETED
);
21114 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21118 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
21120 INSN_ADDRESSES_NEW (insn
, addr
);
21125 prologue
= get_insns ();
21128 if (TARGET_DEBUG_STACK
)
21129 debug_rtx_list (prologue
, 100);
21131 emit_insn_before_noloc (prologue
, BB_HEAD (ENTRY_BLOCK_PTR
->next_bb
),
21135 rs6000_pic_labelno
++;
21138 /* Non-zero if vmx regs are restored before the frame pop, zero if
21139 we restore after the pop when possible. */
21140 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21142 /* Reload CR from REG. */
21145 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
21150 if (using_mfcr_multiple
)
21152 for (i
= 0; i
< 8; i
++)
21153 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21155 gcc_assert (count
);
21158 if (using_mfcr_multiple
&& count
> 1)
21163 p
= rtvec_alloc (count
);
21166 for (i
= 0; i
< 8; i
++)
21167 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21169 rtvec r
= rtvec_alloc (2);
21170 RTVEC_ELT (r
, 0) = reg
;
21171 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
21172 RTVEC_ELT (p
, ndx
) =
21173 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
21174 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
21177 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21178 gcc_assert (ndx
== count
);
21181 for (i
= 0; i
< 8; i
++)
21182 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21184 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
21190 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21191 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21192 below stack pointer not cloberred by signals. */
21195 offset_below_red_zone_p (HOST_WIDE_INT offset
)
21197 return offset
< (DEFAULT_ABI
== ABI_V4
21199 : TARGET_32BIT
? -220 : -288);
21202 /* Emit function epilogue as insns. */
21205 rs6000_emit_epilogue (int sibcall
)
21207 rs6000_stack_t
*info
;
21208 int restoring_GPRs_inline
;
21209 int restoring_FPRs_inline
;
21210 int using_load_multiple
;
21211 int using_mtcr_multiple
;
21212 int use_backchain_to_restore_sp
;
21216 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
21217 rtx frame_reg_rtx
= sp_reg_rtx
;
21218 rtx cfa_restores
= NULL_RTX
;
21220 rtx cr_save_reg
= NULL_RTX
;
21221 enum machine_mode reg_mode
= Pmode
;
21222 int reg_size
= TARGET_32BIT
? 4 : 8;
21225 info
= rs6000_stack_info ();
21227 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
21229 reg_mode
= V2SImode
;
21233 strategy
= info
->savres_strategy
;
21234 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
21235 restoring_FPRs_inline
= sibcall
|| (strategy
& REST_INLINE_FPRS
);
21236 restoring_GPRs_inline
= sibcall
|| (strategy
& REST_INLINE_GPRS
);
21237 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
21238 || rs6000_cpu
== PROCESSOR_PPC603
21239 || rs6000_cpu
== PROCESSOR_PPC750
21241 /* Restore via the backchain when we have a large frame, since this
21242 is more efficient than an addis, addi pair. The second condition
21243 here will not trigger at the moment; We don't actually need a
21244 frame pointer for alloca, but the generic parts of the compiler
21245 give us one anyway. */
21246 use_backchain_to_restore_sp
= (info
->total_size
> 32767
21247 || info
->total_size
21248 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
21250 || (cfun
->calls_alloca
21251 && !frame_pointer_needed
));
21252 restore_lr
= (info
->lr_save_p
21253 && (restoring_FPRs_inline
21254 || (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
))
21255 && (restoring_GPRs_inline
21256 || info
->first_fp_reg_save
< 64));
21258 if (WORLD_SAVE_P (info
))
21262 const char *alloc_rname
;
21265 /* eh_rest_world_r10 will return to the location saved in the LR
21266 stack slot (which is not likely to be our caller.)
21267 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21268 rest_world is similar, except any R10 parameter is ignored.
21269 The exception-handling stuff that was here in 2.95 is no
21270 longer necessary. */
21274 + 32 - info
->first_gp_reg_save
21275 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
21276 + 63 + 1 - info
->first_fp_reg_save
);
21278 strcpy (rname
, ((crtl
->calls_eh_return
) ?
21279 "*eh_rest_world_r10" : "*rest_world"));
21280 alloc_rname
= ggc_strdup (rname
);
21283 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
21284 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
21285 gen_rtx_REG (Pmode
,
21288 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
21289 /* The instruction pattern requires a clobber here;
21290 it is shared with the restVEC helper. */
21292 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
21295 /* CR register traditionally saved as CR2. */
21296 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
21297 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21298 GEN_INT (info
->cr_save_offset
));
21299 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21301 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21304 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21306 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21307 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21308 GEN_INT (info
->gp_save_offset
21310 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21312 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21314 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
21316 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
21317 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21318 GEN_INT (info
->altivec_save_offset
21320 rtx mem
= gen_frame_mem (V4SImode
, addr
);
21322 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21324 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
21326 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21327 ? DFmode
: SFmode
),
21328 info
->first_fp_reg_save
+ i
);
21329 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21330 GEN_INT (info
->fp_save_offset
21332 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21333 ? DFmode
: SFmode
), addr
);
21335 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21338 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
21340 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
21342 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
21344 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
21346 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
21347 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21352 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21354 sp_offset
= info
->total_size
;
21356 /* Restore AltiVec registers if we must do so before adjusting the
21358 if (TARGET_ALTIVEC_ABI
21359 && info
->altivec_size
!= 0
21360 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21361 || (DEFAULT_ABI
!= ABI_V4
21362 && offset_below_red_zone_p (info
->altivec_save_offset
))))
21366 if (use_backchain_to_restore_sp
)
21368 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21369 emit_move_insn (frame_reg_rtx
,
21370 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21373 else if (frame_pointer_needed
)
21374 frame_reg_rtx
= hard_frame_pointer_rtx
;
21376 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21377 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21379 rtx addr
, areg
, mem
, reg
;
21381 areg
= gen_rtx_REG (Pmode
, 0);
21383 (areg
, GEN_INT (info
->altivec_save_offset
21385 + 16 * (i
- info
->first_altivec_reg_save
)));
21387 /* AltiVec addressing mode is [reg+reg]. */
21388 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
21389 mem
= gen_frame_mem (V4SImode
, addr
);
21391 reg
= gen_rtx_REG (V4SImode
, i
);
21392 emit_move_insn (reg
, mem
);
21393 if (offset_below_red_zone_p (info
->altivec_save_offset
21394 + (i
- info
->first_altivec_reg_save
)
21396 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21401 /* Restore VRSAVE if we must do so before adjusting the stack. */
21403 && TARGET_ALTIVEC_VRSAVE
21404 && info
->vrsave_mask
!= 0
21405 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21406 || (DEFAULT_ABI
!= ABI_V4
21407 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
21409 rtx addr
, mem
, reg
;
21411 if (frame_reg_rtx
== sp_reg_rtx
)
21413 if (use_backchain_to_restore_sp
)
21415 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21416 emit_move_insn (frame_reg_rtx
,
21417 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21420 else if (frame_pointer_needed
)
21421 frame_reg_rtx
= hard_frame_pointer_rtx
;
21424 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21425 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
21426 mem
= gen_frame_mem (SImode
, addr
);
21427 reg
= gen_rtx_REG (SImode
, 12);
21428 emit_move_insn (reg
, mem
);
21430 emit_insn (generate_set_vrsave (reg
, info
, 1));
21434 /* If we have a large stack frame, restore the old stack pointer
21435 using the backchain. */
21436 if (use_backchain_to_restore_sp
)
21438 if (frame_reg_rtx
== sp_reg_rtx
)
21440 /* Under V.4, don't reset the stack pointer until after we're done
21441 loading the saved registers. */
21442 if (DEFAULT_ABI
== ABI_V4
)
21443 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21445 insn
= emit_move_insn (frame_reg_rtx
,
21446 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21449 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21450 && DEFAULT_ABI
== ABI_V4
)
21451 /* frame_reg_rtx has been set up by the altivec restore. */
21455 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
21456 frame_reg_rtx
= sp_reg_rtx
;
21459 /* If we have a frame pointer, we can restore the old stack pointer
21461 else if (frame_pointer_needed
)
21463 frame_reg_rtx
= sp_reg_rtx
;
21464 if (DEFAULT_ABI
== ABI_V4
)
21465 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21466 /* Prevent reordering memory accesses against stack pointer restore. */
21467 else if (cfun
->calls_alloca
21468 || offset_below_red_zone_p (-info
->total_size
))
21470 rtx mem1
= gen_rtx_MEM (BLKmode
, hard_frame_pointer_rtx
);
21471 rtx mem2
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
21472 MEM_NOTRAP_P (mem1
) = 1;
21473 MEM_NOTRAP_P (mem2
) = 1;
21474 emit_insn (gen_frame_tie (mem1
, mem2
));
21477 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
21478 GEN_INT (info
->total_size
)));
21481 else if (info
->push_p
21482 && DEFAULT_ABI
!= ABI_V4
21483 && !crtl
->calls_eh_return
)
21485 /* Prevent reordering memory accesses against stack pointer restore. */
21486 if (cfun
->calls_alloca
21487 || offset_below_red_zone_p (-info
->total_size
))
21489 rtx mem
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
21490 MEM_NOTRAP_P (mem
) = 1;
21491 emit_insn (gen_stack_tie (mem
));
21493 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
21494 GEN_INT (info
->total_size
)));
21497 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
21501 REG_NOTES (insn
) = cfa_restores
;
21502 cfa_restores
= NULL_RTX
;
21504 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21505 RTX_FRAME_RELATED_P (insn
) = 1;
21508 /* Restore AltiVec registers if we have not done so already. */
21509 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21510 && TARGET_ALTIVEC_ABI
21511 && info
->altivec_size
!= 0
21512 && (DEFAULT_ABI
== ABI_V4
21513 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
21517 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21518 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21520 rtx addr
, areg
, mem
, reg
;
21522 areg
= gen_rtx_REG (Pmode
, 0);
21524 (areg
, GEN_INT (info
->altivec_save_offset
21526 + 16 * (i
- info
->first_altivec_reg_save
)));
21528 /* AltiVec addressing mode is [reg+reg]. */
21529 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
21530 mem
= gen_frame_mem (V4SImode
, addr
);
21532 reg
= gen_rtx_REG (V4SImode
, i
);
21533 emit_move_insn (reg
, mem
);
21534 if (DEFAULT_ABI
== ABI_V4
)
21535 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21540 /* Restore VRSAVE if we have not done so already. */
21541 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21543 && TARGET_ALTIVEC_VRSAVE
21544 && info
->vrsave_mask
!= 0
21545 && (DEFAULT_ABI
== ABI_V4
21546 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
21548 rtx addr
, mem
, reg
;
21550 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21551 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
21552 mem
= gen_frame_mem (SImode
, addr
);
21553 reg
= gen_rtx_REG (SImode
, 12);
21554 emit_move_insn (reg
, mem
);
21556 emit_insn (generate_set_vrsave (reg
, info
, 1));
21559 /* Get the old lr if we saved it. If we are restoring registers
21560 out-of-line, then the out-of-line routines can do this for us. */
21561 if (restore_lr
&& restoring_GPRs_inline
)
21563 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21564 info
->lr_save_offset
+ sp_offset
);
21566 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21569 /* Get the old cr if we saved it. */
21570 if (info
->cr_save_p
)
21572 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21573 GEN_INT (info
->cr_save_offset
+ sp_offset
));
21574 rtx mem
= gen_frame_mem (SImode
, addr
);
21576 cr_save_reg
= gen_rtx_REG (SImode
,
21577 DEFAULT_ABI
== ABI_AIX
21578 && !restoring_GPRs_inline
21579 && info
->first_fp_reg_save
< 64
21581 emit_move_insn (cr_save_reg
, mem
);
21584 /* Set LR here to try to overlap restores below. LR is always saved
21585 above incoming stack, so it never needs REG_CFA_RESTORE. */
21586 if (restore_lr
&& restoring_GPRs_inline
)
21587 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21588 gen_rtx_REG (Pmode
, 0));
21590 /* Load exception handler data registers, if needed. */
21591 if (crtl
->calls_eh_return
)
21593 unsigned int i
, regno
;
21597 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21598 GEN_INT (sp_offset
+ 5 * reg_size
));
21599 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21601 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
21608 regno
= EH_RETURN_DATA_REGNO (i
);
21609 if (regno
== INVALID_REGNUM
)
21612 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
21613 info
->ehrd_offset
+ sp_offset
21614 + reg_size
* (int) i
);
21616 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
21620 /* Restore GPRs. This is done as a PARALLEL if we are using
21621 the load-multiple instructions. */
21623 && info
->spe_64bit_regs_used
!= 0
21624 && info
->first_gp_reg_save
!= 32)
21626 /* Determine whether we can address all of the registers that need
21627 to be saved with an offset from the stack pointer that fits in
21628 the small const field for SPE memory instructions. */
21629 int spe_regs_addressable_via_sp
21630 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
21631 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
21632 && restoring_GPRs_inline
);
21635 if (spe_regs_addressable_via_sp
)
21636 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
21639 rtx old_frame_reg_rtx
= frame_reg_rtx
;
21640 /* Make r11 point to the start of the SPE save area. We worried about
21641 not clobbering it when we were saving registers in the prologue.
21642 There's no need to worry here because the static chain is passed
21643 anew to every function. */
21644 int ool_adjust
= (restoring_GPRs_inline
21646 : (info
->first_gp_reg_save
21647 - (FIRST_SAVRES_REGISTER
+1))*8);
21649 if (frame_reg_rtx
== sp_reg_rtx
)
21650 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21651 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
21652 GEN_INT (info
->spe_gp_save_offset
21655 /* Keep the invariant that frame_reg_rtx + sp_offset points
21656 at the top of the stack frame. */
21657 sp_offset
= -info
->spe_gp_save_offset
;
21662 if (restoring_GPRs_inline
)
21664 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21665 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21667 rtx offset
, addr
, mem
, reg
;
21669 /* We're doing all this to ensure that the immediate offset
21670 fits into the immediate field of 'evldd'. */
21671 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
21673 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
21674 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
21675 mem
= gen_rtx_MEM (V2SImode
, addr
);
21676 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21678 insn
= emit_move_insn (reg
, mem
);
21679 if (DEFAULT_ABI
== ABI_V4
)
21681 if (frame_pointer_needed
21682 && info
->first_gp_reg_save
+ i
21683 == HARD_FRAME_POINTER_REGNUM
)
21685 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21686 plus_constant (frame_reg_rtx
,
21688 RTX_FRAME_RELATED_P (insn
) = 1;
21691 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21700 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
21702 /*savep=*/false, /*gpr=*/true,
21704 emit_jump_insn (par
);
21705 /* We don't want anybody else emitting things after we jumped
21710 else if (!restoring_GPRs_inline
)
21712 /* We are jumping to an out-of-line function. */
21713 bool can_use_exit
= info
->first_fp_reg_save
== 64;
21716 /* Emit stack reset code if we need it. */
21718 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21719 sp_offset
, can_use_exit
);
21722 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode
, DEFAULT_ABI
== ABI_AIX
21725 GEN_INT (sp_offset
- info
->fp_size
)));
21726 if (REGNO (frame_reg_rtx
) == 11)
21727 sp_offset
+= info
->fp_size
;
21730 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
21731 info
->gp_save_offset
, reg_mode
,
21732 /*savep=*/false, /*gpr=*/true,
21733 /*lr=*/can_use_exit
);
21737 if (info
->cr_save_p
)
21739 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21740 if (DEFAULT_ABI
== ABI_V4
)
21742 = alloc_reg_note (REG_CFA_RESTORE
,
21743 gen_rtx_REG (SImode
, CR2_REGNO
),
21747 emit_jump_insn (par
);
21749 /* We don't want anybody else emitting things after we jumped
21754 insn
= emit_insn (par
);
21755 if (DEFAULT_ABI
== ABI_V4
)
21757 if (frame_pointer_needed
)
21759 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21760 plus_constant (frame_reg_rtx
, sp_offset
));
21761 RTX_FRAME_RELATED_P (insn
) = 1;
21764 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
21766 = alloc_reg_note (REG_CFA_RESTORE
,
21767 gen_rtx_REG (reg_mode
, i
), cfa_restores
);
21770 else if (using_load_multiple
)
21773 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
21774 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21776 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21777 GEN_INT (info
->gp_save_offset
21780 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21781 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21783 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21784 if (DEFAULT_ABI
== ABI_V4
)
21785 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21788 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21789 if (DEFAULT_ABI
== ABI_V4
&& frame_pointer_needed
)
21791 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21792 plus_constant (frame_reg_rtx
, sp_offset
));
21793 RTX_FRAME_RELATED_P (insn
) = 1;
21798 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21799 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21801 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21802 GEN_INT (info
->gp_save_offset
21805 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21806 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21808 insn
= emit_move_insn (reg
, mem
);
21809 if (DEFAULT_ABI
== ABI_V4
)
21811 if (frame_pointer_needed
21812 && info
->first_gp_reg_save
+ i
21813 == HARD_FRAME_POINTER_REGNUM
)
21815 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21816 plus_constant (frame_reg_rtx
, sp_offset
));
21817 RTX_FRAME_RELATED_P (insn
) = 1;
21820 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21826 if (restore_lr
&& !restoring_GPRs_inline
)
21828 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21829 info
->lr_save_offset
+ sp_offset
);
21831 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21832 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21833 gen_rtx_REG (Pmode
, 0));
21836 /* Restore fpr's if we need to do it without calling a function. */
21837 if (restoring_FPRs_inline
)
21838 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21839 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
21840 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
21842 rtx addr
, mem
, reg
;
21843 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21844 GEN_INT (info
->fp_save_offset
21847 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21848 ? DFmode
: SFmode
), addr
);
21849 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21850 ? DFmode
: SFmode
),
21851 info
->first_fp_reg_save
+ i
);
21853 emit_move_insn (reg
, mem
);
21854 if (DEFAULT_ABI
== ABI_V4
)
21855 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21859 /* If we saved cr, restore it here. Just those that were used. */
21860 if (info
->cr_save_p
)
21862 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21863 if (DEFAULT_ABI
== ABI_V4
)
21865 = alloc_reg_note (REG_CFA_RESTORE
, gen_rtx_REG (SImode
, CR2_REGNO
),
21869 /* If this is V.4, unwind the stack pointer after all of the loads
21871 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21872 sp_offset
, !restoring_FPRs_inline
);
21877 REG_NOTES (insn
) = cfa_restores
;
21878 cfa_restores
= NULL_RTX
;
21880 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21881 RTX_FRAME_RELATED_P (insn
) = 1;
21884 if (crtl
->calls_eh_return
)
21886 rtx sa
= EH_RETURN_STACKADJ_RTX
;
21887 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
21893 bool lr
= (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
) == 0;
21894 if (! restoring_FPRs_inline
)
21895 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
21897 p
= rtvec_alloc (2);
21899 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
21900 RTVEC_ELT (p
, 1) = ((restoring_FPRs_inline
|| !lr
)
21901 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
21902 : gen_rtx_CLOBBER (VOIDmode
,
21903 gen_rtx_REG (Pmode
, 65)));
21905 /* If we have to restore more than two FP registers, branch to the
21906 restore function. It will return to our caller. */
21907 if (! restoring_FPRs_inline
)
21912 sym
= rs6000_savres_routine_sym (info
,
21916 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
21917 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
21918 gen_rtx_REG (Pmode
,
21919 DEFAULT_ABI
== ABI_AIX
21921 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21924 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
21925 GEN_INT (info
->fp_save_offset
+ 8*i
));
21926 mem
= gen_frame_mem (DFmode
, addr
);
21928 RTVEC_ELT (p
, i
+4) =
21929 gen_rtx_SET (VOIDmode
,
21930 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
21935 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21939 /* Write function epilogue. */
21942 rs6000_output_function_epilogue (FILE *file
,
21943 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
21945 if (! HAVE_epilogue
)
21947 rtx insn
= get_last_insn ();
21948 /* If the last insn was a BARRIER, we don't have to write anything except
21949 the trace table. */
21950 if (GET_CODE (insn
) == NOTE
)
21951 insn
= prev_nonnote_insn (insn
);
21952 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
21954 /* This is slightly ugly, but at least we don't have two
21955 copies of the epilogue-emitting code. */
21958 /* A NOTE_INSN_DELETED is supposed to be at the start
21959 and end of the "toplevel" insn chain. */
21960 emit_note (NOTE_INSN_DELETED
);
21961 rs6000_emit_epilogue (FALSE
);
21962 emit_note (NOTE_INSN_DELETED
);
21964 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21968 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
21970 INSN_ADDRESSES_NEW (insn
, addr
);
21975 if (TARGET_DEBUG_STACK
)
21976 debug_rtx_list (get_insns (), 100);
21977 final (get_insns (), file
, FALSE
);
21983 macho_branch_islands ();
21984 /* Mach-O doesn't support labels at the end of objects, so if
21985 it looks like we might want one, insert a NOP. */
21987 rtx insn
= get_last_insn ();
21990 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
21991 insn
= PREV_INSN (insn
);
21995 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
21996 fputs ("\tnop\n", file
);
22000 /* Output a traceback table here. See /usr/include/sys/debug.h for info
22003 We don't output a traceback table if -finhibit-size-directive was
22004 used. The documentation for -finhibit-size-directive reads
22005 ``don't output a @code{.size} assembler directive, or anything
22006 else that would cause trouble if the function is split in the
22007 middle, and the two halves are placed at locations far apart in
22008 memory.'' The traceback table has this property, since it
22009 includes the offset from the start of the function to the
22010 traceback table itself.
22012 System V.4 Powerpc's (and the embedded ABI derived from it) use a
22013 different traceback table. */
22014 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
22015 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
22017 const char *fname
= NULL
;
22018 const char *language_string
= lang_hooks
.name
;
22019 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
22021 int optional_tbtab
;
22022 rs6000_stack_t
*info
= rs6000_stack_info ();
22024 if (rs6000_traceback
== traceback_full
)
22025 optional_tbtab
= 1;
22026 else if (rs6000_traceback
== traceback_part
)
22027 optional_tbtab
= 0;
22029 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
22031 if (optional_tbtab
)
22033 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
22034 while (*fname
== '.') /* V.4 encodes . in the name */
22037 /* Need label immediately before tbtab, so we can compute
22038 its offset from the function start. */
22039 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
22040 ASM_OUTPUT_LABEL (file
, fname
);
22043 /* The .tbtab pseudo-op can only be used for the first eight
22044 expressions, since it can't handle the possibly variable
22045 length fields that follow. However, if you omit the optional
22046 fields, the assembler outputs zeros for all optional fields
22047 anyways, giving each variable length field is minimum length
22048 (as defined in sys/debug.h). Thus we can not use the .tbtab
22049 pseudo-op at all. */
22051 /* An all-zero word flags the start of the tbtab, for debuggers
22052 that have to find it by searching forward from the entry
22053 point or from the current pc. */
22054 fputs ("\t.long 0\n", file
);
22056 /* Tbtab format type. Use format type 0. */
22057 fputs ("\t.byte 0,", file
);
22059 /* Language type. Unfortunately, there does not seem to be any
22060 official way to discover the language being compiled, so we
22061 use language_string.
22062 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22063 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22064 a number, so for now use 9. LTO isn't assigned a number either,
22065 so for now use 0. */
22066 if (! strcmp (language_string
, "GNU C")
22067 || ! strcmp (language_string
, "GNU GIMPLE"))
22069 else if (! strcmp (language_string
, "GNU F77")
22070 || ! strcmp (language_string
, "GNU Fortran"))
22072 else if (! strcmp (language_string
, "GNU Pascal"))
22074 else if (! strcmp (language_string
, "GNU Ada"))
22076 else if (! strcmp (language_string
, "GNU C++")
22077 || ! strcmp (language_string
, "GNU Objective-C++"))
22079 else if (! strcmp (language_string
, "GNU Java"))
22081 else if (! strcmp (language_string
, "GNU Objective-C"))
22084 gcc_unreachable ();
22085 fprintf (file
, "%d,", i
);
22087 /* 8 single bit fields: global linkage (not set for C extern linkage,
22088 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22089 from start of procedure stored in tbtab, internal function, function
22090 has controlled storage, function has no toc, function uses fp,
22091 function logs/aborts fp operations. */
22092 /* Assume that fp operations are used if any fp reg must be saved. */
22093 fprintf (file
, "%d,",
22094 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
22096 /* 6 bitfields: function is interrupt handler, name present in
22097 proc table, function calls alloca, on condition directives
22098 (controls stack walks, 3 bits), saves condition reg, saves
22100 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22101 set up as a frame pointer, even when there is no alloca call. */
22102 fprintf (file
, "%d,",
22103 ((optional_tbtab
<< 6)
22104 | ((optional_tbtab
& frame_pointer_needed
) << 5)
22105 | (info
->cr_save_p
<< 1)
22106 | (info
->lr_save_p
)));
22108 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22110 fprintf (file
, "%d,",
22111 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
22113 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22114 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
22116 if (optional_tbtab
)
22118 /* Compute the parameter info from the function decl argument
22121 int next_parm_info_bit
= 31;
22123 for (decl
= DECL_ARGUMENTS (current_function_decl
);
22124 decl
; decl
= DECL_CHAIN (decl
))
22126 rtx parameter
= DECL_INCOMING_RTL (decl
);
22127 enum machine_mode mode
= GET_MODE (parameter
);
22129 if (GET_CODE (parameter
) == REG
)
22131 if (SCALAR_FLOAT_MODE_P (mode
))
22152 gcc_unreachable ();
22155 /* If only one bit will fit, don't or in this entry. */
22156 if (next_parm_info_bit
> 0)
22157 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
22158 next_parm_info_bit
-= 2;
22162 fixed_parms
+= ((GET_MODE_SIZE (mode
)
22163 + (UNITS_PER_WORD
- 1))
22165 next_parm_info_bit
-= 1;
22171 /* Number of fixed point parameters. */
22172 /* This is actually the number of words of fixed point parameters; thus
22173 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22174 fprintf (file
, "%d,", fixed_parms
);
22176 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22178 /* This is actually the number of fp registers that hold parameters;
22179 and thus the maximum value is 13. */
22180 /* Set parameters on stack bit if parameters are not in their original
22181 registers, regardless of whether they are on the stack? Xlc
22182 seems to set the bit when not optimizing. */
22183 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
22185 if (! optional_tbtab
)
22188 /* Optional fields follow. Some are variable length. */
22190 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22191 11 double float. */
22192 /* There is an entry for each parameter in a register, in the order that
22193 they occur in the parameter list. Any intervening arguments on the
22194 stack are ignored. If the list overflows a long (max possible length
22195 34 bits) then completely leave off all elements that don't fit. */
22196 /* Only emit this long if there was at least one parameter. */
22197 if (fixed_parms
|| float_parms
)
22198 fprintf (file
, "\t.long %d\n", parm_info
);
22200 /* Offset from start of code to tb table. */
22201 fputs ("\t.long ", file
);
22202 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
22203 RS6000_OUTPUT_BASENAME (file
, fname
);
22205 rs6000_output_function_entry (file
, fname
);
22208 /* Interrupt handler mask. */
22209 /* Omit this long, since we never set the interrupt handler bit
22212 /* Number of CTL (controlled storage) anchors. */
22213 /* Omit this long, since the has_ctl bit is never set above. */
22215 /* Displacement into stack of each CTL anchor. */
22216 /* Omit this list of longs, because there are no CTL anchors. */
22218 /* Length of function name. */
22221 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
22223 /* Function name. */
22224 assemble_string (fname
, strlen (fname
));
22226 /* Register for alloca automatic storage; this is always reg 31.
22227 Only emit this if the alloca bit was set above. */
22228 if (frame_pointer_needed
)
22229 fputs ("\t.byte 31\n", file
);
22231 fputs ("\t.align 2\n", file
);
22235 /* A C compound statement that outputs the assembler code for a thunk
22236 function, used to implement C++ virtual function calls with
22237 multiple inheritance. The thunk acts as a wrapper around a virtual
22238 function, adjusting the implicit object parameter before handing
22239 control off to the real function.
22241 First, emit code to add the integer DELTA to the location that
22242 contains the incoming first argument. Assume that this argument
22243 contains a pointer, and is the one used to pass the `this' pointer
22244 in C++. This is the incoming argument *before* the function
22245 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22246 values of all other incoming arguments.
22248 After the addition, emit code to jump to FUNCTION, which is a
22249 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22250 not touch the return address. Hence returning from FUNCTION will
22251 return to whoever called the current `thunk'.
22253 The effect must be as if FUNCTION had been called directly with the
22254 adjusted first argument. This macro is responsible for emitting
22255 all of the code for a thunk function; output_function_prologue()
22256 and output_function_epilogue() are not invoked.
22258 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22259 been extracted from it.) It might possibly be useful on some
22260 targets, but probably not.
22262 If you do not define this macro, the target-independent code in the
22263 C++ frontend will generate a less efficient heavyweight thunk that
22264 calls FUNCTION instead of jumping to it. The generic approach does
22265 not support varargs. */
22268 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
22269 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
22272 rtx this_rtx
, insn
, funexp
;
22274 reload_completed
= 1;
22275 epilogue_completed
= 1;
22277 /* Mark the end of the (empty) prologue. */
22278 emit_note (NOTE_INSN_PROLOGUE_END
);
22280 /* Find the "this" pointer. If the function returns a structure,
22281 the structure return pointer is in r3. */
22282 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
22283 this_rtx
= gen_rtx_REG (Pmode
, 4);
22285 this_rtx
= gen_rtx_REG (Pmode
, 3);
22287 /* Apply the constant offset, if required. */
22289 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
22291 /* Apply the offset from the vtable, if required. */
22294 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
22295 rtx tmp
= gen_rtx_REG (Pmode
, 12);
22297 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
22298 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
22300 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
22301 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
22305 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
22307 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
22309 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
22312 /* Generate a tail call to the target function. */
22313 if (!TREE_USED (function
))
22315 assemble_external (function
);
22316 TREE_USED (function
) = 1;
22318 funexp
= XEXP (DECL_RTL (function
), 0);
22319 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
22322 if (MACHOPIC_INDIRECT
)
22323 funexp
= machopic_indirect_call_target (funexp
);
22326 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22327 generate sibcall RTL explicitly. */
22328 insn
= emit_call_insn (
22329 gen_rtx_PARALLEL (VOIDmode
,
22331 gen_rtx_CALL (VOIDmode
,
22332 funexp
, const0_rtx
),
22333 gen_rtx_USE (VOIDmode
, const0_rtx
),
22334 gen_rtx_USE (VOIDmode
,
22335 gen_rtx_REG (SImode
,
22337 gen_rtx_RETURN (VOIDmode
))));
22338 SIBLING_CALL_P (insn
) = 1;
22341 /* Run just enough of rest_of_compilation to get the insns emitted.
22342 There's not really enough bulk here to make other passes such as
22343 instruction scheduling worth while. Note that use_thunk calls
22344 assemble_start_function and assemble_end_function. */
22345 insn
= get_insns ();
22346 insn_locators_alloc ();
22347 shorten_branches (insn
);
22348 final_start_function (insn
, file
, 1);
22349 final (insn
, file
, 1);
22350 final_end_function ();
22352 reload_completed
= 0;
22353 epilogue_completed
= 0;
22356 /* A quick summary of the various types of 'constant-pool tables'
22359 Target Flags Name One table per
22360 AIX (none) AIX TOC object file
22361 AIX -mfull-toc AIX TOC object file
22362 AIX -mminimal-toc AIX minimal TOC translation unit
22363 SVR4/EABI (none) SVR4 SDATA object file
22364 SVR4/EABI -fpic SVR4 pic object file
22365 SVR4/EABI -fPIC SVR4 PIC translation unit
22366 SVR4/EABI -mrelocatable EABI TOC function
22367 SVR4/EABI -maix AIX TOC object file
22368 SVR4/EABI -maix -mminimal-toc
22369 AIX minimal TOC translation unit
22371 Name Reg. Set by entries contains:
22372 made by addrs? fp? sum?
22374 AIX TOC 2 crt0 as Y option option
22375 AIX minimal TOC 30 prolog gcc Y Y option
22376 SVR4 SDATA 13 crt0 gcc N Y N
22377 SVR4 pic 30 prolog ld Y not yet N
22378 SVR4 PIC 30 prolog gcc Y option option
22379 EABI TOC 30 prolog gcc Y option option
22383 /* Hash functions for the hash table. */
22386 rs6000_hash_constant (rtx k
)
22388 enum rtx_code code
= GET_CODE (k
);
22389 enum machine_mode mode
= GET_MODE (k
);
22390 unsigned result
= (code
<< 3) ^ mode
;
22391 const char *format
;
22394 format
= GET_RTX_FORMAT (code
);
22395 flen
= strlen (format
);
22401 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
22404 if (mode
!= VOIDmode
)
22405 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
22417 for (; fidx
< flen
; fidx
++)
22418 switch (format
[fidx
])
22423 const char *str
= XSTR (k
, fidx
);
22424 len
= strlen (str
);
22425 result
= result
* 613 + len
;
22426 for (i
= 0; i
< len
; i
++)
22427 result
= result
* 613 + (unsigned) str
[i
];
22432 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
22436 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
22439 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
22440 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
22444 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
22445 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
22452 gcc_unreachable ();
22459 toc_hash_function (const void *hash_entry
)
22461 const struct toc_hash_struct
*thc
=
22462 (const struct toc_hash_struct
*) hash_entry
;
22463 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
22466 /* Compare H1 and H2 for equivalence. */
22469 toc_hash_eq (const void *h1
, const void *h2
)
22471 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
22472 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
22474 if (((const struct toc_hash_struct
*) h1
)->key_mode
22475 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
22478 return rtx_equal_p (r1
, r2
);
22481 /* These are the names given by the C++ front-end to vtables, and
22482 vtable-like objects. Ideally, this logic should not be here;
22483 instead, there should be some programmatic way of inquiring as
22484 to whether or not an object is a vtable. */
22486 #define VTABLE_NAME_P(NAME) \
22487 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22488 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22489 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22490 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22491 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22493 #ifdef NO_DOLLAR_IN_LABEL
22494 /* Return a GGC-allocated character string translating dollar signs in
22495 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22498 rs6000_xcoff_strip_dollar (const char *name
)
22503 p
= strchr (name
, '$');
22505 if (p
== 0 || p
== name
)
22508 len
= strlen (name
);
22509 strip
= (char *) alloca (len
+ 1);
22510 strcpy (strip
, name
);
22511 p
= strchr (strip
, '$');
22515 p
= strchr (p
+ 1, '$');
22518 return ggc_alloc_string (strip
, len
);
22523 rs6000_output_symbol_ref (FILE *file
, rtx x
)
22525 /* Currently C++ toc references to vtables can be emitted before it
22526 is decided whether the vtable is public or private. If this is
22527 the case, then the linker will eventually complain that there is
22528 a reference to an unknown section. Thus, for vtables only,
22529 we emit the TOC reference to reference the symbol and not the
22531 const char *name
= XSTR (x
, 0);
22533 if (VTABLE_NAME_P (name
))
22535 RS6000_OUTPUT_BASENAME (file
, name
);
22538 assemble_name (file
, name
);
22541 /* Output a TOC entry. We derive the entry name from what is being
22545 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
22548 const char *name
= buf
;
22550 HOST_WIDE_INT offset
= 0;
22552 gcc_assert (!TARGET_NO_TOC
);
22554 /* When the linker won't eliminate them, don't output duplicate
22555 TOC entries (this happens on AIX if there is any kind of TOC,
22556 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22558 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
22560 struct toc_hash_struct
*h
;
22563 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22564 time because GGC is not initialized at that point. */
22565 if (toc_hash_table
== NULL
)
22566 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
22567 toc_hash_eq
, NULL
);
22569 h
= ggc_alloc_toc_hash_struct ();
22571 h
->key_mode
= mode
;
22572 h
->labelno
= labelno
;
22574 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
22575 if (*found
== NULL
)
22577 else /* This is indeed a duplicate.
22578 Set this label equal to that label. */
22580 fputs ("\t.set ", file
);
22581 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22582 fprintf (file
, "%d,", labelno
);
22583 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22584 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
22590 /* If we're going to put a double constant in the TOC, make sure it's
22591 aligned properly when strict alignment is on. */
22592 if (GET_CODE (x
) == CONST_DOUBLE
22593 && STRICT_ALIGNMENT
22594 && GET_MODE_BITSIZE (mode
) >= 64
22595 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
22596 ASM_OUTPUT_ALIGN (file
, 3);
22599 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
22601 /* Handle FP constants specially. Note that if we have a minimal
22602 TOC, things we put here aren't actually in the TOC, so we can allow
22604 if (GET_CODE (x
) == CONST_DOUBLE
&&
22605 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
22607 REAL_VALUE_TYPE rv
;
22610 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22611 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22612 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
22614 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
22618 if (TARGET_MINIMAL_TOC
)
22619 fputs (DOUBLE_INT_ASM_OP
, file
);
22621 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22622 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22623 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22624 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
22625 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22626 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22631 if (TARGET_MINIMAL_TOC
)
22632 fputs ("\t.long ", file
);
22634 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22635 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22636 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22637 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22638 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22639 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22643 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22644 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
22646 REAL_VALUE_TYPE rv
;
22649 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22651 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22652 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
22654 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
22658 if (TARGET_MINIMAL_TOC
)
22659 fputs (DOUBLE_INT_ASM_OP
, file
);
22661 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22662 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22663 fprintf (file
, "0x%lx%08lx\n",
22664 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22669 if (TARGET_MINIMAL_TOC
)
22670 fputs ("\t.long ", file
);
22672 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22673 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22674 fprintf (file
, "0x%lx,0x%lx\n",
22675 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22679 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22680 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
22682 REAL_VALUE_TYPE rv
;
22685 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22686 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22687 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
22689 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
22693 if (TARGET_MINIMAL_TOC
)
22694 fputs (DOUBLE_INT_ASM_OP
, file
);
22696 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22697 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
22702 if (TARGET_MINIMAL_TOC
)
22703 fputs ("\t.long ", file
);
22705 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22706 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
22710 else if (GET_MODE (x
) == VOIDmode
22711 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
22713 unsigned HOST_WIDE_INT low
;
22714 HOST_WIDE_INT high
;
22716 if (GET_CODE (x
) == CONST_DOUBLE
)
22718 low
= CONST_DOUBLE_LOW (x
);
22719 high
= CONST_DOUBLE_HIGH (x
);
22722 #if HOST_BITS_PER_WIDE_INT == 32
22725 high
= (low
& 0x80000000) ? ~0 : 0;
22729 low
= INTVAL (x
) & 0xffffffff;
22730 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
22734 /* TOC entries are always Pmode-sized, but since this
22735 is a bigendian machine then if we're putting smaller
22736 integer constants in the TOC we have to pad them.
22737 (This is still a win over putting the constants in
22738 a separate constant pool, because then we'd have
22739 to have both a TOC entry _and_ the actual constant.)
22741 For a 32-bit target, CONST_INT values are loaded and shifted
22742 entirely within `low' and can be stored in one TOC entry. */
22744 /* It would be easy to make this work, but it doesn't now. */
22745 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
22747 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
22749 #if HOST_BITS_PER_WIDE_INT == 32
22750 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
22751 POINTER_SIZE
, &low
, &high
, 0);
22754 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
22755 high
= (HOST_WIDE_INT
) low
>> 32;
22762 if (TARGET_MINIMAL_TOC
)
22763 fputs (DOUBLE_INT_ASM_OP
, file
);
22765 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22766 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22767 fprintf (file
, "0x%lx%08lx\n",
22768 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22773 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
22775 if (TARGET_MINIMAL_TOC
)
22776 fputs ("\t.long ", file
);
22778 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22779 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22780 fprintf (file
, "0x%lx,0x%lx\n",
22781 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22785 if (TARGET_MINIMAL_TOC
)
22786 fputs ("\t.long ", file
);
22788 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
22789 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
22795 if (GET_CODE (x
) == CONST
)
22797 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
22798 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
22800 base
= XEXP (XEXP (x
, 0), 0);
22801 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
22804 switch (GET_CODE (base
))
22807 name
= XSTR (base
, 0);
22811 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
22812 CODE_LABEL_NUMBER (XEXP (base
, 0)));
22816 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
22820 gcc_unreachable ();
22823 if (TARGET_MINIMAL_TOC
)
22824 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
22827 fputs ("\t.tc ", file
);
22828 RS6000_OUTPUT_BASENAME (file
, name
);
22831 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
22833 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
22835 fputs ("[TC],", file
);
22838 /* Currently C++ toc references to vtables can be emitted before it
22839 is decided whether the vtable is public or private. If this is
22840 the case, then the linker will eventually complain that there is
22841 a TOC reference to an unknown section. Thus, for vtables only,
22842 we emit the TOC reference to reference the symbol and not the
22844 if (VTABLE_NAME_P (name
))
22846 RS6000_OUTPUT_BASENAME (file
, name
);
22848 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
22849 else if (offset
> 0)
22850 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
22853 output_addr_const (file
, x
);
22857 /* Output an assembler pseudo-op to write an ASCII string of N characters
22858 starting at P to FILE.
22860 On the RS/6000, we have to do this using the .byte operation and
22861 write out special characters outside the quoted string.
22862 Also, the assembler is broken; very long strings are truncated,
22863 so we must artificially break them up early. */
22866 output_ascii (FILE *file
, const char *p
, int n
)
22869 int i
, count_string
;
22870 const char *for_string
= "\t.byte \"";
22871 const char *for_decimal
= "\t.byte ";
22872 const char *to_close
= NULL
;
22875 for (i
= 0; i
< n
; i
++)
22878 if (c
>= ' ' && c
< 0177)
22881 fputs (for_string
, file
);
22884 /* Write two quotes to get one. */
22892 for_decimal
= "\"\n\t.byte ";
22896 if (count_string
>= 512)
22898 fputs (to_close
, file
);
22900 for_string
= "\t.byte \"";
22901 for_decimal
= "\t.byte ";
22909 fputs (for_decimal
, file
);
22910 fprintf (file
, "%d", c
);
22912 for_string
= "\n\t.byte \"";
22913 for_decimal
= ", ";
22919 /* Now close the string if we have written one. Then end the line. */
22921 fputs (to_close
, file
);
22924 /* Generate a unique section name for FILENAME for a section type
22925 represented by SECTION_DESC. Output goes into BUF.
22927 SECTION_DESC can be any string, as long as it is different for each
22928 possible section type.
22930 We name the section in the same manner as xlc. The name begins with an
22931 underscore followed by the filename (after stripping any leading directory
22932 names) with the last period replaced by the string SECTION_DESC. If
22933 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22937 rs6000_gen_section_name (char **buf
, const char *filename
,
22938 const char *section_desc
)
22940 const char *q
, *after_last_slash
, *last_period
= 0;
22944 after_last_slash
= filename
;
22945 for (q
= filename
; *q
; q
++)
22948 after_last_slash
= q
+ 1;
22949 else if (*q
== '.')
22953 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
22954 *buf
= (char *) xmalloc (len
);
22959 for (q
= after_last_slash
; *q
; q
++)
22961 if (q
== last_period
)
22963 strcpy (p
, section_desc
);
22964 p
+= strlen (section_desc
);
22968 else if (ISALNUM (*q
))
22972 if (last_period
== 0)
22973 strcpy (p
, section_desc
);
22978 /* Emit profile function. */
22981 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
22983 /* Non-standard profiling for kernels, which just saves LR then calls
22984 _mcount without worrying about arg saves. The idea is to change
22985 the function prologue as little as possible as it isn't easy to
22986 account for arg save/restore code added just for _mcount. */
22987 if (TARGET_PROFILE_KERNEL
)
22990 if (DEFAULT_ABI
== ABI_AIX
)
22992 #ifndef NO_PROFILE_COUNTERS
22993 # define NO_PROFILE_COUNTERS 0
22995 if (NO_PROFILE_COUNTERS
)
22996 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22997 LCT_NORMAL
, VOIDmode
, 0);
23001 const char *label_name
;
23004 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
23005 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
23006 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
23008 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
23009 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
23012 else if (DEFAULT_ABI
== ABI_DARWIN
)
23014 const char *mcount_name
= RS6000_MCOUNT
;
23015 int caller_addr_regno
= LR_REGNO
;
23017 /* Be conservative and always set this, at least for now. */
23018 crtl
->uses_pic_offset_table
= 1;
23021 /* For PIC code, set up a stub and collect the caller's address
23022 from r0, which is where the prologue puts it. */
23023 if (MACHOPIC_INDIRECT
23024 && crtl
->uses_pic_offset_table
)
23025 caller_addr_regno
= 0;
23027 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
23028 LCT_NORMAL
, VOIDmode
, 1,
23029 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
23033 /* Write function profiler code. */
23036 output_function_profiler (FILE *file
, int labelno
)
23040 switch (DEFAULT_ABI
)
23043 gcc_unreachable ();
23048 warning (0, "no profiling of 64-bit code for this ABI");
23051 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
23052 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
23053 if (NO_PROFILE_COUNTERS
)
23055 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23056 reg_names
[0], reg_names
[1]);
23058 else if (TARGET_SECURE_PLT
&& flag_pic
)
23060 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23061 reg_names
[0], reg_names
[1]);
23062 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
23063 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
23064 reg_names
[12], reg_names
[12]);
23065 assemble_name (file
, buf
);
23066 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
23067 assemble_name (file
, buf
);
23068 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
23070 else if (flag_pic
== 1)
23072 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
23073 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23074 reg_names
[0], reg_names
[1]);
23075 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
23076 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
23077 assemble_name (file
, buf
);
23078 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
23080 else if (flag_pic
> 1)
23082 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23083 reg_names
[0], reg_names
[1]);
23084 /* Now, we need to get the address of the label. */
23085 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
23086 assemble_name (file
, buf
);
23087 fputs ("-.\n1:", file
);
23088 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
23089 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
23090 reg_names
[0], reg_names
[11]);
23091 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
23092 reg_names
[0], reg_names
[0], reg_names
[11]);
23096 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
23097 assemble_name (file
, buf
);
23098 fputs ("@ha\n", file
);
23099 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23100 reg_names
[0], reg_names
[1]);
23101 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
23102 assemble_name (file
, buf
);
23103 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
23106 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23107 fprintf (file
, "\tbl %s%s\n",
23108 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
23113 if (!TARGET_PROFILE_KERNEL
)
23115 /* Don't do anything, done in output_profile_hook (). */
23119 gcc_assert (!TARGET_32BIT
);
23121 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
23122 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
23124 if (cfun
->static_chain_decl
!= NULL
)
23126 asm_fprintf (file
, "\tstd %s,24(%s)\n",
23127 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
23128 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
23129 asm_fprintf (file
, "\tld %s,24(%s)\n",
23130 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
23133 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
23141 /* The following variable value is the last issued insn. */
23143 static rtx last_scheduled_insn
;
23145 /* The following variable helps to balance issuing of load and
23146 store instructions */
23148 static int load_store_pendulum
;
23150 /* Power4 load update and store update instructions are cracked into a
23151 load or store and an integer insn which are executed in the same cycle.
23152 Branches have their own dispatch slot which does not count against the
23153 GCC issue rate, but it changes the program flow so there are no other
23154 instructions to issue in this cycle. */
23157 rs6000_variable_issue_1 (rtx insn
, int more
)
23159 last_scheduled_insn
= insn
;
23160 if (GET_CODE (PATTERN (insn
)) == USE
23161 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23163 cached_can_issue_more
= more
;
23164 return cached_can_issue_more
;
23167 if (insn_terminates_group_p (insn
, current_group
))
23169 cached_can_issue_more
= 0;
23170 return cached_can_issue_more
;
23173 /* If no reservation, but reach here */
23174 if (recog_memoized (insn
) < 0)
23177 if (rs6000_sched_groups
)
23179 if (is_microcoded_insn (insn
))
23180 cached_can_issue_more
= 0;
23181 else if (is_cracked_insn (insn
))
23182 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
23184 cached_can_issue_more
= more
- 1;
23186 return cached_can_issue_more
;
23189 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
23192 cached_can_issue_more
= more
- 1;
23193 return cached_can_issue_more
;
23197 rs6000_variable_issue (FILE *stream
, int verbose
, rtx insn
, int more
)
23199 int r
= rs6000_variable_issue_1 (insn
, more
);
23201 fprintf (stream
, "// rs6000_variable_issue (more = %d) = %d\n", more
, r
);
23205 /* Adjust the cost of a scheduling dependency. Return the new cost of
23206 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23209 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
23211 enum attr_type attr_type
;
23213 if (! recog_memoized (insn
))
23216 switch (REG_NOTE_KIND (link
))
23220 /* Data dependency; DEP_INSN writes a register that INSN reads
23221 some cycles later. */
23223 /* Separate a load from a narrower, dependent store. */
23224 if (rs6000_sched_groups
23225 && GET_CODE (PATTERN (insn
)) == SET
23226 && GET_CODE (PATTERN (dep_insn
)) == SET
23227 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
23228 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
23229 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
23230 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
23233 attr_type
= get_attr_type (insn
);
23238 /* Tell the first scheduling pass about the latency between
23239 a mtctr and bctr (and mtlr and br/blr). The first
23240 scheduling pass will not know about this latency since
23241 the mtctr instruction, which has the latency associated
23242 to it, will be generated by reload. */
23243 return TARGET_POWER
? 5 : 4;
23245 /* Leave some extra cycles between a compare and its
23246 dependent branch, to inhibit expensive mispredicts. */
23247 if ((rs6000_cpu_attr
== CPU_PPC603
23248 || rs6000_cpu_attr
== CPU_PPC604
23249 || rs6000_cpu_attr
== CPU_PPC604E
23250 || rs6000_cpu_attr
== CPU_PPC620
23251 || rs6000_cpu_attr
== CPU_PPC630
23252 || rs6000_cpu_attr
== CPU_PPC750
23253 || rs6000_cpu_attr
== CPU_PPC7400
23254 || rs6000_cpu_attr
== CPU_PPC7450
23255 || rs6000_cpu_attr
== CPU_POWER4
23256 || rs6000_cpu_attr
== CPU_POWER5
23257 || rs6000_cpu_attr
== CPU_POWER7
23258 || rs6000_cpu_attr
== CPU_CELL
)
23259 && recog_memoized (dep_insn
)
23260 && (INSN_CODE (dep_insn
) >= 0))
23262 switch (get_attr_type (dep_insn
))
23266 case TYPE_DELAYED_COMPARE
:
23267 case TYPE_IMUL_COMPARE
:
23268 case TYPE_LMUL_COMPARE
:
23269 case TYPE_FPCOMPARE
:
23270 case TYPE_CR_LOGICAL
:
23271 case TYPE_DELAYED_CR
:
23280 case TYPE_STORE_UX
:
23282 case TYPE_FPSTORE_U
:
23283 case TYPE_FPSTORE_UX
:
23284 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23285 && recog_memoized (dep_insn
)
23286 && (INSN_CODE (dep_insn
) >= 0))
23289 if (GET_CODE (PATTERN (insn
)) != SET
)
23290 /* If this happens, we have to extend this to schedule
23291 optimally. Return default for now. */
23294 /* Adjust the cost for the case where the value written
23295 by a fixed point operation is used as the address
23296 gen value on a store. */
23297 switch (get_attr_type (dep_insn
))
23304 if (! store_data_bypass_p (dep_insn
, insn
))
23308 case TYPE_LOAD_EXT
:
23309 case TYPE_LOAD_EXT_U
:
23310 case TYPE_LOAD_EXT_UX
:
23311 case TYPE_VAR_SHIFT_ROTATE
:
23312 case TYPE_VAR_DELAYED_COMPARE
:
23314 if (! store_data_bypass_p (dep_insn
, insn
))
23320 case TYPE_FAST_COMPARE
:
23323 case TYPE_INSERT_WORD
:
23324 case TYPE_INSERT_DWORD
:
23325 case TYPE_FPLOAD_U
:
23326 case TYPE_FPLOAD_UX
:
23328 case TYPE_STORE_UX
:
23329 case TYPE_FPSTORE_U
:
23330 case TYPE_FPSTORE_UX
:
23332 if (! store_data_bypass_p (dep_insn
, insn
))
23340 case TYPE_IMUL_COMPARE
:
23341 case TYPE_LMUL_COMPARE
:
23343 if (! store_data_bypass_p (dep_insn
, insn
))
23349 if (! store_data_bypass_p (dep_insn
, insn
))
23355 if (! store_data_bypass_p (dep_insn
, insn
))
23368 case TYPE_LOAD_EXT
:
23369 case TYPE_LOAD_EXT_U
:
23370 case TYPE_LOAD_EXT_UX
:
23371 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23372 && recog_memoized (dep_insn
)
23373 && (INSN_CODE (dep_insn
) >= 0))
23376 /* Adjust the cost for the case where the value written
23377 by a fixed point instruction is used within the address
23378 gen portion of a subsequent load(u)(x) */
23379 switch (get_attr_type (dep_insn
))
23386 if (set_to_load_agen (dep_insn
, insn
))
23390 case TYPE_LOAD_EXT
:
23391 case TYPE_LOAD_EXT_U
:
23392 case TYPE_LOAD_EXT_UX
:
23393 case TYPE_VAR_SHIFT_ROTATE
:
23394 case TYPE_VAR_DELAYED_COMPARE
:
23396 if (set_to_load_agen (dep_insn
, insn
))
23402 case TYPE_FAST_COMPARE
:
23405 case TYPE_INSERT_WORD
:
23406 case TYPE_INSERT_DWORD
:
23407 case TYPE_FPLOAD_U
:
23408 case TYPE_FPLOAD_UX
:
23410 case TYPE_STORE_UX
:
23411 case TYPE_FPSTORE_U
:
23412 case TYPE_FPSTORE_UX
:
23414 if (set_to_load_agen (dep_insn
, insn
))
23422 case TYPE_IMUL_COMPARE
:
23423 case TYPE_LMUL_COMPARE
:
23425 if (set_to_load_agen (dep_insn
, insn
))
23431 if (set_to_load_agen (dep_insn
, insn
))
23437 if (set_to_load_agen (dep_insn
, insn
))
23448 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23449 && recog_memoized (dep_insn
)
23450 && (INSN_CODE (dep_insn
) >= 0)
23451 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
23458 /* Fall out to return default cost. */
23462 case REG_DEP_OUTPUT
:
23463 /* Output dependency; DEP_INSN writes a register that INSN writes some
23465 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23466 && recog_memoized (dep_insn
)
23467 && (INSN_CODE (dep_insn
) >= 0))
23469 attr_type
= get_attr_type (insn
);
23474 if (get_attr_type (dep_insn
) == TYPE_FP
)
23478 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
23486 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23491 gcc_unreachable ();
23497 /* Debug version of rs6000_adjust_cost. */
23500 rs6000_debug_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
23502 int ret
= rs6000_adjust_cost (insn
, link
, dep_insn
, cost
);
23508 switch (REG_NOTE_KIND (link
))
23510 default: dep
= "unknown depencency"; break;
23511 case REG_DEP_TRUE
: dep
= "data dependency"; break;
23512 case REG_DEP_OUTPUT
: dep
= "output dependency"; break;
23513 case REG_DEP_ANTI
: dep
= "anti depencency"; break;
23517 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23518 "%s, insn:\n", ret
, cost
, dep
);
23526 /* The function returns a true if INSN is microcoded.
23527 Return false otherwise. */
23530 is_microcoded_insn (rtx insn
)
23532 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23533 || GET_CODE (PATTERN (insn
)) == USE
23534 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23537 if (rs6000_cpu_attr
== CPU_CELL
)
23538 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
23540 if (rs6000_sched_groups
)
23542 enum attr_type type
= get_attr_type (insn
);
23543 if (type
== TYPE_LOAD_EXT_U
23544 || type
== TYPE_LOAD_EXT_UX
23545 || type
== TYPE_LOAD_UX
23546 || type
== TYPE_STORE_UX
23547 || type
== TYPE_MFCR
)
23554 /* The function returns true if INSN is cracked into 2 instructions
23555 by the processor (and therefore occupies 2 issue slots). */
23558 is_cracked_insn (rtx insn
)
23560 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23561 || GET_CODE (PATTERN (insn
)) == USE
23562 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23565 if (rs6000_sched_groups
)
23567 enum attr_type type
= get_attr_type (insn
);
23568 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
23569 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
23570 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
23571 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
23572 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
23573 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
23574 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
23575 || type
== TYPE_INSERT_WORD
)
23582 /* The function returns true if INSN can be issued only from
23583 the branch slot. */
23586 is_branch_slot_insn (rtx insn
)
23588 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23589 || GET_CODE (PATTERN (insn
)) == USE
23590 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23593 if (rs6000_sched_groups
)
23595 enum attr_type type
= get_attr_type (insn
);
23596 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
23604 /* The function returns true if out_inst sets a value that is
23605 used in the address generation computation of in_insn */
23607 set_to_load_agen (rtx out_insn
, rtx in_insn
)
23609 rtx out_set
, in_set
;
23611 /* For performance reasons, only handle the simple case where
23612 both loads are a single_set. */
23613 out_set
= single_set (out_insn
);
23616 in_set
= single_set (in_insn
);
23618 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
23624 /* The function returns true if the target storage location of
23625 out_insn is adjacent to the target storage location of in_insn */
23626 /* Return 1 if memory locations are adjacent. */
23629 adjacent_mem_locations (rtx insn1
, rtx insn2
)
23632 rtx a
= get_store_dest (PATTERN (insn1
));
23633 rtx b
= get_store_dest (PATTERN (insn2
));
23635 if ((GET_CODE (XEXP (a
, 0)) == REG
23636 || (GET_CODE (XEXP (a
, 0)) == PLUS
23637 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
23638 && (GET_CODE (XEXP (b
, 0)) == REG
23639 || (GET_CODE (XEXP (b
, 0)) == PLUS
23640 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
23642 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
23645 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
23647 reg0
= XEXP (XEXP (a
, 0), 0);
23648 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
23651 reg0
= XEXP (a
, 0);
23653 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
23655 reg1
= XEXP (XEXP (b
, 0), 0);
23656 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
23659 reg1
= XEXP (b
, 0);
23661 val_diff
= val1
- val0
;
23663 return ((REGNO (reg0
) == REGNO (reg1
))
23664 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
23665 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
23671 /* A C statement (sans semicolon) to update the integer scheduling
23672 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23673 INSN earlier, reduce the priority to execute INSN later. Do not
23674 define this macro if you do not need to adjust the scheduling
23675 priorities of insns. */
23678 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
23680 /* On machines (like the 750) which have asymmetric integer units,
23681 where one integer unit can do multiply and divides and the other
23682 can't, reduce the priority of multiply/divide so it is scheduled
23683 before other integer operations. */
23686 if (! INSN_P (insn
))
23689 if (GET_CODE (PATTERN (insn
)) == USE
)
23692 switch (rs6000_cpu_attr
) {
23694 switch (get_attr_type (insn
))
23701 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
23702 priority
, priority
);
23703 if (priority
>= 0 && priority
< 0x01000000)
23710 if (insn_must_be_first_in_group (insn
)
23711 && reload_completed
23712 && current_sched_info
->sched_max_insns_priority
23713 && rs6000_sched_restricted_insns_priority
)
23716 /* Prioritize insns that can be dispatched only in the first
23718 if (rs6000_sched_restricted_insns_priority
== 1)
23719 /* Attach highest priority to insn. This means that in
23720 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23721 precede 'priority' (critical path) considerations. */
23722 return current_sched_info
->sched_max_insns_priority
;
23723 else if (rs6000_sched_restricted_insns_priority
== 2)
23724 /* Increase priority of insn by a minimal amount. This means that in
23725 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23726 considerations precede dispatch-slot restriction considerations. */
23727 return (priority
+ 1);
23730 if (rs6000_cpu
== PROCESSOR_POWER6
23731 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
23732 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
23733 /* Attach highest priority to insn if the scheduler has just issued two
23734 stores and this instruction is a load, or two loads and this instruction
23735 is a store. Power6 wants loads and stores scheduled alternately
23737 return current_sched_info
->sched_max_insns_priority
;
23742 /* Return true if the instruction is nonpipelined on the Cell. */
23744 is_nonpipeline_insn (rtx insn
)
23746 enum attr_type type
;
23747 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23748 || GET_CODE (PATTERN (insn
)) == USE
23749 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23752 type
= get_attr_type (insn
);
23753 if (type
== TYPE_IMUL
23754 || type
== TYPE_IMUL2
23755 || type
== TYPE_IMUL3
23756 || type
== TYPE_LMUL
23757 || type
== TYPE_IDIV
23758 || type
== TYPE_LDIV
23759 || type
== TYPE_SDIV
23760 || type
== TYPE_DDIV
23761 || type
== TYPE_SSQRT
23762 || type
== TYPE_DSQRT
23763 || type
== TYPE_MFCR
23764 || type
== TYPE_MFCRF
23765 || type
== TYPE_MFJMPR
)
23773 /* Return how many instructions the machine can issue per cycle. */
23776 rs6000_issue_rate (void)
23778 /* Unless scheduling for register pressure, use issue rate of 1 for
23779 first scheduling pass to decrease degradation. */
23780 if (!reload_completed
&& !flag_sched_pressure
)
23783 switch (rs6000_cpu_attr
) {
23784 case CPU_RIOS1
: /* ? */
23786 case CPU_PPC601
: /* ? */
23795 case CPU_PPCE300C2
:
23796 case CPU_PPCE300C3
:
23797 case CPU_PPCE500MC
:
23798 case CPU_PPCE500MC64
:
23818 /* Return how many instructions to look ahead for better insn
23822 rs6000_use_sched_lookahead (void)
23824 if (rs6000_cpu_attr
== CPU_PPC8540
)
23826 if (rs6000_cpu_attr
== CPU_CELL
)
23827 return (reload_completed
? 8 : 0);
23831 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23833 rs6000_use_sched_lookahead_guard (rtx insn
)
23835 if (rs6000_cpu_attr
!= CPU_CELL
)
23838 if (insn
== NULL_RTX
|| !INSN_P (insn
))
23841 if (!reload_completed
23842 || is_nonpipeline_insn (insn
)
23843 || is_microcoded_insn (insn
))
23849 /* Determine is PAT refers to memory. */
23852 is_mem_ref (rtx pat
)
23858 /* stack_tie does not produce any real memory traffic. */
23859 if (GET_CODE (pat
) == UNSPEC
23860 && XINT (pat
, 1) == UNSPEC_TIE
)
23863 if (GET_CODE (pat
) == MEM
)
23866 /* Recursively process the pattern. */
23867 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
23869 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
23872 ret
|= is_mem_ref (XEXP (pat
, i
));
23873 else if (fmt
[i
] == 'E')
23874 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
23875 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
23881 /* Determine if PAT is a PATTERN of a load insn. */
23884 is_load_insn1 (rtx pat
)
23886 if (!pat
|| pat
== NULL_RTX
)
23889 if (GET_CODE (pat
) == SET
)
23890 return is_mem_ref (SET_SRC (pat
));
23892 if (GET_CODE (pat
) == PARALLEL
)
23896 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23897 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
23904 /* Determine if INSN loads from memory. */
23907 is_load_insn (rtx insn
)
23909 if (!insn
|| !INSN_P (insn
))
23912 if (GET_CODE (insn
) == CALL_INSN
)
23915 return is_load_insn1 (PATTERN (insn
));
23918 /* Determine if PAT is a PATTERN of a store insn. */
23921 is_store_insn1 (rtx pat
)
23923 if (!pat
|| pat
== NULL_RTX
)
23926 if (GET_CODE (pat
) == SET
)
23927 return is_mem_ref (SET_DEST (pat
));
23929 if (GET_CODE (pat
) == PARALLEL
)
23933 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23934 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
23941 /* Determine if INSN stores to memory. */
23944 is_store_insn (rtx insn
)
23946 if (!insn
|| !INSN_P (insn
))
23949 return is_store_insn1 (PATTERN (insn
));
23952 /* Return the dest of a store insn. */
23955 get_store_dest (rtx pat
)
23957 gcc_assert (is_store_insn1 (pat
));
23959 if (GET_CODE (pat
) == SET
)
23960 return SET_DEST (pat
);
23961 else if (GET_CODE (pat
) == PARALLEL
)
23965 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23967 rtx inner_pat
= XVECEXP (pat
, 0, i
);
23968 if (GET_CODE (inner_pat
) == SET
23969 && is_mem_ref (SET_DEST (inner_pat
)))
23973 /* We shouldn't get here, because we should have either a simple
23974 store insn or a store with update which are covered above. */
23978 /* Returns whether the dependence between INSN and NEXT is considered
23979 costly by the given target. */
23982 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
23987 /* If the flag is not enabled - no dependence is considered costly;
23988 allow all dependent insns in the same group.
23989 This is the most aggressive option. */
23990 if (rs6000_sched_costly_dep
== no_dep_costly
)
23993 /* If the flag is set to 1 - a dependence is always considered costly;
23994 do not allow dependent instructions in the same group.
23995 This is the most conservative option. */
23996 if (rs6000_sched_costly_dep
== all_deps_costly
)
23999 insn
= DEP_PRO (dep
);
24000 next
= DEP_CON (dep
);
24002 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
24003 && is_load_insn (next
)
24004 && is_store_insn (insn
))
24005 /* Prevent load after store in the same group. */
24008 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
24009 && is_load_insn (next
)
24010 && is_store_insn (insn
)
24011 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
24012 /* Prevent load after store in the same group if it is a true
24016 /* The flag is set to X; dependences with latency >= X are considered costly,
24017 and will not be scheduled in the same group. */
24018 if (rs6000_sched_costly_dep
<= max_dep_latency
24019 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
24025 /* Return the next insn after INSN that is found before TAIL is reached,
24026 skipping any "non-active" insns - insns that will not actually occupy
24027 an issue slot. Return NULL_RTX if such an insn is not found. */
24030 get_next_active_insn (rtx insn
, rtx tail
)
24032 if (insn
== NULL_RTX
|| insn
== tail
)
24037 insn
= NEXT_INSN (insn
);
24038 if (insn
== NULL_RTX
|| insn
== tail
)
24043 || (NONJUMP_INSN_P (insn
)
24044 && GET_CODE (PATTERN (insn
)) != USE
24045 && GET_CODE (PATTERN (insn
)) != CLOBBER
24046 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
24052 /* We are about to begin issuing insns for this clock cycle. */
24055 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
24056 rtx
*ready ATTRIBUTE_UNUSED
,
24057 int *pn_ready ATTRIBUTE_UNUSED
,
24058 int clock_var ATTRIBUTE_UNUSED
)
24060 int n_ready
= *pn_ready
;
24063 fprintf (dump
, "// rs6000_sched_reorder :\n");
24065 /* Reorder the ready list, if the second to last ready insn
24066 is a nonepipeline insn. */
24067 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
24069 if (is_nonpipeline_insn (ready
[n_ready
- 1])
24070 && (recog_memoized (ready
[n_ready
- 2]) > 0))
24071 /* Simply swap first two insns. */
24073 rtx tmp
= ready
[n_ready
- 1];
24074 ready
[n_ready
- 1] = ready
[n_ready
- 2];
24075 ready
[n_ready
- 2] = tmp
;
24079 if (rs6000_cpu
== PROCESSOR_POWER6
)
24080 load_store_pendulum
= 0;
24082 return rs6000_issue_rate ();
24085 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24088 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
24089 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
24092 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
24094 /* For Power6, we need to handle some special cases to try and keep the
24095 store queue from overflowing and triggering expensive flushes.
24097 This code monitors how load and store instructions are being issued
24098 and skews the ready list one way or the other to increase the likelihood
24099 that a desired instruction is issued at the proper time.
24101 A couple of things are done. First, we maintain a "load_store_pendulum"
24102 to track the current state of load/store issue.
24104 - If the pendulum is at zero, then no loads or stores have been
24105 issued in the current cycle so we do nothing.
24107 - If the pendulum is 1, then a single load has been issued in this
24108 cycle and we attempt to locate another load in the ready list to
24111 - If the pendulum is -2, then two stores have already been
24112 issued in this cycle, so we increase the priority of the first load
24113 in the ready list to increase it's likelihood of being chosen first
24116 - If the pendulum is -1, then a single store has been issued in this
24117 cycle and we attempt to locate another store in the ready list to
24118 issue with it, preferring a store to an adjacent memory location to
24119 facilitate store pairing in the store queue.
24121 - If the pendulum is 2, then two loads have already been
24122 issued in this cycle, so we increase the priority of the first store
24123 in the ready list to increase it's likelihood of being chosen first
24126 - If the pendulum < -2 or > 2, then do nothing.
24128 Note: This code covers the most common scenarios. There exist non
24129 load/store instructions which make use of the LSU and which
24130 would need to be accounted for to strictly model the behavior
24131 of the machine. Those instructions are currently unaccounted
24132 for to help minimize compile time overhead of this code.
24134 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
24140 if (is_store_insn (last_scheduled_insn
))
24141 /* Issuing a store, swing the load_store_pendulum to the left */
24142 load_store_pendulum
--;
24143 else if (is_load_insn (last_scheduled_insn
))
24144 /* Issuing a load, swing the load_store_pendulum to the right */
24145 load_store_pendulum
++;
24147 return cached_can_issue_more
;
24149 /* If the pendulum is balanced, or there is only one instruction on
24150 the ready list, then all is well, so return. */
24151 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
24152 return cached_can_issue_more
;
24154 if (load_store_pendulum
== 1)
24156 /* A load has been issued in this cycle. Scan the ready list
24157 for another load to issue with it */
24162 if (is_load_insn (ready
[pos
]))
24164 /* Found a load. Move it to the head of the ready list,
24165 and adjust it's priority so that it is more likely to
24168 for (i
=pos
; i
<*pn_ready
-1; i
++)
24169 ready
[i
] = ready
[i
+ 1];
24170 ready
[*pn_ready
-1] = tmp
;
24172 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24173 INSN_PRIORITY (tmp
)++;
24179 else if (load_store_pendulum
== -2)
24181 /* Two stores have been issued in this cycle. Increase the
24182 priority of the first load in the ready list to favor it for
24183 issuing in the next cycle. */
24188 if (is_load_insn (ready
[pos
])
24190 && INSN_PRIORITY_KNOWN (ready
[pos
]))
24192 INSN_PRIORITY (ready
[pos
])++;
24194 /* Adjust the pendulum to account for the fact that a load
24195 was found and increased in priority. This is to prevent
24196 increasing the priority of multiple loads */
24197 load_store_pendulum
--;
24204 else if (load_store_pendulum
== -1)
24206 /* A store has been issued in this cycle. Scan the ready list for
24207 another store to issue with it, preferring a store to an adjacent
24209 int first_store_pos
= -1;
24215 if (is_store_insn (ready
[pos
]))
24217 /* Maintain the index of the first store found on the
24219 if (first_store_pos
== -1)
24220 first_store_pos
= pos
;
24222 if (is_store_insn (last_scheduled_insn
)
24223 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
24225 /* Found an adjacent store. Move it to the head of the
24226 ready list, and adjust it's priority so that it is
24227 more likely to stay there */
24229 for (i
=pos
; i
<*pn_ready
-1; i
++)
24230 ready
[i
] = ready
[i
+ 1];
24231 ready
[*pn_ready
-1] = tmp
;
24233 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24234 INSN_PRIORITY (tmp
)++;
24236 first_store_pos
= -1;
24244 if (first_store_pos
>= 0)
24246 /* An adjacent store wasn't found, but a non-adjacent store was,
24247 so move the non-adjacent store to the front of the ready
24248 list, and adjust its priority so that it is more likely to
24250 tmp
= ready
[first_store_pos
];
24251 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
24252 ready
[i
] = ready
[i
+ 1];
24253 ready
[*pn_ready
-1] = tmp
;
24254 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24255 INSN_PRIORITY (tmp
)++;
24258 else if (load_store_pendulum
== 2)
24260 /* Two loads have been issued in this cycle. Increase the priority
24261 of the first store in the ready list to favor it for issuing in
24267 if (is_store_insn (ready
[pos
])
24269 && INSN_PRIORITY_KNOWN (ready
[pos
]))
24271 INSN_PRIORITY (ready
[pos
])++;
24273 /* Adjust the pendulum to account for the fact that a store
24274 was found and increased in priority. This is to prevent
24275 increasing the priority of multiple stores */
24276 load_store_pendulum
++;
24285 return cached_can_issue_more
;
24288 /* Return whether the presence of INSN causes a dispatch group termination
24289 of group WHICH_GROUP.
24291 If WHICH_GROUP == current_group, this function will return true if INSN
24292 causes the termination of the current group (i.e, the dispatch group to
24293 which INSN belongs). This means that INSN will be the last insn in the
24294 group it belongs to.
24296 If WHICH_GROUP == previous_group, this function will return true if INSN
24297 causes the termination of the previous group (i.e, the dispatch group that
24298 precedes the group to which INSN belongs). This means that INSN will be
24299 the first insn in the group it belongs to). */
24302 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
24309 first
= insn_must_be_first_in_group (insn
);
24310 last
= insn_must_be_last_in_group (insn
);
24315 if (which_group
== current_group
)
24317 else if (which_group
== previous_group
)
24325 insn_must_be_first_in_group (rtx insn
)
24327 enum attr_type type
;
24330 || GET_CODE (insn
) == NOTE
24331 || DEBUG_INSN_P (insn
)
24332 || GET_CODE (PATTERN (insn
)) == USE
24333 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
24336 switch (rs6000_cpu
)
24338 case PROCESSOR_POWER5
:
24339 if (is_cracked_insn (insn
))
24341 case PROCESSOR_POWER4
:
24342 if (is_microcoded_insn (insn
))
24345 if (!rs6000_sched_groups
)
24348 type
= get_attr_type (insn
);
24355 case TYPE_DELAYED_CR
:
24356 case TYPE_CR_LOGICAL
:
24370 case PROCESSOR_POWER6
:
24371 type
= get_attr_type (insn
);
24375 case TYPE_INSERT_DWORD
:
24379 case TYPE_VAR_SHIFT_ROTATE
:
24386 case TYPE_INSERT_WORD
:
24387 case TYPE_DELAYED_COMPARE
:
24388 case TYPE_IMUL_COMPARE
:
24389 case TYPE_LMUL_COMPARE
:
24390 case TYPE_FPCOMPARE
:
24401 case TYPE_LOAD_EXT_UX
:
24403 case TYPE_STORE_UX
:
24404 case TYPE_FPLOAD_U
:
24405 case TYPE_FPLOAD_UX
:
24406 case TYPE_FPSTORE_U
:
24407 case TYPE_FPSTORE_UX
:
24413 case PROCESSOR_POWER7
:
24414 type
= get_attr_type (insn
);
24418 case TYPE_CR_LOGICAL
:
24425 case TYPE_DELAYED_COMPARE
:
24426 case TYPE_VAR_DELAYED_COMPARE
:
24432 case TYPE_LOAD_EXT
:
24433 case TYPE_LOAD_EXT_U
:
24434 case TYPE_LOAD_EXT_UX
:
24436 case TYPE_STORE_UX
:
24437 case TYPE_FPLOAD_U
:
24438 case TYPE_FPLOAD_UX
:
24439 case TYPE_FPSTORE_U
:
24440 case TYPE_FPSTORE_UX
:
24456 insn_must_be_last_in_group (rtx insn
)
24458 enum attr_type type
;
24461 || GET_CODE (insn
) == NOTE
24462 || DEBUG_INSN_P (insn
)
24463 || GET_CODE (PATTERN (insn
)) == USE
24464 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
24467 switch (rs6000_cpu
) {
24468 case PROCESSOR_POWER4
:
24469 case PROCESSOR_POWER5
:
24470 if (is_microcoded_insn (insn
))
24473 if (is_branch_slot_insn (insn
))
24477 case PROCESSOR_POWER6
:
24478 type
= get_attr_type (insn
);
24485 case TYPE_VAR_SHIFT_ROTATE
:
24492 case TYPE_DELAYED_COMPARE
:
24493 case TYPE_IMUL_COMPARE
:
24494 case TYPE_LMUL_COMPARE
:
24495 case TYPE_FPCOMPARE
:
24509 case PROCESSOR_POWER7
:
24510 type
= get_attr_type (insn
);
24518 case TYPE_LOAD_EXT_U
:
24519 case TYPE_LOAD_EXT_UX
:
24520 case TYPE_STORE_UX
:
24533 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24534 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24537 is_costly_group (rtx
*group_insns
, rtx next_insn
)
24540 int issue_rate
= rs6000_issue_rate ();
24542 for (i
= 0; i
< issue_rate
; i
++)
24544 sd_iterator_def sd_it
;
24546 rtx insn
= group_insns
[i
];
24551 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
24553 rtx next
= DEP_CON (dep
);
24555 if (next
== next_insn
24556 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
24564 /* Utility of the function redefine_groups.
24565 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24566 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24567 to keep it "far" (in a separate group) from GROUP_INSNS, following
24568 one of the following schemes, depending on the value of the flag
24569 -minsert_sched_nops = X:
24570 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24571 in order to force NEXT_INSN into a separate group.
24572 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24573 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24574 insertion (has a group just ended, how many vacant issue slots remain in the
24575 last group, and how many dispatch groups were encountered so far). */
24578 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
24579 rtx next_insn
, bool *group_end
, int can_issue_more
,
24584 int issue_rate
= rs6000_issue_rate ();
24585 bool end
= *group_end
;
24588 if (next_insn
== NULL_RTX
|| DEBUG_INSN_P (next_insn
))
24589 return can_issue_more
;
24591 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
24592 return can_issue_more
;
24594 force
= is_costly_group (group_insns
, next_insn
);
24596 return can_issue_more
;
24598 if (sched_verbose
> 6)
24599 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
24600 *group_count
,can_issue_more
);
24602 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
24605 can_issue_more
= 0;
24607 /* Since only a branch can be issued in the last issue_slot, it is
24608 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24609 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24610 in this case the last nop will start a new group and the branch
24611 will be forced to the new group. */
24612 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
24615 while (can_issue_more
> 0)
24618 emit_insn_before (nop
, next_insn
);
24626 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
24628 int n_nops
= rs6000_sched_insert_nops
;
24630 /* Nops can't be issued from the branch slot, so the effective
24631 issue_rate for nops is 'issue_rate - 1'. */
24632 if (can_issue_more
== 0)
24633 can_issue_more
= issue_rate
;
24635 if (can_issue_more
== 0)
24637 can_issue_more
= issue_rate
- 1;
24640 for (i
= 0; i
< issue_rate
; i
++)
24642 group_insns
[i
] = 0;
24649 emit_insn_before (nop
, next_insn
);
24650 if (can_issue_more
== issue_rate
- 1) /* new group begins */
24653 if (can_issue_more
== 0)
24655 can_issue_more
= issue_rate
- 1;
24658 for (i
= 0; i
< issue_rate
; i
++)
24660 group_insns
[i
] = 0;
24666 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24669 /* Is next_insn going to start a new group? */
24672 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24673 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24674 || (can_issue_more
< issue_rate
&&
24675 insn_terminates_group_p (next_insn
, previous_group
)));
24676 if (*group_end
&& end
)
24679 if (sched_verbose
> 6)
24680 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
24681 *group_count
, can_issue_more
);
24682 return can_issue_more
;
24685 return can_issue_more
;
24688 /* This function tries to synch the dispatch groups that the compiler "sees"
24689 with the dispatch groups that the processor dispatcher is expected to
24690 form in practice. It tries to achieve this synchronization by forcing the
24691 estimated processor grouping on the compiler (as opposed to the function
24692 'pad_goups' which tries to force the scheduler's grouping on the processor).
24694 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24695 examines the (estimated) dispatch groups that will be formed by the processor
24696 dispatcher. It marks these group boundaries to reflect the estimated
24697 processor grouping, overriding the grouping that the scheduler had marked.
24698 Depending on the value of the flag '-minsert-sched-nops' this function can
24699 force certain insns into separate groups or force a certain distance between
24700 them by inserting nops, for example, if there exists a "costly dependence"
24703 The function estimates the group boundaries that the processor will form as
24704 follows: It keeps track of how many vacant issue slots are available after
24705 each insn. A subsequent insn will start a new group if one of the following
24707 - no more vacant issue slots remain in the current dispatch group.
24708 - only the last issue slot, which is the branch slot, is vacant, but the next
24709 insn is not a branch.
24710 - only the last 2 or less issue slots, including the branch slot, are vacant,
24711 which means that a cracked insn (which occupies two issue slots) can't be
24712 issued in this group.
24713 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24714 start a new group. */
24717 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24719 rtx insn
, next_insn
;
24721 int can_issue_more
;
24724 int group_count
= 0;
24728 issue_rate
= rs6000_issue_rate ();
24729 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
24730 for (i
= 0; i
< issue_rate
; i
++)
24732 group_insns
[i
] = 0;
24734 can_issue_more
= issue_rate
;
24736 insn
= get_next_active_insn (prev_head_insn
, tail
);
24739 while (insn
!= NULL_RTX
)
24741 slot
= (issue_rate
- can_issue_more
);
24742 group_insns
[slot
] = insn
;
24744 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24745 if (insn_terminates_group_p (insn
, current_group
))
24746 can_issue_more
= 0;
24748 next_insn
= get_next_active_insn (insn
, tail
);
24749 if (next_insn
== NULL_RTX
)
24750 return group_count
+ 1;
24752 /* Is next_insn going to start a new group? */
24754 = (can_issue_more
== 0
24755 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24756 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24757 || (can_issue_more
< issue_rate
&&
24758 insn_terminates_group_p (next_insn
, previous_group
)));
24760 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
24761 next_insn
, &group_end
, can_issue_more
,
24767 can_issue_more
= 0;
24768 for (i
= 0; i
< issue_rate
; i
++)
24770 group_insns
[i
] = 0;
24774 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
24775 PUT_MODE (next_insn
, VOIDmode
);
24776 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
24777 PUT_MODE (next_insn
, TImode
);
24780 if (can_issue_more
== 0)
24781 can_issue_more
= issue_rate
;
24784 return group_count
;
24787 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24788 dispatch group boundaries that the scheduler had marked. Pad with nops
24789 any dispatch groups which have vacant issue slots, in order to force the
24790 scheduler's grouping on the processor dispatcher. The function
24791 returns the number of dispatch groups found. */
24794 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24796 rtx insn
, next_insn
;
24799 int can_issue_more
;
24801 int group_count
= 0;
24803 /* Initialize issue_rate. */
24804 issue_rate
= rs6000_issue_rate ();
24805 can_issue_more
= issue_rate
;
24807 insn
= get_next_active_insn (prev_head_insn
, tail
);
24808 next_insn
= get_next_active_insn (insn
, tail
);
24810 while (insn
!= NULL_RTX
)
24813 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24815 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
24817 if (next_insn
== NULL_RTX
)
24822 /* If the scheduler had marked group termination at this location
24823 (between insn and next_insn), and neither insn nor next_insn will
24824 force group termination, pad the group with nops to force group
24827 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24828 && !insn_terminates_group_p (insn
, current_group
)
24829 && !insn_terminates_group_p (next_insn
, previous_group
))
24831 if (!is_branch_slot_insn (next_insn
))
24834 while (can_issue_more
)
24837 emit_insn_before (nop
, next_insn
);
24842 can_issue_more
= issue_rate
;
24847 next_insn
= get_next_active_insn (insn
, tail
);
24850 return group_count
;
24853 /* We're beginning a new block. Initialize data structures as necessary. */
24856 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
24857 int sched_verbose ATTRIBUTE_UNUSED
,
24858 int max_ready ATTRIBUTE_UNUSED
)
24860 last_scheduled_insn
= NULL_RTX
;
24861 load_store_pendulum
= 0;
24864 /* The following function is called at the end of scheduling BB.
24865 After reload, it inserts nops at insn group bundling. */
24868 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
24873 fprintf (dump
, "=== Finishing schedule.\n");
24875 if (reload_completed
&& rs6000_sched_groups
)
24877 /* Do not run sched_finish hook when selective scheduling enabled. */
24878 if (sel_sched_p ())
24881 if (rs6000_sched_insert_nops
== sched_finish_none
)
24884 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24885 n_groups
= pad_groups (dump
, sched_verbose
,
24886 current_sched_info
->prev_head
,
24887 current_sched_info
->next_tail
);
24889 n_groups
= redefine_groups (dump
, sched_verbose
,
24890 current_sched_info
->prev_head
,
24891 current_sched_info
->next_tail
);
24893 if (sched_verbose
>= 6)
24895 fprintf (dump
, "ngroups = %d\n", n_groups
);
24896 print_rtl (dump
, current_sched_info
->prev_head
);
24897 fprintf (dump
, "Done finish_sched\n");
24902 struct _rs6000_sched_context
24904 short cached_can_issue_more
;
24905 rtx last_scheduled_insn
;
24906 int load_store_pendulum
;
24909 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
24910 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
24912 /* Allocate store for new scheduling context. */
24914 rs6000_alloc_sched_context (void)
24916 return xmalloc (sizeof (rs6000_sched_context_def
));
24919 /* If CLEAN_P is true then initializes _SC with clean data,
24920 and from the global context otherwise. */
24922 rs6000_init_sched_context (void *_sc
, bool clean_p
)
24924 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24928 sc
->cached_can_issue_more
= 0;
24929 sc
->last_scheduled_insn
= NULL_RTX
;
24930 sc
->load_store_pendulum
= 0;
24934 sc
->cached_can_issue_more
= cached_can_issue_more
;
24935 sc
->last_scheduled_insn
= last_scheduled_insn
;
24936 sc
->load_store_pendulum
= load_store_pendulum
;
24940 /* Sets the global scheduling context to the one pointed to by _SC. */
24942 rs6000_set_sched_context (void *_sc
)
24944 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24946 gcc_assert (sc
!= NULL
);
24948 cached_can_issue_more
= sc
->cached_can_issue_more
;
24949 last_scheduled_insn
= sc
->last_scheduled_insn
;
24950 load_store_pendulum
= sc
->load_store_pendulum
;
24955 rs6000_free_sched_context (void *_sc
)
24957 gcc_assert (_sc
!= NULL
);
24963 /* Length in units of the trampoline for entering a nested function. */
24966 rs6000_trampoline_size (void)
24970 switch (DEFAULT_ABI
)
24973 gcc_unreachable ();
24976 ret
= (TARGET_32BIT
) ? 12 : 24;
24981 ret
= (TARGET_32BIT
) ? 40 : 48;
24988 /* Emit RTL insns to initialize the variable parts of a trampoline.
24989 FNADDR is an RTX for the address of the function's pure code.
24990 CXT is an RTX for the static chain value for the function. */
24993 rs6000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
24995 int regsize
= (TARGET_32BIT
) ? 4 : 8;
24996 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
24997 rtx ctx_reg
= force_reg (Pmode
, cxt
);
24998 rtx addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
25000 switch (DEFAULT_ABI
)
25003 gcc_unreachable ();
25005 /* Under AIX, just build the 3 word function descriptor */
25008 rtx fnmem
= gen_const_mem (Pmode
, force_reg (Pmode
, fnaddr
));
25009 rtx fn_reg
= gen_reg_rtx (Pmode
);
25010 rtx toc_reg
= gen_reg_rtx (Pmode
);
25012 /* Macro to shorten the code expansions below. */
25013 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25015 m_tramp
= replace_equiv_address (m_tramp
, addr
);
25017 emit_move_insn (fn_reg
, MEM_PLUS (fnmem
, 0));
25018 emit_move_insn (toc_reg
, MEM_PLUS (fnmem
, regsize
));
25019 emit_move_insn (MEM_PLUS (m_tramp
, 0), fn_reg
);
25020 emit_move_insn (MEM_PLUS (m_tramp
, regsize
), toc_reg
);
25021 emit_move_insn (MEM_PLUS (m_tramp
, 2*regsize
), ctx_reg
);
25027 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25030 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
25031 LCT_NORMAL
, VOIDmode
, 4,
25033 GEN_INT (rs6000_trampoline_size ()), SImode
,
25041 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25042 identifier as an argument, so the front end shouldn't look it up. */
25045 rs6000_attribute_takes_identifier_p (const_tree attr_id
)
25047 return is_attribute_p ("altivec", attr_id
);
25050 /* Handle the "altivec" attribute. The attribute may have
25051 arguments as follows:
25053 __attribute__((altivec(vector__)))
25054 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25055 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25057 and may appear more than once (e.g., 'vector bool char') in a
25058 given declaration. */
25061 rs6000_handle_altivec_attribute (tree
*node
,
25062 tree name ATTRIBUTE_UNUSED
,
25064 int flags ATTRIBUTE_UNUSED
,
25065 bool *no_add_attrs
)
25067 tree type
= *node
, result
= NULL_TREE
;
25068 enum machine_mode mode
;
25071 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
25072 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
25073 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
25076 while (POINTER_TYPE_P (type
)
25077 || TREE_CODE (type
) == FUNCTION_TYPE
25078 || TREE_CODE (type
) == METHOD_TYPE
25079 || TREE_CODE (type
) == ARRAY_TYPE
)
25080 type
= TREE_TYPE (type
);
25082 mode
= TYPE_MODE (type
);
25084 /* Check for invalid AltiVec type qualifiers. */
25085 if (type
== long_double_type_node
)
25086 error ("use of %<long double%> in AltiVec types is invalid");
25087 else if (type
== boolean_type_node
)
25088 error ("use of boolean types in AltiVec types is invalid");
25089 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
25090 error ("use of %<complex%> in AltiVec types is invalid");
25091 else if (DECIMAL_FLOAT_MODE_P (mode
))
25092 error ("use of decimal floating point types in AltiVec types is invalid");
25093 else if (!TARGET_VSX
)
25095 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
25098 error ("use of %<long%> in AltiVec types is invalid for "
25099 "64-bit code without -mvsx");
25100 else if (rs6000_warn_altivec_long
)
25101 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25104 else if (type
== long_long_unsigned_type_node
25105 || type
== long_long_integer_type_node
)
25106 error ("use of %<long long%> in AltiVec types is invalid without "
25108 else if (type
== double_type_node
)
25109 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25112 switch (altivec_type
)
25115 unsigned_p
= TYPE_UNSIGNED (type
);
25119 result
= (unsigned_p
? unsigned_V2DI_type_node
: V2DI_type_node
);
25122 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
25125 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
25128 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
25130 case SFmode
: result
= V4SF_type_node
; break;
25131 case DFmode
: result
= V2DF_type_node
; break;
25132 /* If the user says 'vector int bool', we may be handed the 'bool'
25133 attribute _before_ the 'vector' attribute, and so select the
25134 proper type in the 'b' case below. */
25135 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
25136 case V2DImode
: case V2DFmode
:
25144 case DImode
: case V2DImode
: result
= bool_V2DI_type_node
; break;
25145 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
25146 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
25147 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
25154 case V8HImode
: result
= pixel_V8HI_type_node
;
25160 /* Propagate qualifiers attached to the element type
25161 onto the vector type. */
25162 if (result
&& result
!= type
&& TYPE_QUALS (type
))
25163 result
= build_qualified_type (result
, TYPE_QUALS (type
));
25165 *no_add_attrs
= true; /* No need to hang on to the attribute. */
25168 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
25173 /* AltiVec defines four built-in scalar types that serve as vector
25174 elements; we must teach the compiler how to mangle them. */
25176 static const char *
25177 rs6000_mangle_type (const_tree type
)
25179 type
= TYPE_MAIN_VARIANT (type
);
25181 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
25182 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
25185 if (type
== bool_char_type_node
) return "U6__boolc";
25186 if (type
== bool_short_type_node
) return "U6__bools";
25187 if (type
== pixel_type_node
) return "u7__pixel";
25188 if (type
== bool_int_type_node
) return "U6__booli";
25189 if (type
== bool_long_type_node
) return "U6__booll";
25191 /* Mangle IBM extended float long double as `g' (__float128) on
25192 powerpc*-linux where long-double-64 previously was the default. */
25193 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
25195 && TARGET_LONG_DOUBLE_128
25196 && !TARGET_IEEEQUAD
)
25199 /* For all other types, use normal C++ mangling. */
25203 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25204 struct attribute_spec.handler. */
25207 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
25208 tree args ATTRIBUTE_UNUSED
,
25209 int flags ATTRIBUTE_UNUSED
,
25210 bool *no_add_attrs
)
25212 if (TREE_CODE (*node
) != FUNCTION_TYPE
25213 && TREE_CODE (*node
) != FIELD_DECL
25214 && TREE_CODE (*node
) != TYPE_DECL
)
25216 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
25218 *no_add_attrs
= true;
25224 /* Set longcall attributes on all functions declared when
25225 rs6000_default_long_calls is true. */
25227 rs6000_set_default_type_attributes (tree type
)
25229 if (rs6000_default_long_calls
25230 && (TREE_CODE (type
) == FUNCTION_TYPE
25231 || TREE_CODE (type
) == METHOD_TYPE
))
25232 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
25234 TYPE_ATTRIBUTES (type
));
25237 darwin_set_default_type_attributes (type
);
25241 /* Return a reference suitable for calling a function with the
25242 longcall attribute. */
25245 rs6000_longcall_ref (rtx call_ref
)
25247 const char *call_name
;
25250 if (GET_CODE (call_ref
) != SYMBOL_REF
)
25253 /* System V adds '.' to the internal name, so skip them. */
25254 call_name
= XSTR (call_ref
, 0);
25255 if (*call_name
== '.')
25257 while (*call_name
== '.')
25260 node
= get_identifier (call_name
);
25261 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
25264 return force_reg (Pmode
, call_ref
);
25267 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25268 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25271 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25272 struct attribute_spec.handler. */
25274 rs6000_handle_struct_attribute (tree
*node
, tree name
,
25275 tree args ATTRIBUTE_UNUSED
,
25276 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
25279 if (DECL_P (*node
))
25281 if (TREE_CODE (*node
) == TYPE_DECL
)
25282 type
= &TREE_TYPE (*node
);
25287 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
25288 || TREE_CODE (*type
) == UNION_TYPE
)))
25290 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
25291 *no_add_attrs
= true;
25294 else if ((is_attribute_p ("ms_struct", name
)
25295 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
25296 || ((is_attribute_p ("gcc_struct", name
)
25297 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
25299 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
25301 *no_add_attrs
= true;
25308 rs6000_ms_bitfield_layout_p (const_tree record_type
)
25310 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
25311 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
25312 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
25315 #ifdef USING_ELFOS_H
25317 /* A get_unnamed_section callback, used for switching to toc_section. */
25320 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
25322 if (DEFAULT_ABI
== ABI_AIX
25323 && TARGET_MINIMAL_TOC
25324 && !TARGET_RELOCATABLE
)
25326 if (!toc_initialized
)
25328 toc_initialized
= 1;
25329 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
25330 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
25331 fprintf (asm_out_file
, "\t.tc ");
25332 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
25333 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25334 fprintf (asm_out_file
, "\n");
25336 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25337 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25338 fprintf (asm_out_file
, " = .+32768\n");
25341 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25343 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
25344 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
25347 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25348 if (!toc_initialized
)
25350 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25351 fprintf (asm_out_file
, " = .+32768\n");
25352 toc_initialized
= 1;
25357 /* Implement TARGET_ASM_INIT_SECTIONS. */
25360 rs6000_elf_asm_init_sections (void)
25363 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
25366 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
25367 SDATA2_SECTION_ASM_OP
);
25370 /* Implement TARGET_SELECT_RTX_SECTION. */
25373 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
25374 unsigned HOST_WIDE_INT align
)
25376 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
25377 return toc_section
;
25379 return default_elf_select_rtx_section (mode
, x
, align
);
25382 /* For a SYMBOL_REF, set generic flags and then perform some
25383 target-specific processing.
25385 When the AIX ABI is requested on a non-AIX system, replace the
25386 function name with the real name (with a leading .) rather than the
25387 function descriptor name. This saves a lot of overriding code to
25388 read the prefixes. */
25391 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
25393 default_encode_section_info (decl
, rtl
, first
);
25396 && TREE_CODE (decl
) == FUNCTION_DECL
25398 && DEFAULT_ABI
== ABI_AIX
)
25400 rtx sym_ref
= XEXP (rtl
, 0);
25401 size_t len
= strlen (XSTR (sym_ref
, 0));
25402 char *str
= XALLOCAVEC (char, len
+ 2);
25404 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
25405 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
25410 compare_section_name (const char *section
, const char *templ
)
25414 len
= strlen (templ
);
25415 return (strncmp (section
, templ
, len
) == 0
25416 && (section
[len
] == 0 || section
[len
] == '.'));
25420 rs6000_elf_in_small_data_p (const_tree decl
)
25422 if (rs6000_sdata
== SDATA_NONE
)
25425 /* We want to merge strings, so we never consider them small data. */
25426 if (TREE_CODE (decl
) == STRING_CST
)
25429 /* Functions are never in the small data area. */
25430 if (TREE_CODE (decl
) == FUNCTION_DECL
)
25433 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
25435 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
25436 if (compare_section_name (section
, ".sdata")
25437 || compare_section_name (section
, ".sdata2")
25438 || compare_section_name (section
, ".gnu.linkonce.s")
25439 || compare_section_name (section
, ".sbss")
25440 || compare_section_name (section
, ".sbss2")
25441 || compare_section_name (section
, ".gnu.linkonce.sb")
25442 || strcmp (section
, ".PPC.EMB.sdata0") == 0
25443 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
25448 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
25451 && size
<= g_switch_value
25452 /* If it's not public, and we're not going to reference it there,
25453 there's no need to put it in the small data section. */
25454 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
25461 #endif /* USING_ELFOS_H */
25463 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25466 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
25468 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
25471 /* Return a REG that occurs in ADDR with coefficient 1.
25472 ADDR can be effectively incremented by incrementing REG.
25474 r0 is special and we must not select it as an address
25475 register by this routine since our caller will try to
25476 increment the returned register via an "la" instruction. */
25479 find_addr_reg (rtx addr
)
25481 while (GET_CODE (addr
) == PLUS
)
25483 if (GET_CODE (XEXP (addr
, 0)) == REG
25484 && REGNO (XEXP (addr
, 0)) != 0)
25485 addr
= XEXP (addr
, 0);
25486 else if (GET_CODE (XEXP (addr
, 1)) == REG
25487 && REGNO (XEXP (addr
, 1)) != 0)
25488 addr
= XEXP (addr
, 1);
25489 else if (CONSTANT_P (XEXP (addr
, 0)))
25490 addr
= XEXP (addr
, 1);
25491 else if (CONSTANT_P (XEXP (addr
, 1)))
25492 addr
= XEXP (addr
, 0);
25494 gcc_unreachable ();
25496 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
25501 rs6000_fatal_bad_address (rtx op
)
25503 fatal_insn ("bad address", op
);
25508 typedef struct branch_island_d
{
25509 tree function_name
;
25514 DEF_VEC_O(branch_island
);
25515 DEF_VEC_ALLOC_O(branch_island
,gc
);
25517 static VEC(branch_island
,gc
) *branch_islands
;
25519 /* Remember to generate a branch island for far calls to the given
25523 add_compiler_branch_island (tree label_name
, tree function_name
,
25526 branch_island
*bi
= VEC_safe_push (branch_island
, gc
, branch_islands
, NULL
);
25528 bi
->function_name
= function_name
;
25529 bi
->label_name
= label_name
;
25530 bi
->line_number
= line_number
;
25533 /* Generate far-jump branch islands for everything recorded in
25534 branch_islands. Invoked immediately after the last instruction of
25535 the epilogue has been emitted; the branch islands must be appended
25536 to, and contiguous with, the function body. Mach-O stubs are
25537 generated in machopic_output_stub(). */
25540 macho_branch_islands (void)
25544 while (!VEC_empty (branch_island
, branch_islands
))
25546 branch_island
*bi
= VEC_last (branch_island
, branch_islands
);
25547 const char *label
= IDENTIFIER_POINTER (bi
->label_name
);
25548 const char *name
= IDENTIFIER_POINTER (bi
->function_name
);
25549 char name_buf
[512];
25550 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25551 if (name
[0] == '*' || name
[0] == '&')
25552 strcpy (name_buf
, name
+1);
25556 strcpy (name_buf
+1, name
);
25558 strcpy (tmp_buf
, "\n");
25559 strcat (tmp_buf
, label
);
25560 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25561 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25562 dbxout_stabd (N_SLINE
, bi
->line_number
);
25563 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25566 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
25567 strcat (tmp_buf
, label
);
25568 strcat (tmp_buf
, "_pic\n");
25569 strcat (tmp_buf
, label
);
25570 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
25572 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
25573 strcat (tmp_buf
, name_buf
);
25574 strcat (tmp_buf
, " - ");
25575 strcat (tmp_buf
, label
);
25576 strcat (tmp_buf
, "_pic)\n");
25578 strcat (tmp_buf
, "\tmtlr r0\n");
25580 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
25581 strcat (tmp_buf
, name_buf
);
25582 strcat (tmp_buf
, " - ");
25583 strcat (tmp_buf
, label
);
25584 strcat (tmp_buf
, "_pic)\n");
25586 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
25590 strcat (tmp_buf
, ":\nlis r12,hi16(");
25591 strcat (tmp_buf
, name_buf
);
25592 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
25593 strcat (tmp_buf
, name_buf
);
25594 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
25596 output_asm_insn (tmp_buf
, 0);
25597 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25598 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25599 dbxout_stabd (N_SLINE
, bi
->line_number
);
25600 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25601 VEC_pop (branch_island
, branch_islands
);
25605 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25606 already there or not. */
25609 no_previous_def (tree function_name
)
25614 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25615 if (function_name
== bi
->function_name
)
25620 /* GET_PREV_LABEL gets the label name from the previous definition of
25624 get_prev_label (tree function_name
)
25629 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25630 if (function_name
== bi
->function_name
)
25631 return bi
->label_name
;
25635 /* INSN is either a function call or a millicode call. It may have an
25636 unconditional jump in its delay slot.
25638 CALL_DEST is the routine we are calling. */
25641 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
25642 int cookie_operand_number
)
25644 static char buf
[256];
25645 if (darwin_emit_branch_islands
25646 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
25647 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
25650 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
25652 if (no_previous_def (funname
))
25654 rtx label_rtx
= gen_label_rtx ();
25655 char *label_buf
, temp_buf
[256];
25656 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
25657 CODE_LABEL_NUMBER (label_rtx
));
25658 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
25659 labelname
= get_identifier (label_buf
);
25660 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
25663 labelname
= get_prev_label (funname
);
25665 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25666 instruction will reach 'foo', otherwise link as 'bl L42'".
25667 "L42" should be a 'branch island', that will do a far jump to
25668 'foo'. Branch islands are generated in
25669 macho_branch_islands(). */
25670 sprintf (buf
, "jbsr %%z%d,%.246s",
25671 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
25674 sprintf (buf
, "bl %%z%d", dest_operand_number
);
25678 /* Generate PIC and indirect symbol stubs. */
25681 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
25683 unsigned int length
;
25684 char *symbol_name
, *lazy_ptr_name
;
25685 char *local_label_0
;
25686 static int label
= 0;
25688 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25689 symb
= (*targetm
.strip_name_encoding
) (symb
);
25692 length
= strlen (symb
);
25693 symbol_name
= XALLOCAVEC (char, length
+ 32);
25694 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
25696 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
25697 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
25700 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
25702 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
25706 fprintf (file
, "\t.align 5\n");
25708 fprintf (file
, "%s:\n", stub
);
25709 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25712 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25713 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
25715 fprintf (file
, "\tmflr r0\n");
25716 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
25717 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
25718 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
25719 lazy_ptr_name
, local_label_0
);
25720 fprintf (file
, "\tmtlr r0\n");
25721 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
25722 (TARGET_64BIT
? "ldu" : "lwzu"),
25723 lazy_ptr_name
, local_label_0
);
25724 fprintf (file
, "\tmtctr r12\n");
25725 fprintf (file
, "\tbctr\n");
25729 fprintf (file
, "\t.align 4\n");
25731 fprintf (file
, "%s:\n", stub
);
25732 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25734 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
25735 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
25736 (TARGET_64BIT
? "ldu" : "lwzu"),
25738 fprintf (file
, "\tmtctr r12\n");
25739 fprintf (file
, "\tbctr\n");
25742 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
25743 fprintf (file
, "%s:\n", lazy_ptr_name
);
25744 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25745 fprintf (file
, "%sdyld_stub_binding_helper\n",
25746 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
25749 /* Legitimize PIC addresses. If the address is already
25750 position-independent, we return ORIG. Newly generated
25751 position-independent addresses go into a reg. This is REG if non
25752 zero, otherwise we allocate register(s) as necessary. */
25754 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25757 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
25762 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
25763 reg
= gen_reg_rtx (Pmode
);
25765 if (GET_CODE (orig
) == CONST
)
25769 if (GET_CODE (XEXP (orig
, 0)) == PLUS
25770 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
25773 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
25775 /* Use a different reg for the intermediate value, as
25776 it will be marked UNCHANGING. */
25777 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
25778 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
25781 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
25784 if (GET_CODE (offset
) == CONST_INT
)
25786 if (SMALL_INT (offset
))
25787 return plus_constant (base
, INTVAL (offset
));
25788 else if (! reload_in_progress
&& ! reload_completed
)
25789 offset
= force_reg (Pmode
, offset
);
25792 rtx mem
= force_const_mem (Pmode
, orig
);
25793 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
25796 return gen_rtx_PLUS (Pmode
, base
, offset
);
25799 /* Fall back on generic machopic code. */
25800 return machopic_legitimize_pic_address (orig
, mode
, reg
);
25803 /* Output a .machine directive for the Darwin assembler, and call
25804 the generic start_file routine. */
25807 rs6000_darwin_file_start (void)
25809 static const struct
25815 { "ppc64", "ppc64", MASK_64BIT
},
25816 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
25817 { "power4", "ppc970", 0 },
25818 { "G5", "ppc970", 0 },
25819 { "7450", "ppc7450", 0 },
25820 { "7400", "ppc7400", MASK_ALTIVEC
},
25821 { "G4", "ppc7400", 0 },
25822 { "750", "ppc750", 0 },
25823 { "740", "ppc750", 0 },
25824 { "G3", "ppc750", 0 },
25825 { "604e", "ppc604e", 0 },
25826 { "604", "ppc604", 0 },
25827 { "603e", "ppc603", 0 },
25828 { "603", "ppc603", 0 },
25829 { "601", "ppc601", 0 },
25830 { NULL
, "ppc", 0 } };
25831 const char *cpu_id
= "";
25834 rs6000_file_start ();
25835 darwin_file_start ();
25837 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25838 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
25839 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
25840 && rs6000_select
[i
].string
[0] != '\0')
25841 cpu_id
= rs6000_select
[i
].string
;
25843 /* Look through the mapping array. Pick the first name that either
25844 matches the argument, has a bit set in IF_SET that is also set
25845 in the target flags, or has a NULL name. */
25848 while (mapping
[i
].arg
!= NULL
25849 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
25850 && (mapping
[i
].if_set
& target_flags
) == 0)
25853 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
25856 #endif /* TARGET_MACHO */
25860 rs6000_elf_reloc_rw_mask (void)
25864 else if (DEFAULT_ABI
== ABI_AIX
)
25870 /* Record an element in the table of global constructors. SYMBOL is
25871 a SYMBOL_REF of the function to be called; PRIORITY is a number
25872 between 0 and MAX_INIT_PRIORITY.
25874 This differs from default_named_section_asm_out_constructor in
25875 that we have special handling for -mrelocatable. */
25878 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
25880 const char *section
= ".ctors";
25883 if (priority
!= DEFAULT_INIT_PRIORITY
)
25885 sprintf (buf
, ".ctors.%.5u",
25886 /* Invert the numbering so the linker puts us in the proper
25887 order; constructors are run from right to left, and the
25888 linker sorts in increasing order. */
25889 MAX_INIT_PRIORITY
- priority
);
25893 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25894 assemble_align (POINTER_SIZE
);
25896 if (TARGET_RELOCATABLE
)
25898 fputs ("\t.long (", asm_out_file
);
25899 output_addr_const (asm_out_file
, symbol
);
25900 fputs (")@fixup\n", asm_out_file
);
25903 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25907 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
25909 const char *section
= ".dtors";
25912 if (priority
!= DEFAULT_INIT_PRIORITY
)
25914 sprintf (buf
, ".dtors.%.5u",
25915 /* Invert the numbering so the linker puts us in the proper
25916 order; constructors are run from right to left, and the
25917 linker sorts in increasing order. */
25918 MAX_INIT_PRIORITY
- priority
);
25922 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25923 assemble_align (POINTER_SIZE
);
25925 if (TARGET_RELOCATABLE
)
25927 fputs ("\t.long (", asm_out_file
);
25928 output_addr_const (asm_out_file
, symbol
);
25929 fputs (")@fixup\n", asm_out_file
);
25932 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25936 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
25940 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
25941 ASM_OUTPUT_LABEL (file
, name
);
25942 fputs (DOUBLE_INT_ASM_OP
, file
);
25943 rs6000_output_function_entry (file
, name
);
25944 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
25947 fputs ("\t.size\t", file
);
25948 assemble_name (file
, name
);
25949 fputs (",24\n\t.type\t.", file
);
25950 assemble_name (file
, name
);
25951 fputs (",@function\n", file
);
25952 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
25954 fputs ("\t.globl\t.", file
);
25955 assemble_name (file
, name
);
25960 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25961 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25962 rs6000_output_function_entry (file
, name
);
25963 fputs (":\n", file
);
25967 if (TARGET_RELOCATABLE
25968 && !TARGET_SECURE_PLT
25969 && (get_pool_size () != 0 || crtl
->profile
)
25974 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
25976 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
25977 fprintf (file
, "\t.long ");
25978 assemble_name (file
, buf
);
25980 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
25981 assemble_name (file
, buf
);
25985 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25986 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25988 if (DEFAULT_ABI
== ABI_AIX
)
25990 const char *desc_name
, *orig_name
;
25992 orig_name
= (*targetm
.strip_name_encoding
) (name
);
25993 desc_name
= orig_name
;
25994 while (*desc_name
== '.')
25997 if (TREE_PUBLIC (decl
))
25998 fprintf (file
, "\t.globl %s\n", desc_name
);
26000 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
26001 fprintf (file
, "%s:\n", desc_name
);
26002 fprintf (file
, "\t.long %s\n", orig_name
);
26003 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
26004 if (DEFAULT_ABI
== ABI_AIX
)
26005 fputs ("\t.long 0\n", file
);
26006 fprintf (file
, "\t.previous\n");
26008 ASM_OUTPUT_LABEL (file
, name
);
26012 rs6000_elf_file_end (void)
26014 #ifdef HAVE_AS_GNU_ATTRIBUTE
26015 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
26017 if (rs6000_passes_float
)
26018 fprintf (asm_out_file
, "\t.gnu_attribute 4, %d\n",
26019 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
26020 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
26022 if (rs6000_passes_vector
)
26023 fprintf (asm_out_file
, "\t.gnu_attribute 8, %d\n",
26024 (TARGET_ALTIVEC_ABI
? 2
26025 : TARGET_SPE_ABI
? 3
26027 if (rs6000_returns_struct
)
26028 fprintf (asm_out_file
, "\t.gnu_attribute 12, %d\n",
26029 aix_struct_return
? 2 : 1);
26032 #ifdef POWERPC_LINUX
26034 file_end_indicate_exec_stack ();
26041 rs6000_xcoff_asm_output_anchor (rtx symbol
)
26045 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
26046 SYMBOL_REF_BLOCK_OFFSET (symbol
));
26047 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
26051 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
26053 fputs (GLOBAL_ASM_OP
, stream
);
26054 RS6000_OUTPUT_BASENAME (stream
, name
);
26055 putc ('\n', stream
);
26058 /* A get_unnamed_decl callback, used for read-only sections. PTR
26059 points to the section string variable. */
26062 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
26064 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
26065 *(const char *const *) directive
,
26066 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
26069 /* Likewise for read-write sections. */
26072 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
26074 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
26075 *(const char *const *) directive
,
26076 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
26079 /* A get_unnamed_section callback, used for switching to toc_section. */
26082 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
26084 if (TARGET_MINIMAL_TOC
)
26086 /* toc_section is always selected at least once from
26087 rs6000_xcoff_file_start, so this is guaranteed to
26088 always be defined once and only once in each file. */
26089 if (!toc_initialized
)
26091 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
26092 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
26093 toc_initialized
= 1;
26095 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
26096 (TARGET_32BIT
? "" : ",3"));
26099 fputs ("\t.toc\n", asm_out_file
);
26102 /* Implement TARGET_ASM_INIT_SECTIONS. */
26105 rs6000_xcoff_asm_init_sections (void)
26107 read_only_data_section
26108 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
26109 &xcoff_read_only_section_name
);
26111 private_data_section
26112 = get_unnamed_section (SECTION_WRITE
,
26113 rs6000_xcoff_output_readwrite_section_asm_op
,
26114 &xcoff_private_data_section_name
);
26116 read_only_private_data_section
26117 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
26118 &xcoff_private_data_section_name
);
26121 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
26123 readonly_data_section
= read_only_data_section
;
26124 exception_section
= data_section
;
26128 rs6000_xcoff_reloc_rw_mask (void)
26134 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
26135 tree decl ATTRIBUTE_UNUSED
)
26138 static const char * const suffix
[3] = { "PR", "RO", "RW" };
26140 if (flags
& SECTION_CODE
)
26142 else if (flags
& SECTION_WRITE
)
26147 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
26148 (flags
& SECTION_CODE
) ? "." : "",
26149 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
26153 rs6000_xcoff_select_section (tree decl
, int reloc
,
26154 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
26156 if (decl_readonly_section (decl
, reloc
))
26158 if (TREE_PUBLIC (decl
))
26159 return read_only_data_section
;
26161 return read_only_private_data_section
;
26165 if (TREE_PUBLIC (decl
))
26166 return data_section
;
26168 return private_data_section
;
26173 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
26177 /* Use select_section for private and uninitialized data. */
26178 if (!TREE_PUBLIC (decl
)
26179 || DECL_COMMON (decl
)
26180 || DECL_INITIAL (decl
) == NULL_TREE
26181 || DECL_INITIAL (decl
) == error_mark_node
26182 || (flag_zero_initialized_in_bss
26183 && initializer_zerop (DECL_INITIAL (decl
))))
26186 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
26187 name
= (*targetm
.strip_name_encoding
) (name
);
26188 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
26191 /* Select section for constant in constant pool.
26193 On RS/6000, all constants are in the private read-only data area.
26194 However, if this is being placed in the TOC it must be output as a
26198 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
26199 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
26201 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
26202 return toc_section
;
26204 return read_only_private_data_section
;
26207 /* Remove any trailing [DS] or the like from the symbol name. */
26209 static const char *
26210 rs6000_xcoff_strip_name_encoding (const char *name
)
26215 len
= strlen (name
);
26216 if (name
[len
- 1] == ']')
26217 return ggc_alloc_string (name
, len
- 4);
26222 /* Section attributes. AIX is always PIC. */
26224 static unsigned int
26225 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
26227 unsigned int align
;
26228 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
26230 /* Align to at least UNIT size. */
26231 if (flags
& SECTION_CODE
)
26232 align
= MIN_UNITS_PER_WORD
;
26234 /* Increase alignment of large objects if not already stricter. */
26235 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
26236 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
26237 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
26239 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
26242 /* Output at beginning of assembler file.
26244 Initialize the section names for the RS/6000 at this point.
26246 Specify filename, including full path, to assembler.
26248 We want to go into the TOC section so at least one .toc will be emitted.
26249 Also, in order to output proper .bs/.es pairs, we need at least one static
26250 [RW] section emitted.
26252 Finally, declare mcount when profiling to make the assembler happy. */
26255 rs6000_xcoff_file_start (void)
26257 rs6000_gen_section_name (&xcoff_bss_section_name
,
26258 main_input_filename
, ".bss_");
26259 rs6000_gen_section_name (&xcoff_private_data_section_name
,
26260 main_input_filename
, ".rw_");
26261 rs6000_gen_section_name (&xcoff_read_only_section_name
,
26262 main_input_filename
, ".ro_");
26264 fputs ("\t.file\t", asm_out_file
);
26265 output_quoted_string (asm_out_file
, main_input_filename
);
26266 fputc ('\n', asm_out_file
);
26267 if (write_symbols
!= NO_DEBUG
)
26268 switch_to_section (private_data_section
);
26269 switch_to_section (text_section
);
26271 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
26272 rs6000_file_start ();
26275 /* Output at end of assembler file.
26276 On the RS/6000, referencing data should automatically pull in text. */
26279 rs6000_xcoff_file_end (void)
26281 switch_to_section (text_section
);
26282 fputs ("_section_.text:\n", asm_out_file
);
26283 switch_to_section (data_section
);
26284 fputs (TARGET_32BIT
26285 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26288 #endif /* TARGET_XCOFF */
26290 /* Compute a (partial) cost for rtx X. Return true if the complete
26291 cost has been computed, and false if subexpressions should be
26292 scanned. In either case, *TOTAL contains the cost result. */
26295 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
26298 enum machine_mode mode
= GET_MODE (x
);
26302 /* On the RS/6000, if it is valid in the insn, it is free. */
26304 if (((outer_code
== SET
26305 || outer_code
== PLUS
26306 || outer_code
== MINUS
)
26307 && (satisfies_constraint_I (x
)
26308 || satisfies_constraint_L (x
)))
26309 || (outer_code
== AND
26310 && (satisfies_constraint_K (x
)
26312 ? satisfies_constraint_L (x
)
26313 : satisfies_constraint_J (x
))
26314 || mask_operand (x
, mode
)
26316 && mask64_operand (x
, DImode
))))
26317 || ((outer_code
== IOR
|| outer_code
== XOR
)
26318 && (satisfies_constraint_K (x
)
26320 ? satisfies_constraint_L (x
)
26321 : satisfies_constraint_J (x
))))
26322 || outer_code
== ASHIFT
26323 || outer_code
== ASHIFTRT
26324 || outer_code
== LSHIFTRT
26325 || outer_code
== ROTATE
26326 || outer_code
== ROTATERT
26327 || outer_code
== ZERO_EXTRACT
26328 || (outer_code
== MULT
26329 && satisfies_constraint_I (x
))
26330 || ((outer_code
== DIV
|| outer_code
== UDIV
26331 || outer_code
== MOD
|| outer_code
== UMOD
)
26332 && exact_log2 (INTVAL (x
)) >= 0)
26333 || (outer_code
== COMPARE
26334 && (satisfies_constraint_I (x
)
26335 || satisfies_constraint_K (x
)))
26336 || ((outer_code
== EQ
|| outer_code
== NE
)
26337 && (satisfies_constraint_I (x
)
26338 || satisfies_constraint_K (x
)
26340 ? satisfies_constraint_L (x
)
26341 : satisfies_constraint_J (x
))))
26342 || (outer_code
== GTU
26343 && satisfies_constraint_I (x
))
26344 || (outer_code
== LTU
26345 && satisfies_constraint_P (x
)))
26350 else if ((outer_code
== PLUS
26351 && reg_or_add_cint_operand (x
, VOIDmode
))
26352 || (outer_code
== MINUS
26353 && reg_or_sub_cint_operand (x
, VOIDmode
))
26354 || ((outer_code
== SET
26355 || outer_code
== IOR
26356 || outer_code
== XOR
)
26358 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
26360 *total
= COSTS_N_INSNS (1);
26366 if (mode
== DImode
&& code
== CONST_DOUBLE
)
26368 if ((outer_code
== IOR
|| outer_code
== XOR
)
26369 && CONST_DOUBLE_HIGH (x
) == 0
26370 && (CONST_DOUBLE_LOW (x
)
26371 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
26376 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
26377 || ((outer_code
== SET
26378 || outer_code
== IOR
26379 || outer_code
== XOR
)
26380 && CONST_DOUBLE_HIGH (x
) == 0))
26382 *total
= COSTS_N_INSNS (1);
26392 /* When optimizing for size, MEM should be slightly more expensive
26393 than generating address, e.g., (plus (reg) (const)).
26394 L1 cache latency is about two instructions. */
26395 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26404 if (FLOAT_MODE_P (mode
))
26405 *total
= rs6000_cost
->fp
;
26407 *total
= COSTS_N_INSNS (1);
26411 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
26412 && satisfies_constraint_I (XEXP (x
, 1)))
26414 if (INTVAL (XEXP (x
, 1)) >= -256
26415 && INTVAL (XEXP (x
, 1)) <= 255)
26416 *total
= rs6000_cost
->mulsi_const9
;
26418 *total
= rs6000_cost
->mulsi_const
;
26420 else if (mode
== SFmode
)
26421 *total
= rs6000_cost
->fp
;
26422 else if (FLOAT_MODE_P (mode
))
26423 *total
= rs6000_cost
->dmul
;
26424 else if (mode
== DImode
)
26425 *total
= rs6000_cost
->muldi
;
26427 *total
= rs6000_cost
->mulsi
;
26431 if (mode
== SFmode
)
26432 *total
= rs6000_cost
->fp
;
26434 *total
= rs6000_cost
->dmul
;
26439 if (FLOAT_MODE_P (mode
))
26441 *total
= mode
== DFmode
? rs6000_cost
->ddiv
26442 : rs6000_cost
->sdiv
;
26449 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
26450 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
26452 if (code
== DIV
|| code
== MOD
)
26454 *total
= COSTS_N_INSNS (2);
26457 *total
= COSTS_N_INSNS (1);
26461 if (GET_MODE (XEXP (x
, 1)) == DImode
)
26462 *total
= rs6000_cost
->divdi
;
26464 *total
= rs6000_cost
->divsi
;
26466 /* Add in shift and subtract for MOD. */
26467 if (code
== MOD
|| code
== UMOD
)
26468 *total
+= COSTS_N_INSNS (2);
26473 *total
= COSTS_N_INSNS (4);
26477 *total
= COSTS_N_INSNS (TARGET_POPCNTD
? 1 : 6);
26481 *total
= COSTS_N_INSNS (TARGET_CMPB
? 2 : 6);
26485 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
26497 *total
= COSTS_N_INSNS (1);
26505 /* Handle mul_highpart. */
26506 if (outer_code
== TRUNCATE
26507 && GET_CODE (XEXP (x
, 0)) == MULT
)
26509 if (mode
== DImode
)
26510 *total
= rs6000_cost
->muldi
;
26512 *total
= rs6000_cost
->mulsi
;
26515 else if (outer_code
== AND
)
26518 *total
= COSTS_N_INSNS (1);
26523 if (GET_CODE (XEXP (x
, 0)) == MEM
)
26526 *total
= COSTS_N_INSNS (1);
26532 if (!FLOAT_MODE_P (mode
))
26534 *total
= COSTS_N_INSNS (1);
26540 case UNSIGNED_FLOAT
:
26543 case FLOAT_TRUNCATE
:
26544 *total
= rs6000_cost
->fp
;
26548 if (mode
== DFmode
)
26551 *total
= rs6000_cost
->fp
;
26555 switch (XINT (x
, 1))
26558 *total
= rs6000_cost
->fp
;
26570 *total
= COSTS_N_INSNS (1);
26573 else if (FLOAT_MODE_P (mode
)
26574 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26576 *total
= rs6000_cost
->fp
;
26584 /* Carry bit requires mode == Pmode.
26585 NEG or PLUS already counted so only add one. */
26587 && (outer_code
== NEG
|| outer_code
== PLUS
))
26589 *total
= COSTS_N_INSNS (1);
26592 if (outer_code
== SET
)
26594 if (XEXP (x
, 1) == const0_rtx
)
26596 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26597 *total
= COSTS_N_INSNS (8);
26599 *total
= COSTS_N_INSNS (2);
26602 else if (mode
== Pmode
)
26604 *total
= COSTS_N_INSNS (3);
26613 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
26615 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26616 *total
= COSTS_N_INSNS (8);
26618 *total
= COSTS_N_INSNS (2);
26622 if (outer_code
== COMPARE
)
26636 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26639 rs6000_debug_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
26642 bool ret
= rs6000_rtx_costs (x
, code
, outer_code
, total
, speed
);
26645 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26646 "total = %d, speed = %s, x:\n",
26647 ret
? "complete" : "scan inner",
26648 GET_RTX_NAME (code
),
26649 GET_RTX_NAME (outer_code
),
26651 speed
? "true" : "false");
26658 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26661 rs6000_debug_address_cost (rtx x
, bool speed
)
26663 int ret
= TARGET_ADDRESS_COST (x
, speed
);
26665 fprintf (stderr
, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26666 ret
, speed
? "true" : "false");
26673 /* A C expression returning the cost of moving data from a register of class
26674 CLASS1 to one of CLASS2. */
26677 rs6000_register_move_cost (enum machine_mode mode
,
26678 reg_class_t from
, reg_class_t to
)
26682 /* Moves from/to GENERAL_REGS. */
26683 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
26684 || reg_classes_intersect_p (from
, GENERAL_REGS
))
26686 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
26689 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
|| from
== VSX_REGS
)
26690 ret
= (rs6000_memory_move_cost (mode
, from
, false)
26691 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, false));
26693 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26695 else if (from
== CR_REGS
)
26698 /* Power6 has slower LR/CTR moves so make them more expensive than
26699 memory in order to bias spills to memory .*/
26700 else if (rs6000_cpu
== PROCESSOR_POWER6
26701 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
26702 ret
= 6 * hard_regno_nregs
[0][mode
];
26705 /* A move will cost one instruction per GPR moved. */
26706 ret
= 2 * hard_regno_nregs
[0][mode
];
26709 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26710 else if (VECTOR_UNIT_VSX_P (mode
)
26711 && reg_classes_intersect_p (to
, VSX_REGS
)
26712 && reg_classes_intersect_p (from
, VSX_REGS
))
26713 ret
= 2 * hard_regno_nregs
[32][mode
];
26715 /* Moving between two similar registers is just one instruction. */
26716 else if (reg_classes_intersect_p (to
, from
))
26717 ret
= (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
26719 /* Everything else has to go through GENERAL_REGS. */
26721 ret
= (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
26722 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
26724 if (TARGET_DEBUG_COST
)
26726 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26727 ret
, GET_MODE_NAME (mode
), reg_class_names
[from
],
26728 reg_class_names
[to
]);
26733 /* A C expressions returning the cost of moving data of MODE from a register to
26737 rs6000_memory_move_cost (enum machine_mode mode
, reg_class_t rclass
,
26738 bool in ATTRIBUTE_UNUSED
)
26742 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
26743 ret
= 4 * hard_regno_nregs
[0][mode
];
26744 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
26745 ret
= 4 * hard_regno_nregs
[32][mode
];
26746 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
26747 ret
= 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
26749 ret
= 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
26751 if (TARGET_DEBUG_COST
)
26753 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26754 ret
, GET_MODE_NAME (mode
), reg_class_names
[rclass
], in
);
26759 /* Returns a code for a target-specific builtin that implements
26760 reciprocal of the function, or NULL_TREE if not available. */
26763 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
26764 bool sqrt ATTRIBUTE_UNUSED
)
26766 if (optimize_insn_for_size_p ())
26772 case VSX_BUILTIN_XVSQRTDP
:
26773 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode
))
26776 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
26778 case VSX_BUILTIN_XVSQRTSP
:
26779 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode
))
26782 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V4SF
];
26791 case BUILT_IN_SQRT
:
26792 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode
))
26795 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRT
];
26797 case BUILT_IN_SQRTF
:
26798 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode
))
26801 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
26808 /* Load up a constant. If the mode is a vector mode, splat the value across
26809 all of the vector elements. */
26812 rs6000_load_constant_and_splat (enum machine_mode mode
, REAL_VALUE_TYPE dconst
)
26816 if (mode
== SFmode
|| mode
== DFmode
)
26818 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, mode
);
26819 reg
= force_reg (mode
, d
);
26821 else if (mode
== V4SFmode
)
26823 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, SFmode
);
26824 rtvec v
= gen_rtvec (4, d
, d
, d
, d
);
26825 reg
= gen_reg_rtx (mode
);
26826 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26828 else if (mode
== V2DFmode
)
26830 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, DFmode
);
26831 rtvec v
= gen_rtvec (2, d
, d
);
26832 reg
= gen_reg_rtx (mode
);
26833 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26836 gcc_unreachable ();
26841 /* Generate an FMA instruction. */
26844 rs6000_emit_madd (rtx target
, rtx m1
, rtx m2
, rtx a
)
26846 enum machine_mode mode
= GET_MODE (target
);
26849 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26850 gcc_assert (dst
!= NULL
);
26853 emit_move_insn (target
, dst
);
26856 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26859 rs6000_emit_msub (rtx target
, rtx m1
, rtx m2
, rtx a
)
26861 enum machine_mode mode
= GET_MODE (target
);
26864 /* Altivec does not support fms directly;
26865 generate in terms of fma in that case. */
26866 if (optab_handler (fms_optab
, mode
) != CODE_FOR_nothing
)
26867 dst
= expand_ternary_op (mode
, fms_optab
, m1
, m2
, a
, target
, 0);
26870 a
= expand_unop (mode
, neg_optab
, a
, NULL_RTX
, 0);
26871 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26873 gcc_assert (dst
!= NULL
);
26876 emit_move_insn (target
, dst
);
26879 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26882 rs6000_emit_nmsub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26884 enum machine_mode mode
= GET_MODE (dst
);
26887 /* This is a tad more complicated, since the fnma_optab is for
26888 a different expression: fma(-m1, m2, a), which is the same
26889 thing except in the case of signed zeros.
26891 Fortunately we know that if FMA is supported that FNMSUB is
26892 also supported in the ISA. Just expand it directly. */
26894 gcc_assert (optab_handler (fma_optab
, mode
) != CODE_FOR_nothing
);
26896 r
= gen_rtx_NEG (mode
, a
);
26897 r
= gen_rtx_FMA (mode
, m1
, m2
, r
);
26898 r
= gen_rtx_NEG (mode
, r
);
26899 emit_insn (gen_rtx_SET (VOIDmode
, dst
, r
));
26902 /* Newton-Raphson approximation of floating point divide with just 2 passes
26903 (either single precision floating point, or newer machines with higher
26904 accuracy estimates). Support both scalar and vector divide. Assumes no
26905 trapping math and finite arguments. */
26908 rs6000_emit_swdiv_high_precision (rtx dst
, rtx n
, rtx d
)
26910 enum machine_mode mode
= GET_MODE (dst
);
26911 rtx x0
, e0
, e1
, y1
, u0
, v0
;
26912 enum insn_code code
= optab_handler (smul_optab
, mode
);
26913 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26914 rtx one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26916 gcc_assert (code
!= CODE_FOR_nothing
);
26918 /* x0 = 1./d estimate */
26919 x0
= gen_reg_rtx (mode
);
26920 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26921 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26924 e0
= gen_reg_rtx (mode
);
26925 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - (d * x0) */
26927 e1
= gen_reg_rtx (mode
);
26928 rs6000_emit_madd (e1
, e0
, e0
, e0
); /* e1 = (e0 * e0) + e0 */
26930 y1
= gen_reg_rtx (mode
);
26931 rs6000_emit_madd (y1
, e1
, x0
, x0
); /* y1 = (e1 * x0) + x0 */
26933 u0
= gen_reg_rtx (mode
);
26934 emit_insn (gen_mul (u0
, n
, y1
)); /* u0 = n * y1 */
26936 v0
= gen_reg_rtx (mode
);
26937 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - (d * u0) */
26939 rs6000_emit_madd (dst
, v0
, y1
, u0
); /* dst = (v0 * y1) + u0 */
26942 /* Newton-Raphson approximation of floating point divide that has a low
26943 precision estimate. Assumes no trapping math and finite arguments. */
26946 rs6000_emit_swdiv_low_precision (rtx dst
, rtx n
, rtx d
)
26948 enum machine_mode mode
= GET_MODE (dst
);
26949 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
26950 enum insn_code code
= optab_handler (smul_optab
, mode
);
26951 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26953 gcc_assert (code
!= CODE_FOR_nothing
);
26955 one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26957 /* x0 = 1./d estimate */
26958 x0
= gen_reg_rtx (mode
);
26959 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26960 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26963 e0
= gen_reg_rtx (mode
);
26964 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - d * x0 */
26966 y1
= gen_reg_rtx (mode
);
26967 rs6000_emit_madd (y1
, e0
, x0
, x0
); /* y1 = x0 + e0 * x0 */
26969 e1
= gen_reg_rtx (mode
);
26970 emit_insn (gen_mul (e1
, e0
, e0
)); /* e1 = e0 * e0 */
26972 y2
= gen_reg_rtx (mode
);
26973 rs6000_emit_madd (y2
, e1
, y1
, y1
); /* y2 = y1 + e1 * y1 */
26975 e2
= gen_reg_rtx (mode
);
26976 emit_insn (gen_mul (e2
, e1
, e1
)); /* e2 = e1 * e1 */
26978 y3
= gen_reg_rtx (mode
);
26979 rs6000_emit_madd (y3
, e2
, y2
, y2
); /* y3 = y2 + e2 * y2 */
26981 u0
= gen_reg_rtx (mode
);
26982 emit_insn (gen_mul (u0
, n
, y3
)); /* u0 = n * y3 */
26984 v0
= gen_reg_rtx (mode
);
26985 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - d * u0 */
26987 rs6000_emit_madd (dst
, v0
, y3
, u0
); /* dst = u0 + v0 * y3 */
26990 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26991 add a reg_note saying that this was a division. Support both scalar and
26992 vector divide. Assumes no trapping math and finite arguments. */
26995 rs6000_emit_swdiv (rtx dst
, rtx n
, rtx d
, bool note_p
)
26997 enum machine_mode mode
= GET_MODE (dst
);
26999 if (RS6000_RECIP_HIGH_PRECISION_P (mode
))
27000 rs6000_emit_swdiv_high_precision (dst
, n
, d
);
27002 rs6000_emit_swdiv_low_precision (dst
, n
, d
);
27005 add_reg_note (get_last_insn (), REG_EQUAL
, gen_rtx_DIV (mode
, n
, d
));
27008 /* Newton-Raphson approximation of single/double-precision floating point
27009 rsqrt. Assumes no trapping math and finite arguments. */
27012 rs6000_emit_swrsqrt (rtx dst
, rtx src
)
27014 enum machine_mode mode
= GET_MODE (src
);
27015 rtx x0
= gen_reg_rtx (mode
);
27016 rtx y
= gen_reg_rtx (mode
);
27017 int passes
= (TARGET_RECIP_PRECISION
) ? 2 : 3;
27018 REAL_VALUE_TYPE dconst3_2
;
27021 enum insn_code code
= optab_handler (smul_optab
, mode
);
27022 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
27024 gcc_assert (code
!= CODE_FOR_nothing
);
27026 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27027 real_from_integer (&dconst3_2
, VOIDmode
, 3, 0, 0);
27028 SET_REAL_EXP (&dconst3_2
, REAL_EXP (&dconst3_2
) - 1);
27030 halfthree
= rs6000_load_constant_and_splat (mode
, dconst3_2
);
27032 /* x0 = rsqrt estimate */
27033 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
27034 gen_rtx_UNSPEC (mode
, gen_rtvec (1, src
),
27037 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27038 rs6000_emit_msub (y
, src
, halfthree
, src
);
27040 for (i
= 0; i
< passes
; i
++)
27042 rtx x1
= gen_reg_rtx (mode
);
27043 rtx u
= gen_reg_rtx (mode
);
27044 rtx v
= gen_reg_rtx (mode
);
27046 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27047 emit_insn (gen_mul (u
, x0
, x0
));
27048 rs6000_emit_nmsub (v
, y
, u
, halfthree
);
27049 emit_insn (gen_mul (x1
, x0
, v
));
27053 emit_move_insn (dst
, x0
);
27057 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27058 (Power7) targets. DST is the target, and SRC is the argument operand. */
27061 rs6000_emit_popcount (rtx dst
, rtx src
)
27063 enum machine_mode mode
= GET_MODE (dst
);
27066 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27067 if (TARGET_POPCNTD
)
27069 if (mode
== SImode
)
27070 emit_insn (gen_popcntdsi2 (dst
, src
));
27072 emit_insn (gen_popcntddi2 (dst
, src
));
27076 tmp1
= gen_reg_rtx (mode
);
27078 if (mode
== SImode
)
27080 emit_insn (gen_popcntbsi2 (tmp1
, src
));
27081 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
27083 tmp2
= force_reg (SImode
, tmp2
);
27084 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
27088 emit_insn (gen_popcntbdi2 (tmp1
, src
));
27089 tmp2
= expand_mult (DImode
, tmp1
,
27090 GEN_INT ((HOST_WIDE_INT
)
27091 0x01010101 << 32 | 0x01010101),
27093 tmp2
= force_reg (DImode
, tmp2
);
27094 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
27099 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27100 target, and SRC is the argument operand. */
27103 rs6000_emit_parity (rtx dst
, rtx src
)
27105 enum machine_mode mode
= GET_MODE (dst
);
27108 tmp
= gen_reg_rtx (mode
);
27110 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27113 if (mode
== SImode
)
27115 emit_insn (gen_popcntbsi2 (tmp
, src
));
27116 emit_insn (gen_paritysi2_cmpb (dst
, tmp
));
27120 emit_insn (gen_popcntbdi2 (tmp
, src
));
27121 emit_insn (gen_paritydi2_cmpb (dst
, tmp
));
27126 if (mode
== SImode
)
27128 /* Is mult+shift >= shift+xor+shift+xor? */
27129 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
27131 rtx tmp1
, tmp2
, tmp3
, tmp4
;
27133 tmp1
= gen_reg_rtx (SImode
);
27134 emit_insn (gen_popcntbsi2 (tmp1
, src
));
27136 tmp2
= gen_reg_rtx (SImode
);
27137 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
27138 tmp3
= gen_reg_rtx (SImode
);
27139 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
27141 tmp4
= gen_reg_rtx (SImode
);
27142 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
27143 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
27146 rs6000_emit_popcount (tmp
, src
);
27147 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
27151 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27152 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
27154 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
27156 tmp1
= gen_reg_rtx (DImode
);
27157 emit_insn (gen_popcntbdi2 (tmp1
, src
));
27159 tmp2
= gen_reg_rtx (DImode
);
27160 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
27161 tmp3
= gen_reg_rtx (DImode
);
27162 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
27164 tmp4
= gen_reg_rtx (DImode
);
27165 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
27166 tmp5
= gen_reg_rtx (DImode
);
27167 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
27169 tmp6
= gen_reg_rtx (DImode
);
27170 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
27171 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
27174 rs6000_emit_popcount (tmp
, src
);
27175 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
27179 /* Return an RTX representing where to find the function value of a
27180 function returning MODE. */
27182 rs6000_complex_function_value (enum machine_mode mode
)
27184 unsigned int regno
;
27186 enum machine_mode inner
= GET_MODE_INNER (mode
);
27187 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
27189 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27190 regno
= FP_ARG_RETURN
;
27193 regno
= GP_ARG_RETURN
;
27195 /* 32-bit is OK since it'll go in r3/r4. */
27196 if (TARGET_32BIT
&& inner_bytes
>= 4)
27197 return gen_rtx_REG (mode
, regno
);
27200 if (inner_bytes
>= 8)
27201 return gen_rtx_REG (mode
, regno
);
27203 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
27205 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
27206 GEN_INT (inner_bytes
));
27207 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
27210 /* Target hook for TARGET_FUNCTION_VALUE.
27212 On the SPE, both FPs and vectors are returned in r3.
27214 On RS/6000 an integer value is in r3 and a floating-point value is in
27215 fp1, unless -msoft-float. */
27218 rs6000_function_value (const_tree valtype
,
27219 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
27220 bool outgoing ATTRIBUTE_UNUSED
)
27222 enum machine_mode mode
;
27223 unsigned int regno
;
27225 /* Special handling for structs in darwin64. */
27227 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype
), valtype
))
27229 CUMULATIVE_ARGS valcum
;
27233 valcum
.fregno
= FP_ARG_MIN_REG
;
27234 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
27235 /* Do a trial code generation as if this were going to be passed as
27236 an argument; if any part goes in memory, we return NULL. */
27237 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, true, /* retval= */ true);
27240 /* Otherwise fall through to standard ABI rules. */
27243 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
27245 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27246 return gen_rtx_PARALLEL (DImode
,
27248 gen_rtx_EXPR_LIST (VOIDmode
,
27249 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27251 gen_rtx_EXPR_LIST (VOIDmode
,
27252 gen_rtx_REG (SImode
,
27253 GP_ARG_RETURN
+ 1),
27256 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
27258 return gen_rtx_PARALLEL (DCmode
,
27260 gen_rtx_EXPR_LIST (VOIDmode
,
27261 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27263 gen_rtx_EXPR_LIST (VOIDmode
,
27264 gen_rtx_REG (SImode
,
27265 GP_ARG_RETURN
+ 1),
27267 gen_rtx_EXPR_LIST (VOIDmode
,
27268 gen_rtx_REG (SImode
,
27269 GP_ARG_RETURN
+ 2),
27271 gen_rtx_EXPR_LIST (VOIDmode
,
27272 gen_rtx_REG (SImode
,
27273 GP_ARG_RETURN
+ 3),
27277 mode
= TYPE_MODE (valtype
);
27278 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
27279 || POINTER_TYPE_P (valtype
))
27280 mode
= TARGET_32BIT
? SImode
: DImode
;
27282 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27283 /* _Decimal128 must use an even/odd register pair. */
27284 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
27285 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
27286 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
27287 regno
= FP_ARG_RETURN
;
27288 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
27289 && targetm
.calls
.split_complex_arg
)
27290 return rs6000_complex_function_value (mode
);
27291 else if (TREE_CODE (valtype
) == VECTOR_TYPE
27292 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
27293 && ALTIVEC_VECTOR_MODE (mode
))
27294 regno
= ALTIVEC_ARG_RETURN
;
27295 else if (TREE_CODE (valtype
) == VECTOR_TYPE
27296 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
27297 && VSX_VECTOR_MODE (mode
))
27298 regno
= ALTIVEC_ARG_RETURN
;
27299 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
27300 && (mode
== DFmode
|| mode
== DCmode
27301 || mode
== TFmode
|| mode
== TCmode
))
27302 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
27304 regno
= GP_ARG_RETURN
;
27306 return gen_rtx_REG (mode
, regno
);
27309 /* Define how to find the value returned by a library function
27310 assuming the value has mode MODE. */
27312 rs6000_libcall_value (enum machine_mode mode
)
27314 unsigned int regno
;
27316 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
27318 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27319 return gen_rtx_PARALLEL (DImode
,
27321 gen_rtx_EXPR_LIST (VOIDmode
,
27322 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27324 gen_rtx_EXPR_LIST (VOIDmode
,
27325 gen_rtx_REG (SImode
,
27326 GP_ARG_RETURN
+ 1),
27330 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27331 /* _Decimal128 must use an even/odd register pair. */
27332 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
27333 else if (SCALAR_FLOAT_MODE_P (mode
)
27334 && TARGET_HARD_FLOAT
&& TARGET_FPRS
27335 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
27336 regno
= FP_ARG_RETURN
;
27337 else if (ALTIVEC_VECTOR_MODE (mode
)
27338 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
27339 regno
= ALTIVEC_ARG_RETURN
;
27340 else if (VSX_VECTOR_MODE (mode
)
27341 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
)
27342 regno
= ALTIVEC_ARG_RETURN
;
27343 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
27344 return rs6000_complex_function_value (mode
);
27345 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
27346 && (mode
== DFmode
|| mode
== DCmode
27347 || mode
== TFmode
|| mode
== TCmode
))
27348 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
27350 regno
= GP_ARG_RETURN
;
27352 return gen_rtx_REG (mode
, regno
);
27356 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27357 Frame pointer elimination is automatically handled.
27359 For the RS/6000, if frame pointer elimination is being done, we would like
27360 to convert ap into fp, not sp.
27362 We need r30 if -mminimal-toc was specified, and there are constant pool
27366 rs6000_can_eliminate (const int from
, const int to
)
27368 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
27369 ? ! frame_pointer_needed
27370 : from
== RS6000_PIC_OFFSET_TABLE_REGNUM
27371 ? ! TARGET_MINIMAL_TOC
|| TARGET_NO_TOC
|| get_pool_size () == 0
27375 /* Define the offset between two registers, FROM to be eliminated and its
27376 replacement TO, at the start of a routine. */
27378 rs6000_initial_elimination_offset (int from
, int to
)
27380 rs6000_stack_t
*info
= rs6000_stack_info ();
27381 HOST_WIDE_INT offset
;
27383 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27384 offset
= info
->push_p
? 0 : -info
->total_size
;
27385 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27387 offset
= info
->push_p
? 0 : -info
->total_size
;
27388 if (FRAME_GROWS_DOWNWARD
)
27389 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
27391 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
27392 offset
= FRAME_GROWS_DOWNWARD
27393 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
27395 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
27396 offset
= info
->total_size
;
27397 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27398 offset
= info
->push_p
? info
->total_size
: 0;
27399 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
27402 gcc_unreachable ();
27408 rs6000_dwarf_register_span (rtx reg
)
27412 unsigned regno
= REGNO (reg
);
27413 enum machine_mode mode
= GET_MODE (reg
);
27417 && (SPE_VECTOR_MODE (GET_MODE (reg
))
27418 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
27419 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
27424 regno
= REGNO (reg
);
27426 /* The duality of the SPE register size wreaks all kinds of havoc.
27427 This is a way of distinguishing r0 in 32-bits from r0 in
27429 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
27430 gcc_assert (words
<= 4);
27431 for (i
= 0; i
< words
; i
++, regno
++)
27433 if (BYTES_BIG_ENDIAN
)
27435 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
27436 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
27440 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
27441 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
27445 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
27448 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27451 rs6000_init_dwarf_reg_sizes_extra (tree address
)
27456 enum machine_mode mode
= TYPE_MODE (char_type_node
);
27457 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
27458 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
27459 rtx value
= gen_int_mode (4, mode
);
27461 for (i
= 1201; i
< 1232; i
++)
27463 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
27464 HOST_WIDE_INT offset
27465 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
27467 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
27472 /* Map internal gcc register numbers to DWARF2 register numbers. */
27475 rs6000_dbx_register_number (unsigned int regno
)
27477 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
27479 if (regno
== MQ_REGNO
)
27481 if (regno
== LR_REGNO
)
27483 if (regno
== CTR_REGNO
)
27485 if (CR_REGNO_P (regno
))
27486 return regno
- CR0_REGNO
+ 86;
27487 if (regno
== CA_REGNO
)
27488 return 101; /* XER */
27489 if (ALTIVEC_REGNO_P (regno
))
27490 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
27491 if (regno
== VRSAVE_REGNO
)
27493 if (regno
== VSCR_REGNO
)
27495 if (regno
== SPE_ACC_REGNO
)
27497 if (regno
== SPEFSCR_REGNO
)
27499 /* SPE high reg number. We get these values of regno from
27500 rs6000_dwarf_register_span. */
27501 gcc_assert (regno
>= 1200 && regno
< 1232);
27505 /* target hook eh_return_filter_mode */
27506 static enum machine_mode
27507 rs6000_eh_return_filter_mode (void)
27509 return TARGET_32BIT
? SImode
: word_mode
;
27512 /* Target hook for scalar_mode_supported_p. */
27514 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
27516 if (DECIMAL_FLOAT_MODE_P (mode
))
27517 return default_decimal_float_supported_p ();
27519 return default_scalar_mode_supported_p (mode
);
27522 /* Target hook for vector_mode_supported_p. */
27524 rs6000_vector_mode_supported_p (enum machine_mode mode
)
27527 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
27530 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
27533 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
27540 /* Target hook for invalid_arg_for_unprototyped_fn. */
27541 static const char *
27542 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
27544 return (!rs6000_darwin64_abi
27546 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
27547 && (funcdecl
== NULL_TREE
27548 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
27549 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
27550 ? N_("AltiVec argument passed to unprototyped function")
27554 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27555 setup by using __stack_chk_fail_local hidden function instead of
27556 calling __stack_chk_fail directly. Otherwise it is better to call
27557 __stack_chk_fail directly. */
27560 rs6000_stack_protect_fail (void)
27562 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
27563 ? default_hidden_stack_protect_fail ()
27564 : default_external_stack_protect_fail ();
27568 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
27569 int num_operands ATTRIBUTE_UNUSED
)
27571 if (rs6000_warn_cell_microcode
)
27574 int insn_code_number
= recog_memoized (insn
);
27575 location_t location
= locator_location (INSN_LOCATOR (insn
));
27577 /* Punt on insns we cannot recognize. */
27578 if (insn_code_number
< 0)
27581 temp
= get_insn_template (insn_code_number
, insn
);
27583 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
27584 warning_at (location
, OPT_mwarn_cell_microcode
,
27585 "emitting microcode insn %s\t[%s] #%d",
27586 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27587 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
27588 warning_at (location
, OPT_mwarn_cell_microcode
,
27589 "emitting conditional microcode insn %s\t[%s] #%d",
27590 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27595 /* Mask options that we want to support inside of attribute((target)) and
27596 #pragma GCC target operations. Note, we do not include things like
27597 64/32-bit, endianess, hard/soft floating point, etc. that would have
27598 different calling sequences. */
27600 struct rs6000_opt_mask
{
27601 const char *name
; /* option name */
27602 int mask
; /* mask to set */
27603 bool invert
; /* invert sense of mask */
27604 bool valid_target
; /* option is a target option */
27607 static struct rs6000_opt_mask
const rs6000_opt_masks
[] =
27609 { "altivec", MASK_ALTIVEC
, false, true },
27610 { "cmpb", MASK_CMPB
, false, true },
27611 { "dlmzb", MASK_DLMZB
, false, true },
27612 { "fprnd", MASK_FPRND
, false, true },
27613 { "hard-dfp", MASK_DFP
, false, true },
27614 { "isel", MASK_ISEL
, false, true },
27615 { "mfcrf", MASK_MFCRF
, false, true },
27616 { "mfpgpr", MASK_MFPGPR
, false, true },
27617 { "mulhw", MASK_MULHW
, false, true },
27618 { "multiple", MASK_MULTIPLE
, false, true },
27619 { "update", MASK_NO_UPDATE
, true , true },
27620 { "popcntb", MASK_POPCNTB
, false, true },
27621 { "popcntd", MASK_POPCNTD
, false, true },
27622 { "powerpc-gfxopt", MASK_PPC_GFXOPT
, false, true },
27623 { "powerpc-gpopt", MASK_PPC_GPOPT
, false, true },
27624 { "recip-precision", MASK_RECIP_PRECISION
, false, true },
27625 { "string", MASK_STRING
, false, true },
27626 { "vsx", MASK_VSX
, false, true },
27629 { "aix64", MASK_64BIT
, false, false },
27630 { "aix32", MASK_64BIT
, true, false },
27632 { "64", MASK_64BIT
, false, false },
27633 { "32", MASK_64BIT
, true, false },
27637 { "eabi", MASK_EABI
, false, false },
27639 #ifdef MASK_LITTLE_ENDIAN
27640 { "little", MASK_LITTLE_ENDIAN
, false, false },
27641 { "big", MASK_LITTLE_ENDIAN
, true, false },
27643 #ifdef MASK_RELOCATABLE
27644 { "relocatable", MASK_RELOCATABLE
, false, false },
27646 #ifdef MASK_STRICT_ALIGN
27647 { "strict-align", MASK_STRICT_ALIGN
, false, false },
27649 { "power", MASK_POWER
, false, false },
27650 { "power2", MASK_POWER2
, false, false },
27651 { "powerpc", MASK_POWERPC
, false, false },
27652 { "soft-float", MASK_SOFT_FLOAT
, false, false },
27653 { "string", MASK_STRING
, false, false },
27656 /* Option variables that we want to support inside attribute((target)) and
27657 #pragma GCC target operations. */
27659 struct rs6000_opt_var
{
27660 const char *name
; /* option name */
27661 size_t global_offset
; /* offset of the option in global_options. */
27662 size_t target_offset
; /* offset of the option in target optiosn. */
27665 static struct rs6000_opt_var
const rs6000_opt_vars
[] =
27668 offsetof (struct gcc_options
, x_TARGET_FRIZ
),
27669 offsetof (struct cl_target_option
, x_TARGET_FRIZ
), },
27670 { "avoid-indexed-addresses",
27671 offsetof (struct gcc_options
, x_TARGET_AVOID_XFORM
),
27672 offsetof (struct cl_target_option
, x_TARGET_AVOID_XFORM
) },
27674 offsetof (struct gcc_options
, x_rs6000_paired_float
),
27675 offsetof (struct cl_target_option
, x_rs6000_paired_float
), },
27677 offsetof (struct gcc_options
, x_rs6000_default_long_calls
),
27678 offsetof (struct cl_target_option
, x_rs6000_default_long_calls
), },
27681 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27682 parsing. Return true if there were no errors. */
27685 rs6000_inner_target_options (tree args
, bool attr_p
)
27689 if (args
== NULL_TREE
)
27692 else if (TREE_CODE (args
) == STRING_CST
)
27694 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27697 while ((q
= strtok (p
, ",")) != NULL
)
27699 bool error_p
= false;
27700 bool not_valid_p
= false;
27701 const char *cpu_opt
= NULL
;
27704 if (strncmp (q
, "cpu=", 4) == 0)
27706 int cpu_index
= rs6000_cpu_name_lookup (q
+4);
27707 if (cpu_index
>= 0)
27708 rs6000_cpu_index
= cpu_index
;
27715 else if (strncmp (q
, "tune=", 5) == 0)
27717 int tune_index
= rs6000_cpu_name_lookup (q
+5);
27718 if (tune_index
>= 0)
27719 rs6000_tune_index
= tune_index
;
27729 bool invert
= false;
27733 if (strncmp (r
, "no-", 3) == 0)
27739 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
27740 if (strcmp (r
, rs6000_opt_masks
[i
].name
) == 0)
27742 int mask
= rs6000_opt_masks
[i
].mask
;
27744 if (!rs6000_opt_masks
[i
].valid_target
)
27745 not_valid_p
= true;
27749 target_flags_explicit
|= mask
;
27751 if (rs6000_opt_masks
[i
].invert
)
27755 target_flags
&= ~mask
;
27757 target_flags
|= mask
;
27762 if (error_p
&& !not_valid_p
)
27764 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
27765 if (strcmp (r
, rs6000_opt_vars
[i
].name
) == 0)
27767 size_t j
= rs6000_opt_vars
[i
].global_offset
;
27768 ((int *) &global_options
)[j
] = !invert
;
27777 const char *eprefix
, *esuffix
;
27782 eprefix
= "__attribute__((__target__(";
27787 eprefix
= "#pragma GCC target ";
27792 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt
, eprefix
,
27794 else if (not_valid_p
)
27795 error ("%s\"%s\"%s is not allowed", eprefix
, q
, esuffix
);
27797 error ("%s\"%s\"%s is invalid", eprefix
, q
, esuffix
);
27802 else if (TREE_CODE (args
) == TREE_LIST
)
27806 tree value
= TREE_VALUE (args
);
27809 bool ret2
= rs6000_inner_target_options (value
, attr_p
);
27813 args
= TREE_CHAIN (args
);
27815 while (args
!= NULL_TREE
);
27819 gcc_unreachable ();
27824 /* Print out the target options as a list for -mdebug=target. */
27827 rs6000_debug_target_options (tree args
, const char *prefix
)
27829 if (args
== NULL_TREE
)
27830 fprintf (stderr
, "%s<NULL>", prefix
);
27832 else if (TREE_CODE (args
) == STRING_CST
)
27834 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27837 while ((q
= strtok (p
, ",")) != NULL
)
27840 fprintf (stderr
, "%s\"%s\"", prefix
, q
);
27845 else if (TREE_CODE (args
) == TREE_LIST
)
27849 tree value
= TREE_VALUE (args
);
27852 rs6000_debug_target_options (value
, prefix
);
27855 args
= TREE_CHAIN (args
);
27857 while (args
!= NULL_TREE
);
27861 gcc_unreachable ();
27867 /* Hook to validate attribute((target("..."))). */
27870 rs6000_valid_attribute_p (tree fndecl
,
27871 tree
ARG_UNUSED (name
),
27875 struct cl_target_option cur_target
;
27877 tree old_optimize
= build_optimization_node ();
27878 tree new_target
, new_optimize
;
27879 tree func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27881 gcc_assert ((fndecl
!= NULL_TREE
) && (args
!= NULL_TREE
));
27883 if (TARGET_DEBUG_TARGET
)
27885 tree tname
= DECL_NAME (fndecl
);
27886 fprintf (stderr
, "\n==================== rs6000_valid_attribute_p:\n");
27888 fprintf (stderr
, "function: %.*s\n",
27889 (int) IDENTIFIER_LENGTH (tname
),
27890 IDENTIFIER_POINTER (tname
));
27892 fprintf (stderr
, "function: unknown\n");
27894 fprintf (stderr
, "args:");
27895 rs6000_debug_target_options (args
, " ");
27896 fprintf (stderr
, "\n");
27899 fprintf (stderr
, "flags: 0x%x\n", flags
);
27901 fprintf (stderr
, "--------------------\n");
27904 old_optimize
= build_optimization_node ();
27905 func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27907 /* If the function changed the optimization levels as well as setting target
27908 options, start with the optimizations specified. */
27909 if (func_optimize
&& func_optimize
!= old_optimize
)
27910 cl_optimization_restore (&global_options
,
27911 TREE_OPTIMIZATION (func_optimize
));
27913 /* The target attributes may also change some optimization flags, so update
27914 the optimization options if necessary. */
27915 cl_target_option_save (&cur_target
, &global_options
);
27916 rs6000_cpu_index
= rs6000_tune_index
= -1;
27917 ret
= rs6000_inner_target_options (args
, true);
27919 /* Set up any additional state. */
27922 ret
= rs6000_option_override_internal (false);
27923 new_target
= build_target_option_node ();
27928 new_optimize
= build_optimization_node ();
27935 DECL_FUNCTION_SPECIFIC_TARGET (fndecl
) = new_target
;
27937 if (old_optimize
!= new_optimize
)
27938 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
) = new_optimize
;
27941 cl_target_option_restore (&global_options
, &cur_target
);
27943 if (old_optimize
!= new_optimize
)
27944 cl_optimization_restore (&global_options
,
27945 TREE_OPTIMIZATION (old_optimize
));
27951 /* Hook to validate the current #pragma GCC target and set the state, and
27952 update the macros based on what was changed. If ARGS is NULL, then
27953 POP_TARGET is used to reset the options. */
27956 rs6000_pragma_target_parse (tree args
, tree pop_target
)
27961 if (TARGET_DEBUG_TARGET
)
27963 fprintf (stderr
, "\n==================== rs6000_pragma_target_parse\n");
27964 fprintf (stderr
, "args:");
27965 rs6000_debug_target_options (args
, " ");
27966 fprintf (stderr
, "\n");
27970 fprintf (stderr
, "pop_target:\n");
27971 debug_tree (pop_target
);
27974 fprintf (stderr
, "pop_target: <NULL>\n");
27976 fprintf (stderr
, "--------------------\n");
27982 cur_tree
= ((pop_target
)
27984 : target_option_default_node
);
27985 cl_target_option_restore (&global_options
,
27986 TREE_TARGET_OPTION (cur_tree
));
27990 rs6000_cpu_index
= rs6000_tune_index
= -1;
27991 ret
= rs6000_inner_target_options (args
, false);
27992 cur_tree
= build_target_option_node ();
27999 target_option_current_node
= cur_tree
;
28005 /* Remember the last target of rs6000_set_current_function. */
28006 static GTY(()) tree rs6000_previous_fndecl
;
28008 /* Establish appropriate back-end context for processing the function
28009 FNDECL. The argument might be NULL to indicate processing at top
28010 level, outside of any function scope. */
28012 rs6000_set_current_function (tree fndecl
)
28014 tree old_tree
= (rs6000_previous_fndecl
28015 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl
)
28018 tree new_tree
= (fndecl
28019 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl
)
28022 if (TARGET_DEBUG_TARGET
)
28024 bool print_final
= false;
28025 fprintf (stderr
, "\n==================== rs6000_set_current_function");
28028 fprintf (stderr
, ", fndecl %s (%p)",
28029 (DECL_NAME (fndecl
)
28030 ? IDENTIFIER_POINTER (DECL_NAME (fndecl
))
28031 : "<unknown>"), (void *)fndecl
);
28033 if (rs6000_previous_fndecl
)
28034 fprintf (stderr
, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl
);
28036 fprintf (stderr
, "\n");
28039 fprintf (stderr
, "\nnew fndecl target specific options:\n");
28040 debug_tree (new_tree
);
28041 print_final
= true;
28046 fprintf (stderr
, "\nold fndecl target specific options:\n");
28047 debug_tree (old_tree
);
28048 print_final
= true;
28052 fprintf (stderr
, "--------------------\n");
28055 /* Only change the context if the function changes. This hook is called
28056 several times in the course of compiling a function, and we don't want to
28057 slow things down too much or call target_reinit when it isn't safe. */
28058 if (fndecl
&& fndecl
!= rs6000_previous_fndecl
)
28060 rs6000_previous_fndecl
= fndecl
;
28061 if (old_tree
== new_tree
)
28066 cl_target_option_restore (&global_options
,
28067 TREE_TARGET_OPTION (new_tree
));
28073 struct cl_target_option
*def
28074 = TREE_TARGET_OPTION (target_option_current_node
);
28076 cl_target_option_restore (&global_options
, def
);
28083 /* Save the current options */
28086 rs6000_function_specific_save (struct cl_target_option
*ptr
)
28088 ptr
->rs6000_target_flags_explicit
= target_flags_explicit
;
28091 /* Restore the current options */
28094 rs6000_function_specific_restore (struct cl_target_option
*ptr
)
28096 target_flags_explicit
= ptr
->rs6000_target_flags_explicit
;
28097 (void) rs6000_option_override_internal (false);
28100 /* Print the current options */
28103 rs6000_function_specific_print (FILE *file
, int indent
,
28104 struct cl_target_option
*ptr
)
28107 int flags
= ptr
->x_target_flags
;
28109 /* Print the various mask options. */
28110 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
28111 if ((flags
& rs6000_opt_masks
[i
].mask
) != 0)
28113 flags
&= ~ rs6000_opt_masks
[i
].mask
;
28114 fprintf (file
, "%*s-m%s%s\n", indent
, "",
28115 rs6000_opt_masks
[i
].invert
? "no-" : "",
28116 rs6000_opt_masks
[i
].name
);
28119 /* Print the various options that are variables. */
28120 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
28122 size_t j
= rs6000_opt_vars
[i
].target_offset
;
28123 if (((signed char *) ptr
)[j
])
28124 fprintf (file
, "%*s-m%s\n", indent
, "",
28125 rs6000_opt_vars
[i
].name
);
28130 /* Hook to determine if one function can safely inline another. */
28133 rs6000_can_inline_p (tree caller
, tree callee
)
28136 tree caller_tree
= DECL_FUNCTION_SPECIFIC_TARGET (caller
);
28137 tree callee_tree
= DECL_FUNCTION_SPECIFIC_TARGET (callee
);
28139 /* If callee has no option attributes, then it is ok to inline. */
28143 /* If caller has no option attributes, but callee does then it is not ok to
28145 else if (!caller_tree
)
28150 struct cl_target_option
*caller_opts
= TREE_TARGET_OPTION (caller_tree
);
28151 struct cl_target_option
*callee_opts
= TREE_TARGET_OPTION (callee_tree
);
28153 /* Callee's options should a subset of the caller's, i.e. a vsx function
28154 can inline an altivec function but a non-vsx function can't inline a
28156 if ((caller_opts
->x_target_flags
& callee_opts
->x_target_flags
)
28157 == callee_opts
->x_target_flags
)
28161 if (TARGET_DEBUG_TARGET
)
28162 fprintf (stderr
, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28163 (DECL_NAME (caller
)
28164 ? IDENTIFIER_POINTER (DECL_NAME (caller
))
28166 (DECL_NAME (callee
)
28167 ? IDENTIFIER_POINTER (DECL_NAME (callee
))
28169 (ret
? "can" : "cannot"));
28174 /* Allocate a stack temp and fixup the address so it meets the particular
28175 memory requirements (either offetable or REG+REG addressing). */
28178 rs6000_allocate_stack_temp (enum machine_mode mode
,
28179 bool offsettable_p
,
28182 rtx stack
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
28183 rtx addr
= XEXP (stack
, 0);
28184 int strict_p
= (reload_in_progress
|| reload_completed
);
28186 if (!legitimate_indirect_address_p (addr
, strict_p
))
28189 && !rs6000_legitimate_offset_address_p (mode
, addr
, strict_p
))
28190 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
28192 else if (reg_reg_p
&& !legitimate_indexed_address_p (addr
, strict_p
))
28193 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
28199 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28200 to such a form to deal with memory reference instructions like STFIWX that
28201 only take reg+reg addressing. */
28204 rs6000_address_for_fpconvert (rtx x
)
28206 int strict_p
= (reload_in_progress
|| reload_completed
);
28209 gcc_assert (MEM_P (x
));
28210 addr
= XEXP (x
, 0);
28211 if (! legitimate_indirect_address_p (addr
, strict_p
)
28212 && ! legitimate_indexed_address_p (addr
, strict_p
))
28214 if (GET_CODE (addr
) == PRE_INC
|| GET_CODE (addr
) == PRE_DEC
)
28216 rtx reg
= XEXP (addr
, 0);
28217 HOST_WIDE_INT size
= GET_MODE_SIZE (GET_MODE (x
));
28218 rtx size_rtx
= GEN_INT ((GET_CODE (addr
) == PRE_DEC
) ? -size
: size
);
28219 gcc_assert (REG_P (reg
));
28220 emit_insn (gen_add3_insn (reg
, reg
, size_rtx
));
28223 else if (GET_CODE (addr
) == PRE_MODIFY
)
28225 rtx reg
= XEXP (addr
, 0);
28226 rtx expr
= XEXP (addr
, 1);
28227 gcc_assert (REG_P (reg
));
28228 gcc_assert (GET_CODE (expr
) == PLUS
);
28229 emit_insn (gen_add3_insn (reg
, XEXP (expr
, 0), XEXP (expr
, 1)));
28233 x
= replace_equiv_address (x
, copy_addr_to_reg (addr
));
28239 /* Given a memory reference, if it is not in the form for altivec memory
28240 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28241 convert to the altivec format. */
28244 rs6000_address_for_altivec (rtx x
)
28246 gcc_assert (MEM_P (x
));
28247 if (!altivec_indexed_or_indirect_operand (x
, GET_MODE (x
)))
28249 rtx addr
= XEXP (x
, 0);
28250 int strict_p
= (reload_in_progress
|| reload_completed
);
28252 if (!legitimate_indexed_address_p (addr
, strict_p
)
28253 && !legitimate_indirect_address_p (addr
, strict_p
))
28254 addr
= copy_to_mode_reg (Pmode
, addr
);
28256 addr
= gen_rtx_AND (Pmode
, addr
, GEN_INT (-16));
28257 x
= change_address (x
, GET_MODE (x
), addr
);
28264 #include "gt-rs6000.h"