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
14821 For misaligned 64-bit gpr loads and stores we need a register to
14822 convert an offset address to indirect. */
14825 rs6000_secondary_reload (bool in_p
,
14827 reg_class_t rclass_i
,
14828 enum machine_mode mode
,
14829 secondary_reload_info
*sri
)
14831 enum reg_class rclass
= (enum reg_class
) rclass_i
;
14832 reg_class_t ret
= ALL_REGS
;
14833 enum insn_code icode
;
14834 bool default_p
= false;
14836 sri
->icode
= CODE_FOR_nothing
;
14838 /* Convert vector loads and stores into gprs to use an additional base
14840 icode
= rs6000_vector_reload
[mode
][in_p
!= false];
14841 if (icode
!= CODE_FOR_nothing
)
14844 sri
->icode
= CODE_FOR_nothing
;
14845 sri
->extra_cost
= 0;
14847 if (GET_CODE (x
) == MEM
)
14849 rtx addr
= XEXP (x
, 0);
14851 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14852 an extra register in that case, but it would need an extra
14853 register if the addressing is reg+reg or (reg+reg)&(-16). */
14854 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
)
14856 if (!legitimate_indirect_address_p (addr
, false)
14857 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14859 sri
->icode
= icode
;
14860 /* account for splitting the loads, and converting the
14861 address from reg+reg to reg. */
14862 sri
->extra_cost
= (((TARGET_64BIT
) ? 3 : 5)
14863 + ((GET_CODE (addr
) == AND
) ? 1 : 0));
14866 /* Loads to and stores from vector registers can only do reg+reg
14867 addressing. Altivec registers can also do (reg+reg)&(-16). */
14868 else if (rclass
== VSX_REGS
|| rclass
== ALTIVEC_REGS
14869 || rclass
== FLOAT_REGS
|| rclass
== NO_REGS
)
14871 if (!VECTOR_MEM_ALTIVEC_P (mode
)
14872 && GET_CODE (addr
) == AND
14873 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14874 && INTVAL (XEXP (addr
, 1)) == -16
14875 && (legitimate_indirect_address_p (XEXP (addr
, 0), false)
14876 || legitimate_indexed_address_p (XEXP (addr
, 0), false)))
14878 sri
->icode
= icode
;
14879 sri
->extra_cost
= ((GET_CODE (XEXP (addr
, 0)) == PLUS
)
14882 else if (!legitimate_indirect_address_p (addr
, false)
14883 && (rclass
== NO_REGS
14884 || !legitimate_indexed_address_p (addr
, false)))
14886 sri
->icode
= icode
;
14887 sri
->extra_cost
= 1;
14890 icode
= CODE_FOR_nothing
;
14892 /* Any other loads, including to pseudo registers which haven't been
14893 assigned to a register yet, default to require a scratch
14897 sri
->icode
= icode
;
14898 sri
->extra_cost
= 2;
14901 else if (REG_P (x
))
14903 int regno
= true_regnum (x
);
14905 icode
= CODE_FOR_nothing
;
14906 if (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
)
14910 enum reg_class xclass
= REGNO_REG_CLASS (regno
);
14911 enum reload_reg_type rtype1
= rs6000_reload_register_type (rclass
);
14912 enum reload_reg_type rtype2
= rs6000_reload_register_type (xclass
);
14914 /* If memory is needed, use default_secondary_reload to create the
14916 if (rtype1
!= rtype2
|| rtype1
== OTHER_REGISTER_TYPE
)
14925 else if (TARGET_POWERPC64
14926 && rs6000_reload_register_type (rclass
) == GPR_REGISTER_TYPE
14928 && GET_MODE_SIZE (GET_MODE (x
)) >= UNITS_PER_WORD
)
14930 rtx addr
= XEXP (x
, 0);
14932 if (GET_CODE (addr
) == PRE_MODIFY
)
14933 addr
= XEXP (addr
, 1);
14934 else if (GET_CODE (addr
) == LO_SUM
14935 && GET_CODE (XEXP (addr
, 0)) == REG
14936 && GET_CODE (XEXP (addr
, 1)) == CONST
)
14937 addr
= XEXP (XEXP (addr
, 1), 0);
14939 if (GET_CODE (addr
) == PLUS
14940 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14941 && (INTVAL (XEXP (addr
, 1)) & 3) != 0)
14944 sri
->icode
= CODE_FOR_reload_di_load
;
14946 sri
->icode
= CODE_FOR_reload_di_store
;
14947 sri
->extra_cost
= 2;
14957 ret
= default_secondary_reload (in_p
, x
, rclass
, mode
, sri
);
14959 gcc_assert (ret
!= ALL_REGS
);
14961 if (TARGET_DEBUG_ADDR
)
14964 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14966 reg_class_names
[ret
],
14967 in_p
? "true" : "false",
14968 reg_class_names
[rclass
],
14969 GET_MODE_NAME (mode
));
14972 fprintf (stderr
, ", default secondary reload");
14974 if (sri
->icode
!= CODE_FOR_nothing
)
14975 fprintf (stderr
, ", reload func = %s, extra cost = %d\n",
14976 insn_data
[sri
->icode
].name
, sri
->extra_cost
);
14978 fprintf (stderr
, "\n");
14986 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14987 to SP+reg addressing. */
14990 rs6000_secondary_reload_inner (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
14992 int regno
= true_regnum (reg
);
14993 enum machine_mode mode
= GET_MODE (reg
);
14994 enum reg_class rclass
;
14996 rtx and_op2
= NULL_RTX
;
14999 rtx scratch_or_premodify
= scratch
;
15003 if (TARGET_DEBUG_ADDR
)
15005 fprintf (stderr
, "\nrs6000_secondary_reload_inner, type = %s\n",
15006 store_p
? "store" : "load");
15007 fprintf (stderr
, "reg:\n");
15009 fprintf (stderr
, "mem:\n");
15011 fprintf (stderr
, "scratch:\n");
15012 debug_rtx (scratch
);
15015 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
15016 gcc_assert (GET_CODE (mem
) == MEM
);
15017 rclass
= REGNO_REG_CLASS (regno
);
15018 addr
= XEXP (mem
, 0);
15022 /* GPRs can handle reg + small constant, all other addresses need to use
15023 the scratch register. */
15026 if (GET_CODE (addr
) == AND
)
15028 and_op2
= XEXP (addr
, 1);
15029 addr
= XEXP (addr
, 0);
15032 if (GET_CODE (addr
) == PRE_MODIFY
)
15034 scratch_or_premodify
= XEXP (addr
, 0);
15035 gcc_assert (REG_P (scratch_or_premodify
));
15036 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
15037 addr
= XEXP (addr
, 1);
15040 if (GET_CODE (addr
) == PLUS
15041 && (!rs6000_legitimate_offset_address_p (TImode
, addr
, false)
15042 || and_op2
!= NULL_RTX
))
15044 addr_op1
= XEXP (addr
, 0);
15045 addr_op2
= XEXP (addr
, 1);
15046 gcc_assert (legitimate_indirect_address_p (addr_op1
, false));
15048 if (!REG_P (addr_op2
)
15049 && (GET_CODE (addr_op2
) != CONST_INT
15050 || !satisfies_constraint_I (addr_op2
)))
15052 if (TARGET_DEBUG_ADDR
)
15055 "\nMove plus addr to register %s, mode = %s: ",
15056 rs6000_reg_names
[REGNO (scratch
)],
15057 GET_MODE_NAME (mode
));
15058 debug_rtx (addr_op2
);
15060 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
15061 addr_op2
= scratch
;
15064 emit_insn (gen_rtx_SET (VOIDmode
,
15065 scratch_or_premodify
,
15066 gen_rtx_PLUS (Pmode
,
15070 addr
= scratch_or_premodify
;
15071 scratch_or_premodify
= scratch
;
15073 else if (!legitimate_indirect_address_p (addr
, false)
15074 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
15076 if (TARGET_DEBUG_ADDR
)
15078 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
15079 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
15080 GET_MODE_NAME (mode
));
15083 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
15084 addr
= scratch_or_premodify
;
15085 scratch_or_premodify
= scratch
;
15089 /* Float/Altivec registers can only handle reg+reg addressing. Move
15090 other addresses into a scratch register. */
15095 /* With float regs, we need to handle the AND ourselves, since we can't
15096 use the Altivec instruction with an implicit AND -16. Allow scalar
15097 loads to float registers to use reg+offset even if VSX. */
15098 if (GET_CODE (addr
) == AND
15099 && (rclass
!= ALTIVEC_REGS
|| GET_MODE_SIZE (mode
) != 16
15100 || GET_CODE (XEXP (addr
, 1)) != CONST_INT
15101 || INTVAL (XEXP (addr
, 1)) != -16
15102 || !VECTOR_MEM_ALTIVEC_P (mode
)))
15104 and_op2
= XEXP (addr
, 1);
15105 addr
= XEXP (addr
, 0);
15108 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15109 as the address later. */
15110 if (GET_CODE (addr
) == PRE_MODIFY
15111 && (!VECTOR_MEM_VSX_P (mode
)
15112 || and_op2
!= NULL_RTX
15113 || !legitimate_indexed_address_p (XEXP (addr
, 1), false)))
15115 scratch_or_premodify
= XEXP (addr
, 0);
15116 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify
,
15118 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
15119 addr
= XEXP (addr
, 1);
15122 if (legitimate_indirect_address_p (addr
, false) /* reg */
15123 || legitimate_indexed_address_p (addr
, false) /* reg+reg */
15124 || GET_CODE (addr
) == PRE_MODIFY
/* VSX pre-modify */
15125 || (GET_CODE (addr
) == AND
/* Altivec memory */
15126 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
15127 && INTVAL (XEXP (addr
, 1)) == -16
15128 && VECTOR_MEM_ALTIVEC_P (mode
))
15129 || (rclass
== FLOAT_REGS
/* legacy float mem */
15130 && GET_MODE_SIZE (mode
) == 8
15131 && and_op2
== NULL_RTX
15132 && scratch_or_premodify
== scratch
15133 && rs6000_legitimate_offset_address_p (mode
, addr
, false)))
15136 else if (GET_CODE (addr
) == PLUS
)
15138 addr_op1
= XEXP (addr
, 0);
15139 addr_op2
= XEXP (addr
, 1);
15140 gcc_assert (REG_P (addr_op1
));
15142 if (TARGET_DEBUG_ADDR
)
15144 fprintf (stderr
, "\nMove plus addr to register %s, mode = %s: ",
15145 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
15146 debug_rtx (addr_op2
);
15148 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
15149 emit_insn (gen_rtx_SET (VOIDmode
,
15150 scratch_or_premodify
,
15151 gen_rtx_PLUS (Pmode
,
15154 addr
= scratch_or_premodify
;
15155 scratch_or_premodify
= scratch
;
15158 else if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == CONST
15159 || GET_CODE (addr
) == CONST_INT
|| REG_P (addr
))
15161 if (TARGET_DEBUG_ADDR
)
15163 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
15164 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
15165 GET_MODE_NAME (mode
));
15169 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
15170 addr
= scratch_or_premodify
;
15171 scratch_or_premodify
= scratch
;
15175 gcc_unreachable ();
15180 gcc_unreachable ();
15183 /* If the original address involved a pre-modify that we couldn't use the VSX
15184 memory instruction with update, and we haven't taken care of already,
15185 store the address in the pre-modify register and use that as the
15187 if (scratch_or_premodify
!= scratch
&& scratch_or_premodify
!= addr
)
15189 emit_insn (gen_rtx_SET (VOIDmode
, scratch_or_premodify
, addr
));
15190 addr
= scratch_or_premodify
;
15193 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15194 memory instruction, recreate the AND now, including the clobber which is
15195 generated by the general ANDSI3/ANDDI3 patterns for the
15196 andi. instruction. */
15197 if (and_op2
!= NULL_RTX
)
15199 if (! legitimate_indirect_address_p (addr
, false))
15201 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, addr
));
15205 if (TARGET_DEBUG_ADDR
)
15207 fprintf (stderr
, "\nAnd addr to register %s, mode = %s: ",
15208 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
15209 debug_rtx (and_op2
);
15212 and_rtx
= gen_rtx_SET (VOIDmode
,
15214 gen_rtx_AND (Pmode
,
15218 cc_clobber
= gen_rtx_CLOBBER (CCmode
, gen_rtx_SCRATCH (CCmode
));
15219 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
15220 gen_rtvec (2, and_rtx
, cc_clobber
)));
15224 /* Adjust the address if it changed. */
15225 if (addr
!= XEXP (mem
, 0))
15227 mem
= change_address (mem
, mode
, addr
);
15228 if (TARGET_DEBUG_ADDR
)
15229 fprintf (stderr
, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15232 /* Now create the move. */
15234 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
15236 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
15241 /* Convert reloads involving 64-bit gprs and misaligned offset
15242 addressing to use indirect addressing. */
15245 rs6000_secondary_reload_ppc64 (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
15247 int regno
= true_regnum (reg
);
15248 enum reg_class rclass
;
15250 rtx scratch_or_premodify
= scratch
;
15252 if (TARGET_DEBUG_ADDR
)
15254 fprintf (stderr
, "\nrs6000_secondary_reload_ppc64, type = %s\n",
15255 store_p
? "store" : "load");
15256 fprintf (stderr
, "reg:\n");
15258 fprintf (stderr
, "mem:\n");
15260 fprintf (stderr
, "scratch:\n");
15261 debug_rtx (scratch
);
15264 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
15265 gcc_assert (GET_CODE (mem
) == MEM
);
15266 rclass
= REGNO_REG_CLASS (regno
);
15267 gcc_assert (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
);
15268 addr
= XEXP (mem
, 0);
15270 if (GET_CODE (addr
) == PRE_MODIFY
)
15272 scratch_or_premodify
= XEXP (addr
, 0);
15273 gcc_assert (REG_P (scratch_or_premodify
));
15274 addr
= XEXP (addr
, 1);
15276 gcc_assert (GET_CODE (addr
) == PLUS
|| GET_CODE (addr
) == LO_SUM
);
15278 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
15280 mem
= replace_equiv_address_nv (mem
, scratch_or_premodify
);
15282 /* Now create the move. */
15284 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
15286 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
15291 /* Target hook to return the cover classes for Integrated Register Allocator.
15292 Cover classes is a set of non-intersected register classes covering all hard
15293 registers used for register allocation purpose. Any move between two
15294 registers of a cover class should be cheaper than load or store of the
15295 registers. The value is array of register classes with LIM_REG_CLASSES used
15298 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
15299 account for the Altivec and Floating registers being subsets of the VSX
15300 register set under VSX, but distinct register sets on pre-VSX machines. */
15302 static const reg_class_t
*
15303 rs6000_ira_cover_classes (void)
15305 static const reg_class_t cover_pre_vsx
[] = IRA_COVER_CLASSES_PRE_VSX
;
15306 static const reg_class_t cover_vsx
[] = IRA_COVER_CLASSES_VSX
;
15308 return (TARGET_VSX
) ? cover_vsx
: cover_pre_vsx
;
15311 /* Allocate a 64-bit stack slot to be used for copying SDmode
15312 values through if this function has any SDmode references. */
15315 rs6000_alloc_sdmode_stack_slot (void)
15319 gimple_stmt_iterator gsi
;
15321 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
15324 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
15326 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
15329 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
15330 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
15336 /* Check for any SDmode parameters of the function. */
15337 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= DECL_CHAIN (t
))
15339 if (TREE_TYPE (t
) == error_mark_node
)
15342 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
15343 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
15345 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
15346 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
15354 rs6000_instantiate_decls (void)
15356 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
15357 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
15360 /* Given an rtx X being reloaded into a reg required to be
15361 in class CLASS, return the class of reg to actually use.
15362 In general this is just CLASS; but on some machines
15363 in some cases it is preferable to use a more restrictive class.
15365 On the RS/6000, we have to return NO_REGS when we want to reload a
15366 floating-point CONST_DOUBLE to force it to be copied to memory.
15368 We also don't want to reload integer values into floating-point
15369 registers if we can at all help it. In fact, this can
15370 cause reload to die, if it tries to generate a reload of CTR
15371 into a FP register and discovers it doesn't have the memory location
15374 ??? Would it be a good idea to have reload do the converse, that is
15375 try to reload floating modes into FP registers if possible?
15378 static enum reg_class
15379 rs6000_preferred_reload_class (rtx x
, enum reg_class rclass
)
15381 enum machine_mode mode
= GET_MODE (x
);
15383 if (VECTOR_UNIT_VSX_P (mode
)
15384 && x
== CONST0_RTX (mode
) && VSX_REG_CLASS_P (rclass
))
15387 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
15388 && (rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
15389 && easy_vector_constant (x
, mode
))
15390 return ALTIVEC_REGS
;
15392 if (CONSTANT_P (x
) && reg_classes_intersect_p (rclass
, FLOAT_REGS
))
15395 if (GET_MODE_CLASS (mode
) == MODE_INT
&& rclass
== NON_SPECIAL_REGS
)
15396 return GENERAL_REGS
;
15398 /* For VSX, prefer the traditional registers for 64-bit values because we can
15399 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15400 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15401 prefer Altivec loads.. */
15402 if (rclass
== VSX_REGS
)
15404 if (GET_MODE_SIZE (mode
) <= 8)
15407 if (VECTOR_UNIT_ALTIVEC_P (mode
) || VECTOR_MEM_ALTIVEC_P (mode
))
15408 return ALTIVEC_REGS
;
15416 /* Debug version of rs6000_preferred_reload_class. */
15417 static enum reg_class
15418 rs6000_debug_preferred_reload_class (rtx x
, enum reg_class rclass
)
15420 enum reg_class ret
= rs6000_preferred_reload_class (x
, rclass
);
15423 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15425 reg_class_names
[ret
], reg_class_names
[rclass
],
15426 GET_MODE_NAME (GET_MODE (x
)));
15432 /* If we are copying between FP or AltiVec registers and anything else, we need
15433 a memory location. The exception is when we are targeting ppc64 and the
15434 move to/from fpr to gpr instructions are available. Also, under VSX, you
15435 can copy vector registers from the FP register set to the Altivec register
15436 set and vice versa. */
15439 rs6000_secondary_memory_needed (enum reg_class class1
,
15440 enum reg_class class2
,
15441 enum machine_mode mode
)
15443 if (class1
== class2
)
15446 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15447 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15448 between these classes. But we need memory for other things that can go in
15449 FLOAT_REGS like SFmode. */
15451 && (VECTOR_MEM_VSX_P (mode
) || VECTOR_UNIT_VSX_P (mode
))
15452 && (class1
== VSX_REGS
|| class1
== ALTIVEC_REGS
15453 || class1
== FLOAT_REGS
))
15454 return (class2
!= VSX_REGS
&& class2
!= ALTIVEC_REGS
15455 && class2
!= FLOAT_REGS
);
15457 if (class1
== VSX_REGS
|| class2
== VSX_REGS
)
15460 if (class1
== FLOAT_REGS
15461 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
15462 || ((mode
!= DFmode
)
15463 && (mode
!= DDmode
)
15464 && (mode
!= DImode
))))
15467 if (class2
== FLOAT_REGS
15468 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
15469 || ((mode
!= DFmode
)
15470 && (mode
!= DDmode
)
15471 && (mode
!= DImode
))))
15474 if (class1
== ALTIVEC_REGS
|| class2
== ALTIVEC_REGS
)
15480 /* Debug version of rs6000_secondary_memory_needed. */
15482 rs6000_debug_secondary_memory_needed (enum reg_class class1
,
15483 enum reg_class class2
,
15484 enum machine_mode mode
)
15486 bool ret
= rs6000_secondary_memory_needed (class1
, class2
, mode
);
15489 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15490 "class2 = %s, mode = %s\n",
15491 ret
? "true" : "false", reg_class_names
[class1
],
15492 reg_class_names
[class2
], GET_MODE_NAME (mode
));
15497 /* Return the register class of a scratch register needed to copy IN into
15498 or out of a register in RCLASS in MODE. If it can be done directly,
15499 NO_REGS is returned. */
15501 static enum reg_class
15502 rs6000_secondary_reload_class (enum reg_class rclass
, enum machine_mode mode
,
15507 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
15509 && MACHOPIC_INDIRECT
15513 /* We cannot copy a symbolic operand directly into anything
15514 other than BASE_REGS for TARGET_ELF. So indicate that a
15515 register from BASE_REGS is needed as an intermediate
15518 On Darwin, pic addresses require a load from memory, which
15519 needs a base register. */
15520 if (rclass
!= BASE_REGS
15521 && (GET_CODE (in
) == SYMBOL_REF
15522 || GET_CODE (in
) == HIGH
15523 || GET_CODE (in
) == LABEL_REF
15524 || GET_CODE (in
) == CONST
))
15528 if (GET_CODE (in
) == REG
)
15530 regno
= REGNO (in
);
15531 if (regno
>= FIRST_PSEUDO_REGISTER
)
15533 regno
= true_regnum (in
);
15534 if (regno
>= FIRST_PSEUDO_REGISTER
)
15538 else if (GET_CODE (in
) == SUBREG
)
15540 regno
= true_regnum (in
);
15541 if (regno
>= FIRST_PSEUDO_REGISTER
)
15547 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15549 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
15550 || (regno
>= 0 && INT_REGNO_P (regno
)))
15553 /* Constants, memory, and FP registers can go into FP registers. */
15554 if ((regno
== -1 || FP_REGNO_P (regno
))
15555 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
15556 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
15558 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15561 && (regno
== -1 || VSX_REGNO_P (regno
))
15562 && VSX_REG_CLASS_P (rclass
))
15565 /* Memory, and AltiVec registers can go into AltiVec registers. */
15566 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
15567 && rclass
== ALTIVEC_REGS
)
15570 /* We can copy among the CR registers. */
15571 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
15572 && regno
>= 0 && CR_REGNO_P (regno
))
15575 /* Otherwise, we need GENERAL_REGS. */
15576 return GENERAL_REGS
;
15579 /* Debug version of rs6000_secondary_reload_class. */
15580 static enum reg_class
15581 rs6000_debug_secondary_reload_class (enum reg_class rclass
,
15582 enum machine_mode mode
, rtx in
)
15584 enum reg_class ret
= rs6000_secondary_reload_class (rclass
, mode
, in
);
15586 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15587 "mode = %s, input rtx:\n",
15588 reg_class_names
[ret
], reg_class_names
[rclass
],
15589 GET_MODE_NAME (mode
));
15595 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15598 rs6000_cannot_change_mode_class (enum machine_mode from
,
15599 enum machine_mode to
,
15600 enum reg_class rclass
)
15602 unsigned from_size
= GET_MODE_SIZE (from
);
15603 unsigned to_size
= GET_MODE_SIZE (to
);
15605 if (from_size
!= to_size
)
15607 enum reg_class xclass
= (TARGET_VSX
) ? VSX_REGS
: FLOAT_REGS
;
15608 return ((from_size
< 8 || to_size
< 8 || TARGET_IEEEQUAD
)
15609 && reg_classes_intersect_p (xclass
, rclass
));
15612 if (TARGET_E500_DOUBLE
15613 && ((((to
) == DFmode
) + ((from
) == DFmode
)) == 1
15614 || (((to
) == TFmode
) + ((from
) == TFmode
)) == 1
15615 || (((to
) == DDmode
) + ((from
) == DDmode
)) == 1
15616 || (((to
) == TDmode
) + ((from
) == TDmode
)) == 1
15617 || (((to
) == DImode
) + ((from
) == DImode
)) == 1))
15620 /* Since the VSX register set includes traditional floating point registers
15621 and altivec registers, just check for the size being different instead of
15622 trying to check whether the modes are vector modes. Otherwise it won't
15623 allow say DF and DI to change classes. */
15624 if (TARGET_VSX
&& VSX_REG_CLASS_P (rclass
))
15625 return (from_size
!= 8 && from_size
!= 16);
15627 if (TARGET_ALTIVEC
&& rclass
== ALTIVEC_REGS
15628 && (ALTIVEC_VECTOR_MODE (from
) + ALTIVEC_VECTOR_MODE (to
)) == 1)
15631 if (TARGET_SPE
&& (SPE_VECTOR_MODE (from
) + SPE_VECTOR_MODE (to
)) == 1
15632 && reg_classes_intersect_p (GENERAL_REGS
, rclass
))
15638 /* Debug version of rs6000_cannot_change_mode_class. */
15640 rs6000_debug_cannot_change_mode_class (enum machine_mode from
,
15641 enum machine_mode to
,
15642 enum reg_class rclass
)
15644 bool ret
= rs6000_cannot_change_mode_class (from
, to
, rclass
);
15647 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15648 "to = %s, rclass = %s\n",
15649 ret
? "true" : "false",
15650 GET_MODE_NAME (from
), GET_MODE_NAME (to
),
15651 reg_class_names
[rclass
]);
15656 /* Given a comparison operation, return the bit number in CCR to test. We
15657 know this is a valid comparison.
15659 SCC_P is 1 if this is for an scc. That means that %D will have been
15660 used instead of %C, so the bits will be in different places.
15662 Return -1 if OP isn't a valid comparison for some reason. */
15665 ccr_bit (rtx op
, int scc_p
)
15667 enum rtx_code code
= GET_CODE (op
);
15668 enum machine_mode cc_mode
;
15673 if (!COMPARISON_P (op
))
15676 reg
= XEXP (op
, 0);
15678 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
15680 cc_mode
= GET_MODE (reg
);
15681 cc_regnum
= REGNO (reg
);
15682 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
15684 validate_condition_mode (code
, cc_mode
);
15686 /* When generating a sCOND operation, only positive conditions are
15689 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
15690 || code
== GTU
|| code
== LTU
);
15695 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
15697 return base_bit
+ 2;
15698 case GT
: case GTU
: case UNLE
:
15699 return base_bit
+ 1;
15700 case LT
: case LTU
: case UNGE
:
15702 case ORDERED
: case UNORDERED
:
15703 return base_bit
+ 3;
15706 /* If scc, we will have done a cror to put the bit in the
15707 unordered position. So test that bit. For integer, this is ! LT
15708 unless this is an scc insn. */
15709 return scc_p
? base_bit
+ 3 : base_bit
;
15712 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
15715 gcc_unreachable ();
15719 /* Return the GOT register. */
15722 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
15724 /* The second flow pass currently (June 1999) can't update
15725 regs_ever_live without disturbing other parts of the compiler, so
15726 update it here to make the prolog/epilogue code happy. */
15727 if (!can_create_pseudo_p ()
15728 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
15729 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
15731 crtl
->uses_pic_offset_table
= 1;
15733 return pic_offset_table_rtx
;
15736 static rs6000_stack_t stack_info
;
15738 /* Function to init struct machine_function.
15739 This will be called, via a pointer variable,
15740 from push_function_context. */
15742 static struct machine_function
*
15743 rs6000_init_machine_status (void)
15745 stack_info
.reload_completed
= 0;
15746 return ggc_alloc_cleared_machine_function ();
15749 /* These macros test for integers and extract the low-order bits. */
15751 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15752 && GET_MODE (X) == VOIDmode)
15754 #define INT_LOWPART(X) \
15755 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15758 extract_MB (rtx op
)
15761 unsigned long val
= INT_LOWPART (op
);
15763 /* If the high bit is zero, the value is the first 1 bit we find
15765 if ((val
& 0x80000000) == 0)
15767 gcc_assert (val
& 0xffffffff);
15770 while (((val
<<= 1) & 0x80000000) == 0)
15775 /* If the high bit is set and the low bit is not, or the mask is all
15776 1's, the value is zero. */
15777 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
15780 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15783 while (((val
>>= 1) & 1) != 0)
15790 extract_ME (rtx op
)
15793 unsigned long val
= INT_LOWPART (op
);
15795 /* If the low bit is zero, the value is the first 1 bit we find from
15797 if ((val
& 1) == 0)
15799 gcc_assert (val
& 0xffffffff);
15802 while (((val
>>= 1) & 1) == 0)
15808 /* If the low bit is set and the high bit is not, or the mask is all
15809 1's, the value is 31. */
15810 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
15813 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15816 while (((val
<<= 1) & 0x80000000) != 0)
15822 /* Locate some local-dynamic symbol still in use by this function
15823 so that we can print its name in some tls_ld pattern. */
15825 static const char *
15826 rs6000_get_some_local_dynamic_name (void)
15830 if (cfun
->machine
->some_ld_name
)
15831 return cfun
->machine
->some_ld_name
;
15833 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15835 && for_each_rtx (&PATTERN (insn
),
15836 rs6000_get_some_local_dynamic_name_1
, 0))
15837 return cfun
->machine
->some_ld_name
;
15839 gcc_unreachable ();
15842 /* Helper function for rs6000_get_some_local_dynamic_name. */
15845 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
15849 if (GET_CODE (x
) == SYMBOL_REF
)
15851 const char *str
= XSTR (x
, 0);
15852 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
15854 cfun
->machine
->some_ld_name
= str
;
15862 /* Write out a function code label. */
15865 rs6000_output_function_entry (FILE *file
, const char *fname
)
15867 if (fname
[0] != '.')
15869 switch (DEFAULT_ABI
)
15872 gcc_unreachable ();
15878 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
15887 RS6000_OUTPUT_BASENAME (file
, fname
);
15890 /* Print an operand. Recognize special options, documented below. */
15893 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15894 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15896 #define SMALL_DATA_RELOC "sda21"
15897 #define SMALL_DATA_REG 0
15901 print_operand (FILE *file
, rtx x
, int code
)
15905 unsigned HOST_WIDE_INT uval
;
15910 /* Write out an instruction after the call which may be replaced
15911 with glue code by the loader. This depends on the AIX version. */
15912 asm_fprintf (file
, RS6000_CALL_GLUE
);
15915 /* %a is output_address. */
15918 /* If X is a constant integer whose low-order 5 bits are zero,
15919 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15920 in the AIX assembler where "sri" with a zero shift count
15921 writes a trash instruction. */
15922 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
15929 /* If constant, low-order 16 bits of constant, unsigned.
15930 Otherwise, write normally. */
15932 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
15934 print_operand (file
, x
, 0);
15938 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15939 for 64-bit mask direction. */
15940 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
15943 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15947 /* X is a CR register. Print the number of the GT bit of the CR. */
15948 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15949 output_operand_lossage ("invalid %%c value");
15951 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
15955 /* Like 'J' but get to the GT bit only. */
15956 gcc_assert (GET_CODE (x
) == REG
);
15958 /* Bit 1 is GT bit. */
15959 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
15961 /* Add one for shift count in rlinm for scc. */
15962 fprintf (file
, "%d", i
+ 1);
15966 /* X is a CR register. Print the number of the EQ bit of the CR */
15967 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15968 output_operand_lossage ("invalid %%E value");
15970 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
15974 /* X is a CR register. Print the shift count needed to move it
15975 to the high-order four bits. */
15976 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15977 output_operand_lossage ("invalid %%f value");
15979 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
15983 /* Similar, but print the count for the rotate in the opposite
15985 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15986 output_operand_lossage ("invalid %%F value");
15988 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
15992 /* X is a constant integer. If it is negative, print "m",
15993 otherwise print "z". This is to make an aze or ame insn. */
15994 if (GET_CODE (x
) != CONST_INT
)
15995 output_operand_lossage ("invalid %%G value");
15996 else if (INTVAL (x
) >= 0)
16003 /* If constant, output low-order five bits. Otherwise, write
16006 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
16008 print_operand (file
, x
, 0);
16012 /* If constant, output low-order six bits. Otherwise, write
16015 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
16017 print_operand (file
, x
, 0);
16021 /* Print `i' if this is a constant, else nothing. */
16027 /* Write the bit number in CCR for jump. */
16028 i
= ccr_bit (x
, 0);
16030 output_operand_lossage ("invalid %%j code");
16032 fprintf (file
, "%d", i
);
16036 /* Similar, but add one for shift count in rlinm for scc and pass
16037 scc flag to `ccr_bit'. */
16038 i
= ccr_bit (x
, 1);
16040 output_operand_lossage ("invalid %%J code");
16042 /* If we want bit 31, write a shift count of zero, not 32. */
16043 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
16047 /* X must be a constant. Write the 1's complement of the
16050 output_operand_lossage ("invalid %%k value");
16052 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
16056 /* X must be a symbolic constant on ELF. Write an
16057 expression suitable for an 'addi' that adds in the low 16
16058 bits of the MEM. */
16059 if (GET_CODE (x
) == CONST
)
16061 if (GET_CODE (XEXP (x
, 0)) != PLUS
16062 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
16063 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
16064 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
16065 output_operand_lossage ("invalid %%K value");
16067 print_operand_address (file
, x
);
16068 fputs ("@l", file
);
16071 /* %l is output_asm_label. */
16074 /* Write second word of DImode or DFmode reference. Works on register
16075 or non-indexed memory only. */
16076 if (GET_CODE (x
) == REG
)
16077 fputs (reg_names
[REGNO (x
) + 1], file
);
16078 else if (GET_CODE (x
) == MEM
)
16080 /* Handle possible auto-increment. Since it is pre-increment and
16081 we have already done it, we can just use an offset of word. */
16082 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16083 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16084 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
16086 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16087 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
16090 output_address (XEXP (adjust_address_nv (x
, SImode
,
16094 if (small_data_operand (x
, GET_MODE (x
)))
16095 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16096 reg_names
[SMALL_DATA_REG
]);
16101 /* MB value for a mask operand. */
16102 if (! mask_operand (x
, SImode
))
16103 output_operand_lossage ("invalid %%m value");
16105 fprintf (file
, "%d", extract_MB (x
));
16109 /* ME value for a mask operand. */
16110 if (! mask_operand (x
, SImode
))
16111 output_operand_lossage ("invalid %%M value");
16113 fprintf (file
, "%d", extract_ME (x
));
16116 /* %n outputs the negative of its operand. */
16119 /* Write the number of elements in the vector times 4. */
16120 if (GET_CODE (x
) != PARALLEL
)
16121 output_operand_lossage ("invalid %%N value");
16123 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
16127 /* Similar, but subtract 1 first. */
16128 if (GET_CODE (x
) != PARALLEL
)
16129 output_operand_lossage ("invalid %%O value");
16131 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
16135 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16137 || INT_LOWPART (x
) < 0
16138 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
16139 output_operand_lossage ("invalid %%p value");
16141 fprintf (file
, "%d", i
);
16145 /* The operand must be an indirect memory reference. The result
16146 is the register name. */
16147 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
16148 || REGNO (XEXP (x
, 0)) >= 32)
16149 output_operand_lossage ("invalid %%P value");
16151 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
16155 /* This outputs the logical code corresponding to a boolean
16156 expression. The expression may have one or both operands
16157 negated (if one, only the first one). For condition register
16158 logical operations, it will also treat the negated
16159 CR codes as NOTs, but not handle NOTs of them. */
16161 const char *const *t
= 0;
16163 enum rtx_code code
= GET_CODE (x
);
16164 static const char * const tbl
[3][3] = {
16165 { "and", "andc", "nor" },
16166 { "or", "orc", "nand" },
16167 { "xor", "eqv", "xor" } };
16171 else if (code
== IOR
)
16173 else if (code
== XOR
)
16176 output_operand_lossage ("invalid %%q value");
16178 if (GET_CODE (XEXP (x
, 0)) != NOT
)
16182 if (GET_CODE (XEXP (x
, 1)) == NOT
)
16200 /* X is a CR register. Print the mask for `mtcrf'. */
16201 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
16202 output_operand_lossage ("invalid %%R value");
16204 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
16208 /* Low 5 bits of 32 - value */
16210 output_operand_lossage ("invalid %%s value");
16212 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
16216 /* PowerPC64 mask position. All 0's is excluded.
16217 CONST_INT 32-bit mask is considered sign-extended so any
16218 transition must occur within the CONST_INT, not on the boundary. */
16219 if (! mask64_operand (x
, DImode
))
16220 output_operand_lossage ("invalid %%S value");
16222 uval
= INT_LOWPART (x
);
16224 if (uval
& 1) /* Clear Left */
16226 #if HOST_BITS_PER_WIDE_INT > 64
16227 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
16231 else /* Clear Right */
16234 #if HOST_BITS_PER_WIDE_INT > 64
16235 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
16241 gcc_assert (i
>= 0);
16242 fprintf (file
, "%d", i
);
16246 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16247 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
16249 /* Bit 3 is OV bit. */
16250 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
16252 /* If we want bit 31, write a shift count of zero, not 32. */
16253 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
16257 /* Print the symbolic name of a branch target register. */
16258 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
16259 && REGNO (x
) != CTR_REGNO
))
16260 output_operand_lossage ("invalid %%T value");
16261 else if (REGNO (x
) == LR_REGNO
)
16262 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
16264 fputs ("ctr", file
);
16268 /* High-order 16 bits of constant for use in unsigned operand. */
16270 output_operand_lossage ("invalid %%u value");
16272 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
16273 (INT_LOWPART (x
) >> 16) & 0xffff);
16277 /* High-order 16 bits of constant for use in signed operand. */
16279 output_operand_lossage ("invalid %%v value");
16281 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
16282 (INT_LOWPART (x
) >> 16) & 0xffff);
16286 /* Print `u' if this has an auto-increment or auto-decrement. */
16287 if (GET_CODE (x
) == MEM
16288 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
16289 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
16290 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
16295 /* Print the trap code for this operand. */
16296 switch (GET_CODE (x
))
16299 fputs ("eq", file
); /* 4 */
16302 fputs ("ne", file
); /* 24 */
16305 fputs ("lt", file
); /* 16 */
16308 fputs ("le", file
); /* 20 */
16311 fputs ("gt", file
); /* 8 */
16314 fputs ("ge", file
); /* 12 */
16317 fputs ("llt", file
); /* 2 */
16320 fputs ("lle", file
); /* 6 */
16323 fputs ("lgt", file
); /* 1 */
16326 fputs ("lge", file
); /* 5 */
16329 gcc_unreachable ();
16334 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16337 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
16338 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
16340 print_operand (file
, x
, 0);
16344 /* MB value for a PowerPC64 rldic operand. */
16345 val
= (GET_CODE (x
) == CONST_INT
16346 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
16351 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
16352 if ((val
<<= 1) < 0)
16355 #if HOST_BITS_PER_WIDE_INT == 32
16356 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
16357 i
+= 32; /* zero-extend high-part was all 0's */
16358 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
16360 val
= CONST_DOUBLE_LOW (x
);
16366 for ( ; i
< 64; i
++)
16367 if ((val
<<= 1) < 0)
16372 fprintf (file
, "%d", i
+ 1);
16376 /* X is a FPR or Altivec register used in a VSX context. */
16377 if (GET_CODE (x
) != REG
|| !VSX_REGNO_P (REGNO (x
)))
16378 output_operand_lossage ("invalid %%x value");
16381 int reg
= REGNO (x
);
16382 int vsx_reg
= (FP_REGNO_P (reg
)
16384 : reg
- FIRST_ALTIVEC_REGNO
+ 32);
16386 #ifdef TARGET_REGNAMES
16387 if (TARGET_REGNAMES
)
16388 fprintf (file
, "%%vs%d", vsx_reg
);
16391 fprintf (file
, "%d", vsx_reg
);
16396 if (GET_CODE (x
) == MEM
16397 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
16398 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
16399 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
16404 /* Like 'L', for third word of TImode */
16405 if (GET_CODE (x
) == REG
)
16406 fputs (reg_names
[REGNO (x
) + 2], file
);
16407 else if (GET_CODE (x
) == MEM
)
16409 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16410 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16411 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
16412 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16413 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
16415 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
16416 if (small_data_operand (x
, GET_MODE (x
)))
16417 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16418 reg_names
[SMALL_DATA_REG
]);
16423 /* X is a SYMBOL_REF. Write out the name preceded by a
16424 period and without any trailing data in brackets. Used for function
16425 names. If we are configured for System V (or the embedded ABI) on
16426 the PowerPC, do not emit the period, since those systems do not use
16427 TOCs and the like. */
16428 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
16430 /* Mark the decl as referenced so that cgraph will output the
16432 if (SYMBOL_REF_DECL (x
))
16433 mark_decl_referenced (SYMBOL_REF_DECL (x
));
16435 /* For macho, check to see if we need a stub. */
16438 const char *name
= XSTR (x
, 0);
16440 if (darwin_emit_branch_islands
16441 && MACHOPIC_INDIRECT
16442 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
16443 name
= machopic_indirection_name (x
, /*stub_p=*/true);
16445 assemble_name (file
, name
);
16447 else if (!DOT_SYMBOLS
)
16448 assemble_name (file
, XSTR (x
, 0));
16450 rs6000_output_function_entry (file
, XSTR (x
, 0));
16454 /* Like 'L', for last word of TImode. */
16455 if (GET_CODE (x
) == REG
)
16456 fputs (reg_names
[REGNO (x
) + 3], file
);
16457 else if (GET_CODE (x
) == MEM
)
16459 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
16460 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16461 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
16462 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16463 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
16465 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
16466 if (small_data_operand (x
, GET_MODE (x
)))
16467 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16468 reg_names
[SMALL_DATA_REG
]);
16472 /* Print AltiVec or SPE memory operand. */
16477 gcc_assert (GET_CODE (x
) == MEM
);
16481 /* Ugly hack because %y is overloaded. */
16482 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
16483 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
16484 || GET_MODE (x
) == TFmode
16485 || GET_MODE (x
) == TImode
))
16487 /* Handle [reg]. */
16488 if (GET_CODE (tmp
) == REG
)
16490 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
16493 /* Handle [reg+UIMM]. */
16494 else if (GET_CODE (tmp
) == PLUS
&&
16495 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
16499 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
16501 x
= INTVAL (XEXP (tmp
, 1));
16502 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
16506 /* Fall through. Must be [reg+reg]. */
16508 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x
))
16509 && GET_CODE (tmp
) == AND
16510 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
16511 && INTVAL (XEXP (tmp
, 1)) == -16)
16512 tmp
= XEXP (tmp
, 0);
16513 else if (VECTOR_MEM_VSX_P (GET_MODE (x
))
16514 && GET_CODE (tmp
) == PRE_MODIFY
)
16515 tmp
= XEXP (tmp
, 1);
16516 if (GET_CODE (tmp
) == REG
)
16517 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
16520 if (!GET_CODE (tmp
) == PLUS
16521 || !REG_P (XEXP (tmp
, 0))
16522 || !REG_P (XEXP (tmp
, 1)))
16524 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16528 if (REGNO (XEXP (tmp
, 0)) == 0)
16529 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
16530 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
16532 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
16533 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
16539 if (GET_CODE (x
) == REG
)
16540 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
16541 else if (GET_CODE (x
) == MEM
)
16543 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16544 know the width from the mode. */
16545 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
16546 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
16547 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
16548 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
16549 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
16550 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
16551 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
16552 output_address (XEXP (XEXP (x
, 0), 1));
16554 output_address (XEXP (x
, 0));
16558 if (toc_relative_expr_p (x
))
16559 /* This hack along with a corresponding hack in
16560 rs6000_output_addr_const_extra arranges to output addends
16561 where the assembler expects to find them. eg.
16562 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16563 without this hack would be output as "x@toc+4". We
16565 output_addr_const (file
, tocrel_base
);
16567 output_addr_const (file
, x
);
16572 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
16576 output_operand_lossage ("invalid %%xn code");
16580 /* Print the address of an operand. */
16583 print_operand_address (FILE *file
, rtx x
)
16585 if (GET_CODE (x
) == REG
)
16586 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
16587 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
16588 || GET_CODE (x
) == LABEL_REF
)
16590 output_addr_const (file
, x
);
16591 if (small_data_operand (x
, GET_MODE (x
)))
16592 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
16593 reg_names
[SMALL_DATA_REG
]);
16595 gcc_assert (!TARGET_TOC
);
16597 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
16599 gcc_assert (REG_P (XEXP (x
, 0)));
16600 if (REGNO (XEXP (x
, 0)) == 0)
16601 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
16602 reg_names
[ REGNO (XEXP (x
, 0)) ]);
16604 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
16605 reg_names
[ REGNO (XEXP (x
, 1)) ]);
16607 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
16608 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
16609 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
16611 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16612 && CONSTANT_P (XEXP (x
, 1)))
16614 fprintf (file
, "lo16(");
16615 output_addr_const (file
, XEXP (x
, 1));
16616 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16619 else if (legitimate_constant_pool_address_p (x
, QImode
, true))
16621 /* This hack along with a corresponding hack in
16622 rs6000_output_addr_const_extra arranges to output addends
16623 where the assembler expects to find them. eg.
16625 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16626 without this hack would be output as "x@toc+8@l(9)". We
16627 want "x+8@toc@l(9)". */
16628 output_addr_const (file
, tocrel_base
);
16629 if (GET_CODE (x
) == LO_SUM
)
16630 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16632 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
16635 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16636 && CONSTANT_P (XEXP (x
, 1)))
16638 output_addr_const (file
, XEXP (x
, 1));
16639 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16643 gcc_unreachable ();
16646 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16649 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
16651 if (GET_CODE (x
) == UNSPEC
)
16652 switch (XINT (x
, 1))
16654 case UNSPEC_TOCREL
:
16655 gcc_assert (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
);
16656 output_addr_const (file
, XVECEXP (x
, 0, 0));
16657 if (x
== tocrel_base
&& tocrel_offset
!= const0_rtx
)
16659 if (INTVAL (tocrel_offset
) >= 0)
16660 fprintf (file
, "+");
16661 output_addr_const (file
, tocrel_offset
);
16663 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
16666 assemble_name (file
, toc_label_name
);
16668 else if (TARGET_ELF
)
16669 fputs ("@toc", file
);
16673 case UNSPEC_MACHOPIC_OFFSET
:
16674 output_addr_const (file
, XVECEXP (x
, 0, 0));
16676 machopic_output_function_base_name (file
);
16683 /* Target hook for assembling integer objects. The PowerPC version has
16684 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16685 is defined. It also needs to handle DI-mode objects on 64-bit
16689 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
16691 #ifdef RELOCATABLE_NEEDS_FIXUP
16692 /* Special handling for SI values. */
16693 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
16695 static int recurse
= 0;
16697 /* For -mrelocatable, we mark all addresses that need to be fixed up
16698 in the .fixup section. */
16699 if (TARGET_RELOCATABLE
16700 && in_section
!= toc_section
16701 && in_section
!= text_section
16702 && !unlikely_text_section_p (in_section
)
16704 && GET_CODE (x
) != CONST_INT
16705 && GET_CODE (x
) != CONST_DOUBLE
16711 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
16713 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
16714 fprintf (asm_out_file
, "\t.long\t(");
16715 output_addr_const (asm_out_file
, x
);
16716 fprintf (asm_out_file
, ")@fixup\n");
16717 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
16718 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
16719 fprintf (asm_out_file
, "\t.long\t");
16720 assemble_name (asm_out_file
, buf
);
16721 fprintf (asm_out_file
, "\n\t.previous\n");
16725 /* Remove initial .'s to turn a -mcall-aixdesc function
16726 address into the address of the descriptor, not the function
16728 else if (GET_CODE (x
) == SYMBOL_REF
16729 && XSTR (x
, 0)[0] == '.'
16730 && DEFAULT_ABI
== ABI_AIX
)
16732 const char *name
= XSTR (x
, 0);
16733 while (*name
== '.')
16736 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
16740 #endif /* RELOCATABLE_NEEDS_FIXUP */
16741 return default_assemble_integer (x
, size
, aligned_p
);
16744 #ifdef HAVE_GAS_HIDDEN
16745 /* Emit an assembler directive to set symbol visibility for DECL to
16746 VISIBILITY_TYPE. */
16749 rs6000_assemble_visibility (tree decl
, int vis
)
16751 /* Functions need to have their entry point symbol visibility set as
16752 well as their descriptor symbol visibility. */
16753 if (DEFAULT_ABI
== ABI_AIX
16755 && TREE_CODE (decl
) == FUNCTION_DECL
)
16757 static const char * const visibility_types
[] = {
16758 NULL
, "internal", "hidden", "protected"
16761 const char *name
, *type
;
16763 name
= ((* targetm
.strip_name_encoding
)
16764 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
16765 type
= visibility_types
[vis
];
16767 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
16768 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
16771 default_assemble_visibility (decl
, vis
);
16776 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
16778 /* Reversal of FP compares takes care -- an ordered compare
16779 becomes an unordered compare and vice versa. */
16780 if (mode
== CCFPmode
16781 && (!flag_finite_math_only
16782 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
16783 || code
== UNEQ
|| code
== LTGT
))
16784 return reverse_condition_maybe_unordered (code
);
16786 return reverse_condition (code
);
16789 /* Generate a compare for CODE. Return a brand-new rtx that
16790 represents the result of the compare. */
16793 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
16795 enum machine_mode comp_mode
;
16796 rtx compare_result
;
16797 enum rtx_code code
= GET_CODE (cmp
);
16798 rtx op0
= XEXP (cmp
, 0);
16799 rtx op1
= XEXP (cmp
, 1);
16801 if (FLOAT_MODE_P (mode
))
16802 comp_mode
= CCFPmode
;
16803 else if (code
== GTU
|| code
== LTU
16804 || code
== GEU
|| code
== LEU
)
16805 comp_mode
= CCUNSmode
;
16806 else if ((code
== EQ
|| code
== NE
)
16807 && GET_CODE (op0
) == SUBREG
16808 && GET_CODE (op1
) == SUBREG
16809 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
16810 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
16811 /* These are unsigned values, perhaps there will be a later
16812 ordering compare that can be shared with this one.
16813 Unfortunately we cannot detect the signedness of the operands
16814 for non-subregs. */
16815 comp_mode
= CCUNSmode
;
16817 comp_mode
= CCmode
;
16819 /* First, the compare. */
16820 compare_result
= gen_reg_rtx (comp_mode
);
16822 /* E500 FP compare instructions on the GPRs. Yuck! */
16823 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16824 && FLOAT_MODE_P (mode
))
16826 rtx cmp
, or_result
, compare_result2
;
16827 enum machine_mode op_mode
= GET_MODE (op0
);
16829 if (op_mode
== VOIDmode
)
16830 op_mode
= GET_MODE (op1
);
16832 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16833 This explains the following mess. */
16837 case EQ
: case UNEQ
: case NE
: case LTGT
:
16841 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16842 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
16843 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
16847 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16848 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
16849 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
16853 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16854 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
16855 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
16859 gcc_unreachable ();
16863 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
16867 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16868 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
16869 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
16873 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16874 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
16875 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
16879 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16880 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
16881 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
16885 gcc_unreachable ();
16889 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
16893 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16894 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
16895 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
16899 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16900 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
16901 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
16905 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16906 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
16907 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
16911 gcc_unreachable ();
16915 gcc_unreachable ();
16918 /* Synthesize LE and GE from LT/GT || EQ. */
16919 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
16925 case LE
: code
= LT
; break;
16926 case GE
: code
= GT
; break;
16927 case LEU
: code
= LT
; break;
16928 case GEU
: code
= GT
; break;
16929 default: gcc_unreachable ();
16932 compare_result2
= gen_reg_rtx (CCFPmode
);
16938 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16939 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
16940 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
16944 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16945 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
16946 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
16950 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16951 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
16952 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
16956 gcc_unreachable ();
16960 /* OR them together. */
16961 or_result
= gen_reg_rtx (CCFPmode
);
16962 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
16964 compare_result
= or_result
;
16969 if (code
== NE
|| code
== LTGT
)
16979 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16980 CLOBBERs to match cmptf_internal2 pattern. */
16981 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
16982 && GET_MODE (op0
) == TFmode
16983 && !TARGET_IEEEQUAD
16984 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
16985 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
16987 gen_rtx_SET (VOIDmode
,
16989 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
16990 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16991 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16992 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16993 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16994 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16995 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16996 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16997 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16998 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (Pmode
)))));
16999 else if (GET_CODE (op1
) == UNSPEC
17000 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
17002 rtx op1b
= XVECEXP (op1
, 0, 0);
17003 comp_mode
= CCEQmode
;
17004 compare_result
= gen_reg_rtx (CCEQmode
);
17006 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
17008 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
17011 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
17012 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
17015 /* Some kinds of FP comparisons need an OR operation;
17016 under flag_finite_math_only we don't bother. */
17017 if (FLOAT_MODE_P (mode
)
17018 && !flag_finite_math_only
17019 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
17020 && (code
== LE
|| code
== GE
17021 || code
== UNEQ
|| code
== LTGT
17022 || code
== UNGT
|| code
== UNLT
))
17024 enum rtx_code or1
, or2
;
17025 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
17026 rtx or_result
= gen_reg_rtx (CCEQmode
);
17030 case LE
: or1
= LT
; or2
= EQ
; break;
17031 case GE
: or1
= GT
; or2
= EQ
; break;
17032 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
17033 case LTGT
: or1
= LT
; or2
= GT
; break;
17034 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
17035 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
17036 default: gcc_unreachable ();
17038 validate_condition_mode (or1
, comp_mode
);
17039 validate_condition_mode (or2
, comp_mode
);
17040 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
17041 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
17042 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
17043 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
17045 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
17047 compare_result
= or_result
;
17051 validate_condition_mode (code
, GET_MODE (compare_result
));
17053 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
17057 /* Emit the RTL for an sISEL pattern. */
17060 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx operands
[])
17062 rs6000_emit_int_cmove (operands
[0], operands
[1], const1_rtx
, const0_rtx
);
17066 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
17069 enum machine_mode op_mode
;
17070 enum rtx_code cond_code
;
17071 rtx result
= operands
[0];
17073 if (TARGET_ISEL
&& (mode
== SImode
|| mode
== DImode
))
17075 rs6000_emit_sISEL (mode
, operands
);
17079 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
17080 cond_code
= GET_CODE (condition_rtx
);
17082 if (FLOAT_MODE_P (mode
)
17083 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
17087 PUT_MODE (condition_rtx
, SImode
);
17088 t
= XEXP (condition_rtx
, 0);
17090 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
17092 if (cond_code
== NE
)
17093 emit_insn (gen_e500_flip_gt_bit (t
, t
));
17095 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
17099 if (cond_code
== NE
17100 || cond_code
== GE
|| cond_code
== LE
17101 || cond_code
== GEU
|| cond_code
== LEU
17102 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
17104 rtx not_result
= gen_reg_rtx (CCEQmode
);
17105 rtx not_op
, rev_cond_rtx
;
17106 enum machine_mode cc_mode
;
17108 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
17110 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
17111 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
17112 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
17113 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
17114 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
17117 op_mode
= GET_MODE (XEXP (operands
[1], 0));
17118 if (op_mode
== VOIDmode
)
17119 op_mode
= GET_MODE (XEXP (operands
[1], 1));
17121 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
17123 PUT_MODE (condition_rtx
, DImode
);
17124 convert_move (result
, condition_rtx
, 0);
17128 PUT_MODE (condition_rtx
, SImode
);
17129 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
17133 /* Emit a branch of kind CODE to location LOC. */
17136 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
17138 rtx condition_rtx
, loc_ref
;
17140 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
17141 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
17142 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
17143 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
17144 loc_ref
, pc_rtx
)));
17147 /* Return the string to output a conditional branch to LABEL, which is
17148 the operand number of the label, or -1 if the branch is really a
17149 conditional return.
17151 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17152 condition code register and its mode specifies what kind of
17153 comparison we made.
17155 REVERSED is nonzero if we should reverse the sense of the comparison.
17157 INSN is the insn. */
17160 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
17162 static char string
[64];
17163 enum rtx_code code
= GET_CODE (op
);
17164 rtx cc_reg
= XEXP (op
, 0);
17165 enum machine_mode mode
= GET_MODE (cc_reg
);
17166 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
17167 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
17168 int really_reversed
= reversed
^ need_longbranch
;
17174 validate_condition_mode (code
, mode
);
17176 /* Work out which way this really branches. We could use
17177 reverse_condition_maybe_unordered here always but this
17178 makes the resulting assembler clearer. */
17179 if (really_reversed
)
17181 /* Reversal of FP compares takes care -- an ordered compare
17182 becomes an unordered compare and vice versa. */
17183 if (mode
== CCFPmode
)
17184 code
= reverse_condition_maybe_unordered (code
);
17186 code
= reverse_condition (code
);
17189 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
17191 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17196 /* Opposite of GT. */
17205 gcc_unreachable ();
17211 /* Not all of these are actually distinct opcodes, but
17212 we distinguish them for clarity of the resulting assembler. */
17213 case NE
: case LTGT
:
17214 ccode
= "ne"; break;
17215 case EQ
: case UNEQ
:
17216 ccode
= "eq"; break;
17218 ccode
= "ge"; break;
17219 case GT
: case GTU
: case UNGT
:
17220 ccode
= "gt"; break;
17222 ccode
= "le"; break;
17223 case LT
: case LTU
: case UNLT
:
17224 ccode
= "lt"; break;
17225 case UNORDERED
: ccode
= "un"; break;
17226 case ORDERED
: ccode
= "nu"; break;
17227 case UNGE
: ccode
= "nl"; break;
17228 case UNLE
: ccode
= "ng"; break;
17230 gcc_unreachable ();
17233 /* Maybe we have a guess as to how likely the branch is.
17234 The old mnemonics don't have a way to specify this information. */
17236 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
17237 if (note
!= NULL_RTX
)
17239 /* PROB is the difference from 50%. */
17240 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
17242 /* Only hint for highly probable/improbable branches on newer
17243 cpus as static prediction overrides processor dynamic
17244 prediction. For older cpus we may as well always hint, but
17245 assume not taken for branches that are very close to 50% as a
17246 mispredicted taken branch is more expensive than a
17247 mispredicted not-taken branch. */
17248 if (rs6000_always_hint
17249 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
17250 && br_prob_note_reliable_p (note
)))
17252 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
17253 && ((prob
> 0) ^ need_longbranch
))
17261 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
17263 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
17265 /* We need to escape any '%' characters in the reg_names string.
17266 Assume they'd only be the first character.... */
17267 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
17269 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
17273 /* If the branch distance was too far, we may have to use an
17274 unconditional branch to go the distance. */
17275 if (need_longbranch
)
17276 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
17278 s
+= sprintf (s
, ",%s", label
);
17284 /* Return the string to flip the GT bit on a CR. */
17286 output_e500_flip_gt_bit (rtx dst
, rtx src
)
17288 static char string
[64];
17291 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
17292 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
17295 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
17296 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
17298 sprintf (string
, "crnot %d,%d", a
, b
);
17302 /* Return insn for VSX or Altivec comparisons. */
17305 rs6000_emit_vector_compare_inner (enum rtx_code code
, rtx op0
, rtx op1
)
17308 enum machine_mode mode
= GET_MODE (op0
);
17316 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
17322 mask
= gen_reg_rtx (mode
);
17323 emit_insn (gen_rtx_SET (VOIDmode
,
17325 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17332 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17333 DMODE is expected destination mode. This is a recursive function. */
17336 rs6000_emit_vector_compare (enum rtx_code rcode
,
17338 enum machine_mode dmode
)
17341 bool swap_operands
= false;
17342 bool try_again
= false;
17344 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode
));
17345 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
17347 /* See if the comparison works as is. */
17348 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
17356 swap_operands
= true;
17361 swap_operands
= true;
17369 /* Invert condition and try again.
17370 e.g., A != B becomes ~(A==B). */
17372 enum rtx_code rev_code
;
17373 enum insn_code nor_code
;
17376 rev_code
= reverse_condition_maybe_unordered (rcode
);
17377 if (rev_code
== UNKNOWN
)
17380 nor_code
= optab_handler (one_cmpl_optab
, dmode
);
17381 if (nor_code
== CODE_FOR_nothing
)
17384 mask2
= rs6000_emit_vector_compare (rev_code
, op0
, op1
, dmode
);
17388 mask
= gen_reg_rtx (dmode
);
17389 emit_insn (GEN_FCN (nor_code
) (mask
, mask2
));
17397 /* Try GT/GTU/LT/LTU OR EQ */
17400 enum insn_code ior_code
;
17401 enum rtx_code new_code
;
17422 gcc_unreachable ();
17425 ior_code
= optab_handler (ior_optab
, dmode
);
17426 if (ior_code
== CODE_FOR_nothing
)
17429 c_rtx
= rs6000_emit_vector_compare (new_code
, op0
, op1
, dmode
);
17433 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
, dmode
);
17437 mask
= gen_reg_rtx (dmode
);
17438 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
17456 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
17461 /* You only get two chances. */
17465 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17466 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17467 operands for the relation operation COND. */
17470 rs6000_emit_vector_cond_expr (rtx dest
, rtx op_true
, rtx op_false
,
17471 rtx cond
, rtx cc_op0
, rtx cc_op1
)
17473 enum machine_mode dest_mode
= GET_MODE (dest
);
17474 enum rtx_code rcode
= GET_CODE (cond
);
17475 enum machine_mode cc_mode
= CCmode
;
17479 bool invert_move
= false;
17481 if (VECTOR_UNIT_NONE_P (dest_mode
))
17486 /* Swap operands if we can, and fall back to doing the operation as
17487 specified, and doing a NOR to invert the test. */
17493 /* Invert condition and try again.
17494 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17495 invert_move
= true;
17496 rcode
= reverse_condition_maybe_unordered (rcode
);
17497 if (rcode
== UNKNOWN
)
17501 /* Mark unsigned tests with CCUNSmode. */
17506 cc_mode
= CCUNSmode
;
17513 /* Get the vector mask for the given relational operations. */
17514 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
17522 op_true
= op_false
;
17526 cond2
= gen_rtx_fmt_ee (NE
, cc_mode
, mask
, const0_rtx
);
17527 emit_insn (gen_rtx_SET (VOIDmode
,
17529 gen_rtx_IF_THEN_ELSE (dest_mode
,
17536 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17537 operands of the last comparison is nonzero/true, FALSE_COND if it
17538 is zero/false. Return 0 if the hardware has no such operation. */
17541 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17543 enum rtx_code code
= GET_CODE (op
);
17544 rtx op0
= XEXP (op
, 0);
17545 rtx op1
= XEXP (op
, 1);
17546 REAL_VALUE_TYPE c1
;
17547 enum machine_mode compare_mode
= GET_MODE (op0
);
17548 enum machine_mode result_mode
= GET_MODE (dest
);
17550 bool is_against_zero
;
17552 /* These modes should always match. */
17553 if (GET_MODE (op1
) != compare_mode
17554 /* In the isel case however, we can use a compare immediate, so
17555 op1 may be a small constant. */
17556 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
17558 if (GET_MODE (true_cond
) != result_mode
)
17560 if (GET_MODE (false_cond
) != result_mode
)
17563 /* First, work out if the hardware can do this at all, or
17564 if it's too slow.... */
17565 if (!FLOAT_MODE_P (compare_mode
))
17568 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
17571 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
17572 && SCALAR_FLOAT_MODE_P (compare_mode
))
17575 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
17577 /* A floating-point subtract might overflow, underflow, or produce
17578 an inexact result, thus changing the floating-point flags, so it
17579 can't be generated if we care about that. It's safe if one side
17580 of the construct is zero, since then no subtract will be
17582 if (SCALAR_FLOAT_MODE_P (compare_mode
)
17583 && flag_trapping_math
&& ! is_against_zero
)
17586 /* Eliminate half of the comparisons by switching operands, this
17587 makes the remaining code simpler. */
17588 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
17589 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
17591 code
= reverse_condition_maybe_unordered (code
);
17593 true_cond
= false_cond
;
17597 /* UNEQ and LTGT take four instructions for a comparison with zero,
17598 it'll probably be faster to use a branch here too. */
17599 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
17602 if (GET_CODE (op1
) == CONST_DOUBLE
)
17603 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
17605 /* We're going to try to implement comparisons by performing
17606 a subtract, then comparing against zero. Unfortunately,
17607 Inf - Inf is NaN which is not zero, and so if we don't
17608 know that the operand is finite and the comparison
17609 would treat EQ different to UNORDERED, we can't do it. */
17610 if (HONOR_INFINITIES (compare_mode
)
17611 && code
!= GT
&& code
!= UNGE
17612 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
17613 /* Constructs of the form (a OP b ? a : b) are safe. */
17614 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
17615 || (! rtx_equal_p (op0
, true_cond
)
17616 && ! rtx_equal_p (op1
, true_cond
))))
17619 /* At this point we know we can use fsel. */
17621 /* Reduce the comparison to a comparison against zero. */
17622 if (! is_against_zero
)
17624 temp
= gen_reg_rtx (compare_mode
);
17625 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17626 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
17628 op1
= CONST0_RTX (compare_mode
);
17631 /* If we don't care about NaNs we can reduce some of the comparisons
17632 down to faster ones. */
17633 if (! HONOR_NANS (compare_mode
))
17639 true_cond
= false_cond
;
17652 /* Now, reduce everything down to a GE. */
17659 temp
= gen_reg_rtx (compare_mode
);
17660 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17665 temp
= gen_reg_rtx (compare_mode
);
17666 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
17671 temp
= gen_reg_rtx (compare_mode
);
17672 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17673 gen_rtx_NEG (compare_mode
,
17674 gen_rtx_ABS (compare_mode
, op0
))));
17679 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17680 temp
= gen_reg_rtx (result_mode
);
17681 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17682 gen_rtx_IF_THEN_ELSE (result_mode
,
17683 gen_rtx_GE (VOIDmode
,
17685 true_cond
, false_cond
)));
17686 false_cond
= true_cond
;
17689 temp
= gen_reg_rtx (compare_mode
);
17690 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17695 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17696 temp
= gen_reg_rtx (result_mode
);
17697 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17698 gen_rtx_IF_THEN_ELSE (result_mode
,
17699 gen_rtx_GE (VOIDmode
,
17701 true_cond
, false_cond
)));
17702 true_cond
= false_cond
;
17705 temp
= gen_reg_rtx (compare_mode
);
17706 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17711 gcc_unreachable ();
17714 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
17715 gen_rtx_IF_THEN_ELSE (result_mode
,
17716 gen_rtx_GE (VOIDmode
,
17718 true_cond
, false_cond
)));
17722 /* Same as above, but for ints (isel). */
17725 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17727 rtx condition_rtx
, cr
;
17728 enum machine_mode mode
= GET_MODE (dest
);
17729 enum rtx_code cond_code
;
17730 rtx (*isel_func
) (rtx
, rtx
, rtx
, rtx
, rtx
);
17733 if (mode
!= SImode
&& (!TARGET_POWERPC64
|| mode
!= DImode
))
17736 /* We still have to do the compare, because isel doesn't do a
17737 compare, it just looks at the CRx bits set by a previous compare
17739 condition_rtx
= rs6000_generate_compare (op
, mode
);
17740 cond_code
= GET_CODE (condition_rtx
);
17741 cr
= XEXP (condition_rtx
, 0);
17742 signedp
= GET_MODE (cr
) == CCmode
;
17744 isel_func
= (mode
== SImode
17745 ? (signedp
? gen_isel_signed_si
: gen_isel_unsigned_si
)
17746 : (signedp
? gen_isel_signed_di
: gen_isel_unsigned_di
));
17750 case LT
: case GT
: case LTU
: case GTU
: case EQ
:
17751 /* isel handles these directly. */
17755 /* We need to swap the sense of the comparison. */
17758 true_cond
= false_cond
;
17760 PUT_CODE (condition_rtx
, reverse_condition (cond_code
));
17765 false_cond
= force_reg (mode
, false_cond
);
17766 if (true_cond
!= const0_rtx
)
17767 true_cond
= force_reg (mode
, true_cond
);
17769 emit_insn (isel_func (dest
, condition_rtx
, true_cond
, false_cond
, cr
));
17775 output_isel (rtx
*operands
)
17777 enum rtx_code code
;
17779 code
= GET_CODE (operands
[1]);
17781 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
17783 gcc_assert (GET_CODE (operands
[2]) == REG
17784 && GET_CODE (operands
[3]) == REG
);
17785 PUT_CODE (operands
[1], reverse_condition (code
));
17786 return "isel %0,%3,%2,%j1";
17789 return "isel %0,%2,%3,%j1";
17793 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
17795 enum machine_mode mode
= GET_MODE (op0
);
17799 /* VSX/altivec have direct min/max insns. */
17800 if ((code
== SMAX
|| code
== SMIN
)
17801 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
17802 || (mode
== SFmode
&& VECTOR_UNIT_VSX_P (DFmode
))))
17804 emit_insn (gen_rtx_SET (VOIDmode
,
17806 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17810 if (code
== SMAX
|| code
== SMIN
)
17815 if (code
== SMAX
|| code
== UMAX
)
17816 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17817 op0
, op1
, mode
, 0);
17819 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17820 op1
, op0
, mode
, 0);
17821 gcc_assert (target
);
17822 if (target
!= dest
)
17823 emit_move_insn (dest
, target
);
17826 /* Emit instructions to perform a load-reserved/store-conditional operation.
17827 The operation performed is an atomic
17828 (set M (CODE:MODE M OP))
17829 If not NULL, BEFORE is atomically set to M before the operation, and
17830 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17831 If SYNC_P then a memory barrier is emitted before the operation.
17832 Either OP or M may be wrapped in a NOT operation. */
17835 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
17836 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
17839 enum machine_mode used_mode
;
17840 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
17843 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17844 rtx shift
= NULL_RTX
;
17847 emit_insn (gen_lwsync ());
17851 /* If this is smaller than SImode, we'll have to use SImode with
17853 if (mode
== QImode
|| mode
== HImode
)
17857 if (MEM_ALIGN (used_m
) >= 32)
17860 if (BYTES_BIG_ENDIAN
)
17861 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
17863 shift
= GEN_INT (ishift
);
17864 used_m
= change_address (used_m
, SImode
, 0);
17868 rtx addrSI
, aligned_addr
;
17869 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
17871 addrSI
= gen_lowpart_common (SImode
,
17872 force_reg (Pmode
, XEXP (used_m
, 0)));
17873 addrSI
= force_reg (SImode
, addrSI
);
17874 shift
= gen_reg_rtx (SImode
);
17876 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
17877 GEN_INT (shift_mask
)));
17878 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
17880 aligned_addr
= expand_binop (Pmode
, and_optab
,
17882 GEN_INT (-4), NULL_RTX
,
17883 1, OPTAB_LIB_WIDEN
);
17884 used_m
= change_address (used_m
, SImode
, aligned_addr
);
17885 set_mem_align (used_m
, 32);
17887 /* It's safe to keep the old alias set of USED_M, because
17888 the operation is atomic and only affects the original
17892 if (GET_CODE (op
) == NOT
)
17894 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
17895 oldop
= gen_rtx_NOT (SImode
, oldop
);
17898 oldop
= lowpart_subreg (SImode
, op
, mode
);
17904 newop
= expand_binop (SImode
, and_optab
,
17905 oldop
, GEN_INT (imask
), NULL_RTX
,
17906 1, OPTAB_LIB_WIDEN
);
17907 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17910 case NOT
: /* NAND */
17911 newop
= expand_binop (SImode
, ior_optab
,
17912 oldop
, GEN_INT (~imask
), NULL_RTX
,
17913 1, OPTAB_LIB_WIDEN
);
17914 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17918 newop
= expand_binop (SImode
, ior_optab
,
17919 oldop
, GEN_INT (~imask
), NULL_RTX
,
17920 1, OPTAB_LIB_WIDEN
);
17921 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17929 newop
= expand_binop (SImode
, and_optab
,
17930 oldop
, GEN_INT (imask
), NULL_RTX
,
17931 1, OPTAB_LIB_WIDEN
);
17932 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17934 mask
= gen_reg_rtx (SImode
);
17935 emit_move_insn (mask
, GEN_INT (imask
));
17936 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
17939 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
17941 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
17942 newop
= gen_rtx_AND (SImode
, newop
, mask
);
17943 newop
= gen_rtx_IOR (SImode
, newop
,
17944 gen_rtx_AND (SImode
,
17945 gen_rtx_NOT (SImode
, mask
),
17951 gcc_unreachable ();
17955 used_mode
= SImode
;
17956 before
= gen_reg_rtx (used_mode
);
17957 after
= gen_reg_rtx (used_mode
);
17962 before
= before_param
;
17963 after
= after_param
;
17965 if (before
== NULL_RTX
)
17966 before
= gen_reg_rtx (used_mode
);
17967 if (after
== NULL_RTX
)
17968 after
= gen_reg_rtx (used_mode
);
17971 if ((code
== PLUS
|| code
== MINUS
)
17972 && used_mode
!= mode
)
17973 the_op
= op
; /* Computed above. */
17974 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
17975 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
17976 else if (code
== NOT
)
17977 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
17978 gen_rtx_NOT (used_mode
, m
),
17979 gen_rtx_NOT (used_mode
, op
));
17981 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
17983 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
17984 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
17985 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
17986 gen_rtx_UNSPEC (used_mode
,
17987 gen_rtvec (1, the_op
),
17989 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
17991 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
17992 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
17993 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
17995 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
17996 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
17998 /* Shift and mask the return values properly. */
17999 if (used_mode
!= mode
&& before_param
)
18001 emit_insn (gen_lshrsi3 (before
, before
, shift
));
18002 convert_move (before_param
, before
, 1);
18005 if (used_mode
!= mode
&& after_param
)
18007 emit_insn (gen_lshrsi3 (after
, after
, shift
));
18008 convert_move (after_param
, after
, 1);
18011 /* The previous sequence will end with a branch that's dependent on
18012 the conditional store, so placing an isync will ensure that no
18013 other instructions (especially, no load or store instructions)
18014 can start before the atomic operation completes. */
18016 emit_insn (gen_isync ());
18019 /* A subroutine of the atomic operation splitters. Jump to LABEL if
18020 COND is true. Mark the jump as unlikely to be taken. */
18023 emit_unlikely_jump (rtx cond
, rtx label
)
18025 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
18028 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
18029 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
18030 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
18033 /* A subroutine of the atomic operation splitters. Emit a load-locked
18034 instruction in MODE. */
18037 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
18039 rtx (*fn
) (rtx
, rtx
) = NULL
;
18040 if (mode
== SImode
)
18041 fn
= gen_load_locked_si
;
18042 else if (mode
== DImode
)
18043 fn
= gen_load_locked_di
;
18044 emit_insn (fn (reg
, mem
));
18047 /* A subroutine of the atomic operation splitters. Emit a store-conditional
18048 instruction in MODE. */
18051 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
18053 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
18054 if (mode
== SImode
)
18055 fn
= gen_store_conditional_si
;
18056 else if (mode
== DImode
)
18057 fn
= gen_store_conditional_di
;
18059 /* Emit sync before stwcx. to address PPC405 Erratum. */
18060 if (PPC405_ERRATUM77
)
18061 emit_insn (gen_memory_barrier ());
18063 emit_insn (fn (res
, mem
, val
));
18066 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
18067 to perform. MEM is the memory on which to operate. VAL is the second
18068 operand of the binary operator. BEFORE and AFTER are optional locations to
18069 return the value of MEM either before of after the operation. SCRATCH is
18070 a scratch register. */
18073 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
18074 rtx before
, rtx after
, rtx scratch
)
18076 enum machine_mode mode
= GET_MODE (mem
);
18077 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18079 emit_insn (gen_lwsync ());
18081 label
= gen_label_rtx ();
18082 emit_label (label
);
18083 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
18085 if (before
== NULL_RTX
)
18087 emit_load_locked (mode
, before
, mem
);
18090 x
= gen_rtx_IOR (mode
,
18091 gen_rtx_NOT (mode
, before
),
18092 gen_rtx_NOT (mode
, val
));
18093 else if (code
== AND
)
18094 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
18096 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
18098 if (after
!= NULL_RTX
)
18099 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
18100 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
18102 emit_store_conditional (mode
, cond
, mem
, scratch
);
18104 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18105 emit_unlikely_jump (x
, label
);
18107 emit_insn (gen_isync ());
18110 /* Expand an atomic compare and swap operation. MEM is the memory on which
18111 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18112 value to be stored. SCRATCH is a scratch GPR. */
18115 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
18118 enum machine_mode mode
= GET_MODE (mem
);
18119 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18121 emit_insn (gen_lwsync ());
18123 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18124 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18125 emit_label (XEXP (label1
, 0));
18127 emit_load_locked (mode
, retval
, mem
);
18129 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
18130 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
18132 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18133 emit_unlikely_jump (x
, label2
);
18135 emit_move_insn (scratch
, newval
);
18136 emit_store_conditional (mode
, cond
, mem
, scratch
);
18138 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18139 emit_unlikely_jump (x
, label1
);
18141 emit_insn (gen_isync ());
18142 emit_label (XEXP (label2
, 0));
18145 /* Expand an atomic test and set operation. MEM is the memory on which
18146 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18149 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
18151 enum machine_mode mode
= GET_MODE (mem
);
18152 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18154 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18155 emit_label (XEXP (label
, 0));
18157 emit_load_locked (mode
, retval
, mem
);
18158 emit_move_insn (scratch
, val
);
18159 emit_store_conditional (mode
, cond
, mem
, scratch
);
18161 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18162 emit_unlikely_jump (x
, label
);
18164 emit_insn (gen_isync ());
18168 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
18170 enum machine_mode mode
= GET_MODE (mem
);
18171 rtx addrSI
, align
, wdst
, shift
, mask
;
18172 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
18173 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
18175 /* Shift amount for subword relative to aligned word. */
18176 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
18177 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
18178 shift
= gen_reg_rtx (SImode
);
18179 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
18180 GEN_INT (shift_mask
)));
18181 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
18183 /* Shift and mask old value into position within word. */
18184 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
18185 oldval
= expand_binop (SImode
, and_optab
,
18186 oldval
, GEN_INT (imask
), NULL_RTX
,
18187 1, OPTAB_LIB_WIDEN
);
18188 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
18190 /* Shift and mask new value into position within word. */
18191 newval
= convert_modes (SImode
, mode
, newval
, 1);
18192 newval
= expand_binop (SImode
, and_optab
,
18193 newval
, GEN_INT (imask
), NULL_RTX
,
18194 1, OPTAB_LIB_WIDEN
);
18195 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
18197 /* Mask for insertion. */
18198 mask
= gen_reg_rtx (SImode
);
18199 emit_move_insn (mask
, GEN_INT (imask
));
18200 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
18202 /* Address of aligned word containing subword. */
18203 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
18204 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
18205 mem
= change_address (mem
, SImode
, align
);
18206 set_mem_align (mem
, 32);
18207 MEM_VOLATILE_P (mem
) = 1;
18209 wdst
= gen_reg_rtx (SImode
);
18210 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
18211 oldval
, newval
, mem
));
18213 /* Shift the result back. */
18214 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
18216 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
18220 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
18221 rtx oldval
, rtx newval
, rtx mem
,
18224 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
18226 emit_insn (gen_lwsync ());
18227 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18228 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
18229 emit_label (XEXP (label1
, 0));
18231 emit_load_locked (SImode
, scratch
, mem
);
18233 /* Mask subword within loaded value for comparison with oldval.
18234 Use UNSPEC_AND to avoid clobber.*/
18235 emit_insn (gen_rtx_SET (SImode
, dest
,
18236 gen_rtx_UNSPEC (SImode
,
18237 gen_rtvec (2, scratch
, mask
),
18240 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
18241 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
18243 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18244 emit_unlikely_jump (x
, label2
);
18246 /* Clear subword within loaded value for insertion of new value. */
18247 emit_insn (gen_rtx_SET (SImode
, scratch
,
18248 gen_rtx_AND (SImode
,
18249 gen_rtx_NOT (SImode
, mask
), scratch
)));
18250 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
18251 emit_store_conditional (SImode
, cond
, mem
, scratch
);
18253 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
18254 emit_unlikely_jump (x
, label1
);
18256 emit_insn (gen_isync ());
18257 emit_label (XEXP (label2
, 0));
18261 /* Emit instructions to move SRC to DST. Called by splitters for
18262 multi-register moves. It will emit at most one instruction for
18263 each register that is accessed; that is, it won't emit li/lis pairs
18264 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18268 rs6000_split_multireg_move (rtx dst
, rtx src
)
18270 /* The register number of the first register being moved. */
18272 /* The mode that is to be moved. */
18273 enum machine_mode mode
;
18274 /* The mode that the move is being done in, and its size. */
18275 enum machine_mode reg_mode
;
18277 /* The number of registers that will be moved. */
18280 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
18281 mode
= GET_MODE (dst
);
18282 nregs
= hard_regno_nregs
[reg
][mode
];
18283 if (FP_REGNO_P (reg
))
18284 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
18285 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
18286 else if (ALTIVEC_REGNO_P (reg
))
18287 reg_mode
= V16QImode
;
18288 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
18291 reg_mode
= word_mode
;
18292 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
18294 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
18296 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
18298 /* Move register range backwards, if we might have destructive
18301 for (i
= nregs
- 1; i
>= 0; i
--)
18302 emit_insn (gen_rtx_SET (VOIDmode
,
18303 simplify_gen_subreg (reg_mode
, dst
, mode
,
18304 i
* reg_mode_size
),
18305 simplify_gen_subreg (reg_mode
, src
, mode
,
18306 i
* reg_mode_size
)));
18312 bool used_update
= false;
18313 rtx restore_basereg
= NULL_RTX
;
18315 if (MEM_P (src
) && INT_REGNO_P (reg
))
18319 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
18320 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
18323 breg
= XEXP (XEXP (src
, 0), 0);
18324 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
18325 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
18326 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
18327 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
18328 src
= replace_equiv_address (src
, breg
);
18330 else if (! rs6000_offsettable_memref_p (src
))
18332 if (GET_CODE (XEXP (src
, 0)) == PRE_MODIFY
)
18334 rtx basereg
= XEXP (XEXP (src
, 0), 0);
18337 rtx ndst
= simplify_gen_subreg (reg_mode
, dst
, mode
, 0);
18338 emit_insn (gen_rtx_SET (VOIDmode
, ndst
,
18339 gen_rtx_MEM (reg_mode
, XEXP (src
, 0))));
18340 used_update
= true;
18343 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
18344 XEXP (XEXP (src
, 0), 1)));
18345 src
= replace_equiv_address (src
, basereg
);
18349 rtx basereg
= gen_rtx_REG (Pmode
, reg
);
18350 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
18351 src
= replace_equiv_address (src
, basereg
);
18355 breg
= XEXP (src
, 0);
18356 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
18357 breg
= XEXP (breg
, 0);
18359 /* If the base register we are using to address memory is
18360 also a destination reg, then change that register last. */
18362 && REGNO (breg
) >= REGNO (dst
)
18363 && REGNO (breg
) < REGNO (dst
) + nregs
)
18364 j
= REGNO (breg
) - REGNO (dst
);
18366 else if (MEM_P (dst
) && INT_REGNO_P (reg
))
18370 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
18371 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
18374 breg
= XEXP (XEXP (dst
, 0), 0);
18375 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
18376 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
18377 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
18379 /* We have to update the breg before doing the store.
18380 Use store with update, if available. */
18384 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
18385 emit_insn (TARGET_32BIT
18386 ? (TARGET_POWERPC64
18387 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
18388 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
18389 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
18390 used_update
= true;
18393 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
18394 dst
= replace_equiv_address (dst
, breg
);
18396 else if (!rs6000_offsettable_memref_p (dst
)
18397 && GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
18399 if (GET_CODE (XEXP (dst
, 0)) == PRE_MODIFY
)
18401 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
18404 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
18405 emit_insn (gen_rtx_SET (VOIDmode
,
18406 gen_rtx_MEM (reg_mode
, XEXP (dst
, 0)), nsrc
));
18407 used_update
= true;
18410 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
18411 XEXP (XEXP (dst
, 0), 1)));
18412 dst
= replace_equiv_address (dst
, basereg
);
18416 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
18417 rtx offsetreg
= XEXP (XEXP (dst
, 0), 1);
18418 gcc_assert (GET_CODE (XEXP (dst
, 0)) == PLUS
18420 && REG_P (offsetreg
)
18421 && REGNO (basereg
) != REGNO (offsetreg
));
18422 if (REGNO (basereg
) == 0)
18424 rtx tmp
= offsetreg
;
18425 offsetreg
= basereg
;
18428 emit_insn (gen_add3_insn (basereg
, basereg
, offsetreg
));
18429 restore_basereg
= gen_sub3_insn (basereg
, basereg
, offsetreg
);
18430 dst
= replace_equiv_address (dst
, basereg
);
18433 else if (GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
18434 gcc_assert (rs6000_offsettable_memref_p (dst
));
18437 for (i
= 0; i
< nregs
; i
++)
18439 /* Calculate index to next subword. */
18444 /* If compiler already emitted move of first word by
18445 store with update, no need to do anything. */
18446 if (j
== 0 && used_update
)
18449 emit_insn (gen_rtx_SET (VOIDmode
,
18450 simplify_gen_subreg (reg_mode
, dst
, mode
,
18451 j
* reg_mode_size
),
18452 simplify_gen_subreg (reg_mode
, src
, mode
,
18453 j
* reg_mode_size
)));
18455 if (restore_basereg
!= NULL_RTX
)
18456 emit_insn (restore_basereg
);
18461 /* This page contains routines that are used to determine what the
18462 function prologue and epilogue code will do and write them out. */
18464 /* Return the first fixed-point register that is required to be
18465 saved. 32 if none. */
18468 first_reg_to_save (void)
18472 /* Find lowest numbered live register. */
18473 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
18474 if (df_regs_ever_live_p (first_reg
)
18475 && (! call_used_regs
[first_reg
]
18476 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
18477 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
18478 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
18479 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
18484 && crtl
->uses_pic_offset_table
18485 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18486 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
18492 /* Similar, for FP regs. */
18495 first_fp_reg_to_save (void)
18499 /* Find lowest numbered live register. */
18500 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
18501 if (df_regs_ever_live_p (first_reg
))
18507 /* Similar, for AltiVec regs. */
18510 first_altivec_reg_to_save (void)
18514 /* Stack frame remains as is unless we are in AltiVec ABI. */
18515 if (! TARGET_ALTIVEC_ABI
)
18516 return LAST_ALTIVEC_REGNO
+ 1;
18518 /* On Darwin, the unwind routines are compiled without
18519 TARGET_ALTIVEC, and use save_world to save/restore the
18520 altivec registers when necessary. */
18521 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
18522 && ! TARGET_ALTIVEC
)
18523 return FIRST_ALTIVEC_REGNO
+ 20;
18525 /* Find lowest numbered live register. */
18526 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
18527 if (df_regs_ever_live_p (i
))
18533 /* Return a 32-bit mask of the AltiVec registers we need to set in
18534 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18535 the 32-bit word is 0. */
18537 static unsigned int
18538 compute_vrsave_mask (void)
18540 unsigned int i
, mask
= 0;
18542 /* On Darwin, the unwind routines are compiled without
18543 TARGET_ALTIVEC, and use save_world to save/restore the
18544 call-saved altivec registers when necessary. */
18545 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
18546 && ! TARGET_ALTIVEC
)
18549 /* First, find out if we use _any_ altivec registers. */
18550 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
18551 if (df_regs_ever_live_p (i
))
18552 mask
|= ALTIVEC_REG_BIT (i
);
18557 /* Next, remove the argument registers from the set. These must
18558 be in the VRSAVE mask set by the caller, so we don't need to add
18559 them in again. More importantly, the mask we compute here is
18560 used to generate CLOBBERs in the set_vrsave insn, and we do not
18561 wish the argument registers to die. */
18562 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
18563 mask
&= ~ALTIVEC_REG_BIT (i
);
18565 /* Similarly, remove the return value from the set. */
18568 diddle_return_value (is_altivec_return_reg
, &yes
);
18570 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
18576 /* For a very restricted set of circumstances, we can cut down the
18577 size of prologues/epilogues by calling our own save/restore-the-world
18581 compute_save_world_info (rs6000_stack_t
*info_ptr
)
18583 info_ptr
->world_save_p
= 1;
18584 info_ptr
->world_save_p
18585 = (WORLD_SAVE_P (info_ptr
)
18586 && DEFAULT_ABI
== ABI_DARWIN
18587 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
18588 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
18589 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
18590 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
18591 && info_ptr
->cr_save_p
);
18593 /* This will not work in conjunction with sibcalls. Make sure there
18594 are none. (This check is expensive, but seldom executed.) */
18595 if (WORLD_SAVE_P (info_ptr
))
18598 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
18599 if ( GET_CODE (insn
) == CALL_INSN
18600 && SIBLING_CALL_P (insn
))
18602 info_ptr
->world_save_p
= 0;
18607 if (WORLD_SAVE_P (info_ptr
))
18609 /* Even if we're not touching VRsave, make sure there's room on the
18610 stack for it, if it looks like we're calling SAVE_WORLD, which
18611 will attempt to save it. */
18612 info_ptr
->vrsave_size
= 4;
18614 /* If we are going to save the world, we need to save the link register too. */
18615 info_ptr
->lr_save_p
= 1;
18617 /* "Save" the VRsave register too if we're saving the world. */
18618 if (info_ptr
->vrsave_mask
== 0)
18619 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18621 /* Because the Darwin register save/restore routines only handle
18622 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18624 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
18625 && (info_ptr
->first_altivec_reg_save
18626 >= FIRST_SAVED_ALTIVEC_REGNO
));
18633 is_altivec_return_reg (rtx reg
, void *xyes
)
18635 bool *yes
= (bool *) xyes
;
18636 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
18641 /* Determine the strategy for savings/restoring registers. */
18644 SAVRES_MULTIPLE
= 0x1,
18645 SAVE_INLINE_FPRS
= 0x2,
18646 SAVE_INLINE_GPRS
= 0x4,
18647 REST_INLINE_FPRS
= 0x8,
18648 REST_INLINE_GPRS
= 0x10,
18649 SAVE_NOINLINE_GPRS_SAVES_LR
= 0x20,
18650 SAVE_NOINLINE_FPRS_SAVES_LR
= 0x40,
18651 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
= 0x80
18655 rs6000_savres_strategy (rs6000_stack_t
*info
,
18656 bool using_static_chain_p
)
18660 if (TARGET_MULTIPLE
18661 && !TARGET_POWERPC64
18662 && !(TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
)
18663 && info
->first_gp_reg_save
< 31
18664 && no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true))
18665 strategy
|= SAVRES_MULTIPLE
;
18667 if (crtl
->calls_eh_return
18668 || cfun
->machine
->ra_need_lr
18669 || info
->total_size
> 32767)
18670 strategy
|= (SAVE_INLINE_FPRS
| REST_INLINE_FPRS
18671 | SAVE_INLINE_GPRS
| REST_INLINE_GPRS
);
18673 if (info
->first_fp_reg_save
== 64
18674 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
18675 /* The out-of-line FP routines use double-precision stores;
18676 we can't use those routines if we don't have such stores. */
18677 || (TARGET_HARD_FLOAT
&& !TARGET_DOUBLE_FLOAT
)
18678 || !no_global_regs_above (info
->first_fp_reg_save
, /*gpr=*/false))
18679 strategy
|= SAVE_INLINE_FPRS
| REST_INLINE_FPRS
;
18681 if (info
->first_gp_reg_save
== 32
18682 || GP_SAVE_INLINE (info
->first_gp_reg_save
)
18683 || !((strategy
& SAVRES_MULTIPLE
)
18684 || no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true)))
18685 strategy
|= SAVE_INLINE_GPRS
| REST_INLINE_GPRS
;
18687 /* Don't bother to try to save things out-of-line if r11 is occupied
18688 by the static chain. It would require too much fiddling and the
18689 static chain is rarely used anyway. */
18690 if (using_static_chain_p
)
18691 strategy
|= SAVE_INLINE_FPRS
| SAVE_INLINE_GPRS
;
18693 /* If we are going to use store multiple, then don't even bother
18694 with the out-of-line routines, since the store-multiple
18695 instruction will always be smaller. */
18696 if ((strategy
& SAVRES_MULTIPLE
))
18697 strategy
|= SAVE_INLINE_GPRS
;
18699 /* The situation is more complicated with load multiple. We'd
18700 prefer to use the out-of-line routines for restores, since the
18701 "exit" out-of-line routines can handle the restore of LR and the
18702 frame teardown. However if doesn't make sense to use the
18703 out-of-line routine if that is the only reason we'd need to save
18704 LR, and we can't use the "exit" out-of-line gpr restore if we
18705 have saved some fprs; In those cases it is advantageous to use
18706 load multiple when available. */
18707 if ((strategy
& SAVRES_MULTIPLE
)
18708 && (!info
->lr_save_p
18709 || info
->first_fp_reg_save
!= 64))
18710 strategy
|= REST_INLINE_GPRS
;
18712 /* We can only use load multiple or the out-of-line routines to
18713 restore if we've used store multiple or out-of-line routines
18714 in the prologue, i.e. if we've saved all the registers from
18715 first_gp_reg_save. Otherwise, we risk loading garbage. */
18716 if ((strategy
& (SAVE_INLINE_GPRS
| SAVRES_MULTIPLE
)) == SAVE_INLINE_GPRS
)
18717 strategy
|= REST_INLINE_GPRS
;
18719 /* Saving CR interferes with the exit routines used on the SPE, so
18722 && info
->spe_64bit_regs_used
18723 && info
->cr_save_p
)
18724 strategy
|= REST_INLINE_GPRS
;
18726 #ifdef POWERPC_LINUX
18729 if (!(strategy
& SAVE_INLINE_FPRS
))
18730 strategy
|= SAVE_NOINLINE_FPRS_SAVES_LR
;
18731 else if (!(strategy
& SAVE_INLINE_GPRS
)
18732 && info
->first_fp_reg_save
== 64)
18733 strategy
|= SAVE_NOINLINE_GPRS_SAVES_LR
;
18736 if (TARGET_AIX
&& !(strategy
& REST_INLINE_FPRS
))
18737 strategy
|= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
;
18742 /* Calculate the stack information for the current function. This is
18743 complicated by having two separate calling sequences, the AIX calling
18744 sequence and the V.4 calling sequence.
18746 AIX (and Darwin/Mac OS X) stack frames look like:
18748 SP----> +---------------------------------------+
18749 | back chain to caller | 0 0
18750 +---------------------------------------+
18751 | saved CR | 4 8 (8-11)
18752 +---------------------------------------+
18754 +---------------------------------------+
18755 | reserved for compilers | 12 24
18756 +---------------------------------------+
18757 | reserved for binders | 16 32
18758 +---------------------------------------+
18759 | saved TOC pointer | 20 40
18760 +---------------------------------------+
18761 | Parameter save area (P) | 24 48
18762 +---------------------------------------+
18763 | Alloca space (A) | 24+P etc.
18764 +---------------------------------------+
18765 | Local variable space (L) | 24+P+A
18766 +---------------------------------------+
18767 | Float/int conversion temporary (X) | 24+P+A+L
18768 +---------------------------------------+
18769 | Save area for AltiVec registers (W) | 24+P+A+L+X
18770 +---------------------------------------+
18771 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18772 +---------------------------------------+
18773 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18774 +---------------------------------------+
18775 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18776 +---------------------------------------+
18777 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18778 +---------------------------------------+
18779 old SP->| back chain to caller's caller |
18780 +---------------------------------------+
18782 The required alignment for AIX configurations is two words (i.e., 8
18786 V.4 stack frames look like:
18788 SP----> +---------------------------------------+
18789 | back chain to caller | 0
18790 +---------------------------------------+
18791 | caller's saved LR | 4
18792 +---------------------------------------+
18793 | Parameter save area (P) | 8
18794 +---------------------------------------+
18795 | Alloca space (A) | 8+P
18796 +---------------------------------------+
18797 | Varargs save area (V) | 8+P+A
18798 +---------------------------------------+
18799 | Local variable space (L) | 8+P+A+V
18800 +---------------------------------------+
18801 | Float/int conversion temporary (X) | 8+P+A+V+L
18802 +---------------------------------------+
18803 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18804 +---------------------------------------+
18805 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18806 +---------------------------------------+
18807 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18808 +---------------------------------------+
18809 | SPE: area for 64-bit GP registers |
18810 +---------------------------------------+
18811 | SPE alignment padding |
18812 +---------------------------------------+
18813 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18814 +---------------------------------------+
18815 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18816 +---------------------------------------+
18817 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18818 +---------------------------------------+
18819 old SP->| back chain to caller's caller |
18820 +---------------------------------------+
18822 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18823 given. (But note below and in sysv4.h that we require only 8 and
18824 may round up the size of our stack frame anyways. The historical
18825 reason is early versions of powerpc-linux which didn't properly
18826 align the stack at program startup. A happy side-effect is that
18827 -mno-eabi libraries can be used with -meabi programs.)
18829 The EABI configuration defaults to the V.4 layout. However,
18830 the stack alignment requirements may differ. If -mno-eabi is not
18831 given, the required stack alignment is 8 bytes; if -mno-eabi is
18832 given, the required alignment is 16 bytes. (But see V.4 comment
18835 #ifndef ABI_STACK_BOUNDARY
18836 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18839 static rs6000_stack_t
*
18840 rs6000_stack_info (void)
18842 #ifdef ENABLE_CHECKING
18843 static rs6000_stack_t info_save
;
18845 rs6000_stack_t
*info_ptr
= &stack_info
;
18846 int reg_size
= TARGET_32BIT
? 4 : 8;
18850 HOST_WIDE_INT non_fixed_size
;
18851 bool using_static_chain_p
;
18853 #ifdef ENABLE_CHECKING
18854 memcpy (&info_save
, &stack_info
, sizeof stack_info
);
18856 if (reload_completed
&& info_ptr
->reload_completed
)
18860 memset (&stack_info
, 0, sizeof (stack_info
));
18861 info_ptr
->reload_completed
= reload_completed
;
18865 /* Cache value so we don't rescan instruction chain over and over. */
18866 if (cfun
->machine
->insn_chain_scanned_p
== 0)
18867 cfun
->machine
->insn_chain_scanned_p
18868 = spe_func_has_64bit_regs_p () + 1;
18869 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
18872 /* Select which calling sequence. */
18873 info_ptr
->abi
= DEFAULT_ABI
;
18875 /* Calculate which registers need to be saved & save area size. */
18876 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
18877 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18878 even if it currently looks like we won't. Reload may need it to
18879 get at a constant; if so, it will have already created a constant
18880 pool entry for it. */
18881 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
18882 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
18883 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
18884 && crtl
->uses_const_pool
18885 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18886 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
18888 first_gp
= info_ptr
->first_gp_reg_save
;
18890 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
18892 /* For the SPE, we have an additional upper 32-bits on each GPR.
18893 Ideally we should save the entire 64-bits only when the upper
18894 half is used in SIMD instructions. Since we only record
18895 registers live (not the size they are used in), this proves
18896 difficult because we'd have to traverse the instruction chain at
18897 the right time, taking reload into account. This is a real pain,
18898 so we opt to save the GPRs in 64-bits always if but one register
18899 gets used in 64-bits. Otherwise, all the registers in the frame
18900 get saved in 32-bits.
18902 So... since when we save all GPRs (except the SP) in 64-bits, the
18903 traditional GP save area will be empty. */
18904 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18905 info_ptr
->gp_size
= 0;
18907 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
18908 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
18910 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
18911 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
18912 - info_ptr
->first_altivec_reg_save
);
18914 /* Does this function call anything? */
18915 info_ptr
->calls_p
= (! current_function_is_leaf
18916 || cfun
->machine
->ra_needs_full_frame
);
18918 /* Determine if we need to save the condition code registers. */
18919 if (df_regs_ever_live_p (CR2_REGNO
)
18920 || df_regs_ever_live_p (CR3_REGNO
)
18921 || df_regs_ever_live_p (CR4_REGNO
))
18923 info_ptr
->cr_save_p
= 1;
18924 if (DEFAULT_ABI
== ABI_V4
)
18925 info_ptr
->cr_size
= reg_size
;
18928 /* If the current function calls __builtin_eh_return, then we need
18929 to allocate stack space for registers that will hold data for
18930 the exception handler. */
18931 if (crtl
->calls_eh_return
)
18934 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
18937 /* SPE saves EH registers in 64-bits. */
18938 ehrd_size
= i
* (TARGET_SPE_ABI
18939 && info_ptr
->spe_64bit_regs_used
!= 0
18940 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
18945 /* Determine various sizes. */
18946 info_ptr
->reg_size
= reg_size
;
18947 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
18948 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
18949 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
18950 TARGET_ALTIVEC
? 16 : 8);
18951 if (FRAME_GROWS_DOWNWARD
)
18952 info_ptr
->vars_size
18953 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
18954 + info_ptr
->parm_size
,
18955 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
18956 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
18957 + info_ptr
->parm_size
);
18959 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18960 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
18962 info_ptr
->spe_gp_size
= 0;
18964 if (TARGET_ALTIVEC_ABI
)
18965 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18967 info_ptr
->vrsave_mask
= 0;
18969 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
18970 info_ptr
->vrsave_size
= 4;
18972 info_ptr
->vrsave_size
= 0;
18974 compute_save_world_info (info_ptr
);
18976 /* Calculate the offsets. */
18977 switch (DEFAULT_ABI
)
18981 gcc_unreachable ();
18985 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18986 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18988 if (TARGET_ALTIVEC_ABI
)
18990 info_ptr
->vrsave_save_offset
18991 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
18993 /* Align stack so vector save area is on a quadword boundary.
18994 The padding goes above the vectors. */
18995 if (info_ptr
->altivec_size
!= 0)
18996 info_ptr
->altivec_padding_size
18997 = info_ptr
->vrsave_save_offset
& 0xF;
18999 info_ptr
->altivec_padding_size
= 0;
19001 info_ptr
->altivec_save_offset
19002 = info_ptr
->vrsave_save_offset
19003 - info_ptr
->altivec_padding_size
19004 - info_ptr
->altivec_size
;
19005 gcc_assert (info_ptr
->altivec_size
== 0
19006 || info_ptr
->altivec_save_offset
% 16 == 0);
19008 /* Adjust for AltiVec case. */
19009 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
19012 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
19013 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
19014 info_ptr
->lr_save_offset
= 2*reg_size
;
19018 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
19019 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
19020 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
19022 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
19024 /* Align stack so SPE GPR save area is aligned on a
19025 double-word boundary. */
19026 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
19027 info_ptr
->spe_padding_size
19028 = 8 - (-info_ptr
->cr_save_offset
% 8);
19030 info_ptr
->spe_padding_size
= 0;
19032 info_ptr
->spe_gp_save_offset
19033 = info_ptr
->cr_save_offset
19034 - info_ptr
->spe_padding_size
19035 - info_ptr
->spe_gp_size
;
19037 /* Adjust for SPE case. */
19038 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
19040 else if (TARGET_ALTIVEC_ABI
)
19042 info_ptr
->vrsave_save_offset
19043 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
19045 /* Align stack so vector save area is on a quadword boundary. */
19046 if (info_ptr
->altivec_size
!= 0)
19047 info_ptr
->altivec_padding_size
19048 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
19050 info_ptr
->altivec_padding_size
= 0;
19052 info_ptr
->altivec_save_offset
19053 = info_ptr
->vrsave_save_offset
19054 - info_ptr
->altivec_padding_size
19055 - info_ptr
->altivec_size
;
19057 /* Adjust for AltiVec case. */
19058 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
19061 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
19062 info_ptr
->ehrd_offset
-= ehrd_size
;
19063 info_ptr
->lr_save_offset
= reg_size
;
19067 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
19068 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
19069 + info_ptr
->gp_size
19070 + info_ptr
->altivec_size
19071 + info_ptr
->altivec_padding_size
19072 + info_ptr
->spe_gp_size
19073 + info_ptr
->spe_padding_size
19075 + info_ptr
->cr_size
19076 + info_ptr
->vrsave_size
,
19079 non_fixed_size
= (info_ptr
->vars_size
19080 + info_ptr
->parm_size
19081 + info_ptr
->save_size
);
19083 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
19084 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
19086 /* Determine if we need to save the link register. */
19087 if (info_ptr
->calls_p
19088 || (DEFAULT_ABI
== ABI_AIX
19090 && !TARGET_PROFILE_KERNEL
)
19091 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
19092 #ifdef TARGET_RELOCATABLE
19093 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
19095 || rs6000_ra_ever_killed ())
19096 info_ptr
->lr_save_p
= 1;
19098 using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
19099 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
19100 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
19101 info_ptr
->savres_strategy
= rs6000_savres_strategy (info_ptr
,
19102 using_static_chain_p
);
19104 if (!(info_ptr
->savres_strategy
& SAVE_INLINE_GPRS
)
19105 || !(info_ptr
->savres_strategy
& SAVE_INLINE_FPRS
)
19106 || !(info_ptr
->savres_strategy
& REST_INLINE_GPRS
)
19107 || !(info_ptr
->savres_strategy
& REST_INLINE_FPRS
))
19108 info_ptr
->lr_save_p
= 1;
19110 if (info_ptr
->lr_save_p
)
19111 df_set_regs_ever_live (LR_REGNO
, true);
19113 /* Determine if we need to allocate any stack frame:
19115 For AIX we need to push the stack if a frame pointer is needed
19116 (because the stack might be dynamically adjusted), if we are
19117 debugging, if we make calls, or if the sum of fp_save, gp_save,
19118 and local variables are more than the space needed to save all
19119 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19120 + 18*8 = 288 (GPR13 reserved).
19122 For V.4 we don't have the stack cushion that AIX uses, but assume
19123 that the debugger can handle stackless frames. */
19125 if (info_ptr
->calls_p
)
19126 info_ptr
->push_p
= 1;
19128 else if (DEFAULT_ABI
== ABI_V4
)
19129 info_ptr
->push_p
= non_fixed_size
!= 0;
19131 else if (frame_pointer_needed
)
19132 info_ptr
->push_p
= 1;
19134 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
19135 info_ptr
->push_p
= 1;
19138 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
19140 /* Zero offsets if we're not saving those registers. */
19141 if (info_ptr
->fp_size
== 0)
19142 info_ptr
->fp_save_offset
= 0;
19144 if (info_ptr
->gp_size
== 0)
19145 info_ptr
->gp_save_offset
= 0;
19147 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
19148 info_ptr
->altivec_save_offset
= 0;
19150 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
19151 info_ptr
->vrsave_save_offset
= 0;
19153 if (! TARGET_SPE_ABI
19154 || info_ptr
->spe_64bit_regs_used
== 0
19155 || info_ptr
->spe_gp_size
== 0)
19156 info_ptr
->spe_gp_save_offset
= 0;
19158 if (! info_ptr
->lr_save_p
)
19159 info_ptr
->lr_save_offset
= 0;
19161 if (! info_ptr
->cr_save_p
)
19162 info_ptr
->cr_save_offset
= 0;
19164 #ifdef ENABLE_CHECKING
19165 gcc_assert (!(reload_completed
&& info_save
.reload_completed
)
19166 || memcmp (&info_save
, &stack_info
, sizeof stack_info
) == 0);
19171 /* Return true if the current function uses any GPRs in 64-bit SIMD
19175 spe_func_has_64bit_regs_p (void)
19179 /* Functions that save and restore all the call-saved registers will
19180 need to save/restore the registers in 64-bits. */
19181 if (crtl
->calls_eh_return
19182 || cfun
->calls_setjmp
19183 || crtl
->has_nonlocal_goto
)
19186 insns
= get_insns ();
19188 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
19194 /* FIXME: This should be implemented with attributes...
19196 (set_attr "spe64" "true")....then,
19197 if (get_spe64(insn)) return true;
19199 It's the only reliable way to do the stuff below. */
19201 i
= PATTERN (insn
);
19202 if (GET_CODE (i
) == SET
)
19204 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
19206 if (SPE_VECTOR_MODE (mode
))
19208 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
19218 debug_stack_info (rs6000_stack_t
*info
)
19220 const char *abi_string
;
19223 info
= rs6000_stack_info ();
19225 fprintf (stderr
, "\nStack information for function %s:\n",
19226 ((current_function_decl
&& DECL_NAME (current_function_decl
))
19227 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
19232 default: abi_string
= "Unknown"; break;
19233 case ABI_NONE
: abi_string
= "NONE"; break;
19234 case ABI_AIX
: abi_string
= "AIX"; break;
19235 case ABI_DARWIN
: abi_string
= "Darwin"; break;
19236 case ABI_V4
: abi_string
= "V.4"; break;
19239 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
19241 if (TARGET_ALTIVEC_ABI
)
19242 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
19244 if (TARGET_SPE_ABI
)
19245 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
19247 if (info
->first_gp_reg_save
!= 32)
19248 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
19250 if (info
->first_fp_reg_save
!= 64)
19251 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
19253 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
19254 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
19255 info
->first_altivec_reg_save
);
19257 if (info
->lr_save_p
)
19258 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
19260 if (info
->cr_save_p
)
19261 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
19263 if (info
->vrsave_mask
)
19264 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
19267 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
19270 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
19272 if (info
->gp_save_offset
)
19273 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
19275 if (info
->fp_save_offset
)
19276 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
19278 if (info
->altivec_save_offset
)
19279 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
19280 info
->altivec_save_offset
);
19282 if (info
->spe_gp_save_offset
)
19283 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
19284 info
->spe_gp_save_offset
);
19286 if (info
->vrsave_save_offset
)
19287 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
19288 info
->vrsave_save_offset
);
19290 if (info
->lr_save_offset
)
19291 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
19293 if (info
->cr_save_offset
)
19294 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
19296 if (info
->varargs_save_offset
)
19297 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
19299 if (info
->total_size
)
19300 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
19303 if (info
->vars_size
)
19304 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
19307 if (info
->parm_size
)
19308 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
19310 if (info
->fixed_size
)
19311 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
19314 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
19316 if (info
->spe_gp_size
)
19317 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
19320 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
19322 if (info
->altivec_size
)
19323 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
19325 if (info
->vrsave_size
)
19326 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
19328 if (info
->altivec_padding_size
)
19329 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
19330 info
->altivec_padding_size
);
19332 if (info
->spe_padding_size
)
19333 fprintf (stderr
, "\tspe_padding_size = %5d\n",
19334 info
->spe_padding_size
);
19337 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
19339 if (info
->save_size
)
19340 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
19342 if (info
->reg_size
!= 4)
19343 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
19345 fprintf (stderr
, "\n");
19349 rs6000_return_addr (int count
, rtx frame
)
19351 /* Currently we don't optimize very well between prolog and body
19352 code and for PIC code the code can be actually quite bad, so
19353 don't try to be too clever here. */
19354 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
19356 cfun
->machine
->ra_needs_full_frame
= 1;
19363 plus_constant (copy_to_reg
19364 (gen_rtx_MEM (Pmode
,
19365 memory_address (Pmode
, frame
))),
19366 RETURN_ADDRESS_OFFSET
)));
19369 cfun
->machine
->ra_need_lr
= 1;
19370 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
19373 /* Say whether a function is a candidate for sibcall handling or not.
19374 We do not allow indirect calls to be optimized into sibling calls.
19375 Also, we can't do it if there are any vector parameters; there's
19376 nowhere to put the VRsave code so it works; note that functions with
19377 vector parameters are required to have a prototype, so the argument
19378 type info must be available here. (The tail recursion case can work
19379 with vector parameters, but there's no way to distinguish here.) */
19381 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
19386 if (TARGET_ALTIVEC_VRSAVE
)
19388 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
19389 type
; type
= TREE_CHAIN (type
))
19391 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
19395 if (DEFAULT_ABI
== ABI_DARWIN
19396 || ((*targetm
.binds_local_p
) (decl
)
19397 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
19399 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
19401 if (!lookup_attribute ("longcall", attr_list
)
19402 || lookup_attribute ("shortcall", attr_list
))
19409 /* NULL if INSN insn is valid within a low-overhead loop.
19410 Otherwise return why doloop cannot be applied.
19411 PowerPC uses the COUNT register for branch on table instructions. */
19413 static const char *
19414 rs6000_invalid_within_doloop (const_rtx insn
)
19417 return "Function call in the loop.";
19420 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
19421 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
19422 return "Computed branch in the loop.";
19428 rs6000_ra_ever_killed (void)
19434 if (cfun
->is_thunk
)
19437 if (cfun
->machine
->lr_save_state
)
19438 return cfun
->machine
->lr_save_state
- 1;
19440 /* regs_ever_live has LR marked as used if any sibcalls are present,
19441 but this should not force saving and restoring in the
19442 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19443 clobbers LR, so that is inappropriate. */
19445 /* Also, the prologue can generate a store into LR that
19446 doesn't really count, like this:
19449 bcl to set PIC register
19453 When we're called from the epilogue, we need to avoid counting
19454 this as a store. */
19456 push_topmost_sequence ();
19457 top
= get_insns ();
19458 pop_topmost_sequence ();
19459 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
19461 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
19467 if (!SIBLING_CALL_P (insn
))
19470 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
19472 else if (set_of (reg
, insn
) != NULL_RTX
19473 && !prologue_epilogue_contains (insn
))
19480 /* Emit instructions needed to load the TOC register.
19481 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19482 a constant pool; or for SVR4 -fpic. */
19485 rs6000_emit_load_toc_table (int fromprolog
)
19488 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
19490 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
19493 rtx lab
, tmp1
, tmp2
, got
;
19495 lab
= gen_label_rtx ();
19496 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (lab
));
19497 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19499 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
19501 got
= rs6000_got_sym ();
19502 tmp1
= tmp2
= dest
;
19505 tmp1
= gen_reg_rtx (Pmode
);
19506 tmp2
= gen_reg_rtx (Pmode
);
19508 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
19509 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
19510 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
19511 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
19513 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
19515 emit_insn (gen_load_toc_v4_pic_si ());
19516 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19518 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
19521 rtx temp0
= (fromprolog
19522 ? gen_rtx_REG (Pmode
, 0)
19523 : gen_reg_rtx (Pmode
));
19529 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
19530 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19532 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
19533 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19535 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
19536 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19537 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
19543 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
19544 lab
= gen_label_rtx ();
19545 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
, lab
));
19546 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
19547 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
19549 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
19551 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
19553 /* This is for AIX code running in non-PIC ELF32. */
19556 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
19557 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
19559 emit_insn (gen_elf_high (dest
, realsym
));
19560 emit_insn (gen_elf_low (dest
, dest
, realsym
));
19564 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
19567 emit_insn (gen_load_toc_aix_si (dest
));
19569 emit_insn (gen_load_toc_aix_di (dest
));
19573 /* Emit instructions to restore the link register after determining where
19574 its value has been stored. */
19577 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
19579 rs6000_stack_t
*info
= rs6000_stack_info ();
19582 operands
[0] = source
;
19583 operands
[1] = scratch
;
19585 if (info
->lr_save_p
)
19587 rtx frame_rtx
= stack_pointer_rtx
;
19588 HOST_WIDE_INT sp_offset
= 0;
19591 if (frame_pointer_needed
19592 || cfun
->calls_alloca
19593 || info
->total_size
> 32767)
19595 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
19596 emit_move_insn (operands
[1], tmp
);
19597 frame_rtx
= operands
[1];
19599 else if (info
->push_p
)
19600 sp_offset
= info
->total_size
;
19602 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
19603 tmp
= gen_frame_mem (Pmode
, tmp
);
19604 emit_move_insn (tmp
, operands
[0]);
19607 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
19609 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19610 state of lr_save_p so any change from here on would be a bug. In
19611 particular, stop rs6000_ra_ever_killed from considering the SET
19612 of lr we may have added just above. */
19613 cfun
->machine
->lr_save_state
= info
->lr_save_p
+ 1;
19616 static GTY(()) alias_set_type set
= -1;
19619 get_TOC_alias_set (void)
19622 set
= new_alias_set ();
19626 /* This returns nonzero if the current function uses the TOC. This is
19627 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19628 is generated by the ABI_V4 load_toc_* patterns. */
19635 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
19638 rtx pat
= PATTERN (insn
);
19641 if (GET_CODE (pat
) == PARALLEL
)
19642 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19644 rtx sub
= XVECEXP (pat
, 0, i
);
19645 if (GET_CODE (sub
) == USE
)
19647 sub
= XEXP (sub
, 0);
19648 if (GET_CODE (sub
) == UNSPEC
19649 && XINT (sub
, 1) == UNSPEC_TOC
)
19659 create_TOC_reference (rtx symbol
, rtx largetoc_reg
)
19661 rtx tocrel
, tocreg
;
19663 if (TARGET_DEBUG_ADDR
)
19665 if (GET_CODE (symbol
) == SYMBOL_REF
)
19666 fprintf (stderr
, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19670 fprintf (stderr
, "\ncreate_TOC_reference, code %s:\n",
19671 GET_RTX_NAME (GET_CODE (symbol
)));
19672 debug_rtx (symbol
);
19676 if (!can_create_pseudo_p ())
19677 df_set_regs_ever_live (TOC_REGISTER
, true);
19679 tocrel
= gen_rtx_CONST (Pmode
,
19680 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
),
19682 tocreg
= gen_rtx_REG (Pmode
, TOC_REGISTER
);
19683 if (TARGET_CMODEL
!= CMODEL_SMALL
)
19685 rtx hi
= gen_rtx_PLUS (Pmode
, tocreg
, gen_rtx_HIGH (Pmode
, tocrel
));
19686 if (largetoc_reg
!= NULL
)
19688 emit_move_insn (largetoc_reg
, hi
);
19691 return gen_rtx_LO_SUM (Pmode
, hi
, copy_rtx (tocrel
));
19694 return gen_rtx_PLUS (Pmode
, tocreg
, tocrel
);
19697 /* Issue assembly directives that create a reference to the given DWARF
19698 FRAME_TABLE_LABEL from the current function section. */
19700 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label
)
19702 fprintf (asm_out_file
, "\t.ref %s\n",
19703 TARGET_STRIP_NAME_ENCODING (frame_table_label
));
19706 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19707 and the change to the stack pointer. */
19710 rs6000_emit_stack_tie (void)
19712 rtx mem
= gen_frame_mem (BLKmode
,
19713 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
19715 emit_insn (gen_stack_tie (mem
));
19718 /* Emit the correct code for allocating stack space, as insns.
19719 If COPY_REG, make sure a copy of the old frame is left there.
19720 The generated code may use hard register 0 as a temporary. */
19723 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, rtx copy_reg
)
19726 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19727 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
19728 rtx todec
= gen_int_mode (-size
, Pmode
);
19731 if (INTVAL (todec
) != -size
)
19733 warning (0, "stack frame too large");
19734 emit_insn (gen_trap ());
19738 if (crtl
->limit_stack
)
19740 if (REG_P (stack_limit_rtx
)
19741 && REGNO (stack_limit_rtx
) > 1
19742 && REGNO (stack_limit_rtx
) <= 31)
19744 emit_insn (gen_add3_insn (tmp_reg
, stack_limit_rtx
, GEN_INT (size
)));
19745 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19748 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
19750 && DEFAULT_ABI
== ABI_V4
)
19752 rtx toload
= gen_rtx_CONST (VOIDmode
,
19753 gen_rtx_PLUS (Pmode
,
19757 emit_insn (gen_elf_high (tmp_reg
, toload
));
19758 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
19759 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19763 warning (0, "stack limit expression is not supported");
19767 emit_move_insn (copy_reg
, stack_reg
);
19771 /* Need a note here so that try_split doesn't get confused. */
19772 if (get_last_insn () == NULL_RTX
)
19773 emit_note (NOTE_INSN_DELETED
);
19774 insn
= emit_move_insn (tmp_reg
, todec
);
19775 try_split (PATTERN (insn
), insn
, 0);
19779 insn
= emit_insn (TARGET_32BIT
19780 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
19782 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
19783 todec
, stack_reg
));
19784 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19785 it now and set the alias set/attributes. The above gen_*_update
19786 calls will generate a PARALLEL with the MEM set being the first
19788 par
= PATTERN (insn
);
19789 gcc_assert (GET_CODE (par
) == PARALLEL
);
19790 set
= XVECEXP (par
, 0, 0);
19791 gcc_assert (GET_CODE (set
) == SET
);
19792 mem
= SET_DEST (set
);
19793 gcc_assert (MEM_P (mem
));
19794 MEM_NOTRAP_P (mem
) = 1;
19795 set_mem_alias_set (mem
, get_frame_alias_set ());
19797 RTX_FRAME_RELATED_P (insn
) = 1;
19798 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
19799 gen_rtx_SET (VOIDmode
, stack_reg
,
19800 gen_rtx_PLUS (Pmode
, stack_reg
,
19801 GEN_INT (-size
))));
19804 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19806 #if PROBE_INTERVAL > 32768
19807 #error Cannot use indexed addressing mode for stack probing
19810 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19811 inclusive. These are offsets from the current stack pointer. */
19814 rs6000_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
19816 /* See if we have a constant small number of probes to generate. If so,
19817 that's the easy case. */
19818 if (first
+ size
<= 32768)
19822 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19823 it exceeds SIZE. If only one probe is needed, this will not
19824 generate any code. Then probe at FIRST + SIZE. */
19825 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
19826 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ i
)));
19828 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ size
)));
19831 /* Otherwise, do the same as above, but in a loop. Note that we must be
19832 extra careful with variables wrapping around because we might be at
19833 the very top (or the very bottom) of the address space and we have
19834 to be able to handle this case properly; in particular, we use an
19835 equality test for the loop condition. */
19838 HOST_WIDE_INT rounded_size
;
19839 rtx r12
= gen_rtx_REG (Pmode
, 12);
19840 rtx r0
= gen_rtx_REG (Pmode
, 0);
19842 /* Sanity check for the addressing mode we're going to use. */
19843 gcc_assert (first
<= 32768);
19845 /* Step 1: round SIZE to the previous multiple of the interval. */
19847 rounded_size
= size
& -PROBE_INTERVAL
;
19850 /* Step 2: compute initial and final value of the loop counter. */
19852 /* TEST_ADDR = SP + FIRST. */
19853 emit_insn (gen_rtx_SET (VOIDmode
, r12
,
19854 plus_constant (stack_pointer_rtx
, -first
)));
19856 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19857 if (rounded_size
> 32768)
19859 emit_move_insn (r0
, GEN_INT (-rounded_size
));
19860 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19861 gen_rtx_PLUS (Pmode
, r12
, r0
)));
19864 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19865 plus_constant (r12
, -rounded_size
)));
19868 /* Step 3: the loop
19870 while (TEST_ADDR != LAST_ADDR)
19872 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19876 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19877 until it is equal to ROUNDED_SIZE. */
19880 emit_insn (gen_probe_stack_rangedi (r12
, r12
, r0
));
19882 emit_insn (gen_probe_stack_rangesi (r12
, r12
, r0
));
19885 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19886 that SIZE is equal to ROUNDED_SIZE. */
19888 if (size
!= rounded_size
)
19889 emit_stack_probe (plus_constant (r12
, rounded_size
- size
));
19893 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19894 absolute addresses. */
19897 output_probe_stack_range (rtx reg1
, rtx reg2
)
19899 static int labelno
= 0;
19900 char loop_lab
[32], end_lab
[32];
19903 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
);
19904 ASM_GENERATE_INTERNAL_LABEL (end_lab
, "LPSRE", labelno
++);
19906 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
19908 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19912 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops
);
19914 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops
);
19916 fputs ("\tbeq 0,", asm_out_file
);
19917 assemble_name_raw (asm_out_file
, end_lab
);
19918 fputc ('\n', asm_out_file
);
19920 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19921 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
19922 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops
);
19924 /* Probe at TEST_ADDR and branch. */
19925 output_asm_insn ("{st|stw} 0,0(%0)", xops
);
19926 fprintf (asm_out_file
, "\tb ");
19927 assemble_name_raw (asm_out_file
, loop_lab
);
19928 fputc ('\n', asm_out_file
);
19930 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, end_lab
);
19935 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19936 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19937 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19938 deduce these equivalences by itself so it wasn't necessary to hold
19939 its hand so much. */
19942 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
19943 rtx reg2
, rtx rreg
)
19947 /* copy_rtx will not make unique copies of registers, so we need to
19948 ensure we don't have unwanted sharing here. */
19950 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19953 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19955 real
= copy_rtx (PATTERN (insn
));
19957 if (reg2
!= NULL_RTX
)
19958 real
= replace_rtx (real
, reg2
, rreg
);
19960 real
= replace_rtx (real
, reg
,
19961 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
19962 STACK_POINTER_REGNUM
),
19965 /* We expect that 'real' is either a SET or a PARALLEL containing
19966 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19967 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19969 if (GET_CODE (real
) == SET
)
19973 temp
= simplify_rtx (SET_SRC (set
));
19975 SET_SRC (set
) = temp
;
19976 temp
= simplify_rtx (SET_DEST (set
));
19978 SET_DEST (set
) = temp
;
19979 if (GET_CODE (SET_DEST (set
)) == MEM
)
19981 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19983 XEXP (SET_DEST (set
), 0) = temp
;
19990 gcc_assert (GET_CODE (real
) == PARALLEL
);
19991 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
19992 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
19994 rtx set
= XVECEXP (real
, 0, i
);
19996 temp
= simplify_rtx (SET_SRC (set
));
19998 SET_SRC (set
) = temp
;
19999 temp
= simplify_rtx (SET_DEST (set
));
20001 SET_DEST (set
) = temp
;
20002 if (GET_CODE (SET_DEST (set
)) == MEM
)
20004 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
20006 XEXP (SET_DEST (set
), 0) = temp
;
20008 RTX_FRAME_RELATED_P (set
) = 1;
20012 RTX_FRAME_RELATED_P (insn
) = 1;
20013 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
20016 /* Returns an insn that has a vrsave set operation with the
20017 appropriate CLOBBERs. */
20020 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
20023 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
20024 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
20027 = gen_rtx_SET (VOIDmode
,
20029 gen_rtx_UNSPEC_VOLATILE (SImode
,
20030 gen_rtvec (2, reg
, vrsave
),
20031 UNSPECV_SET_VRSAVE
));
20035 /* We need to clobber the registers in the mask so the scheduler
20036 does not move sets to VRSAVE before sets of AltiVec registers.
20038 However, if the function receives nonlocal gotos, reload will set
20039 all call saved registers live. We will end up with:
20041 (set (reg 999) (mem))
20042 (parallel [ (set (reg vrsave) (unspec blah))
20043 (clobber (reg 999))])
20045 The clobber will cause the store into reg 999 to be dead, and
20046 flow will attempt to delete an epilogue insn. In this case, we
20047 need an unspec use/set of the register. */
20049 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20050 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20052 if (!epiloguep
|| call_used_regs
[i
])
20053 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
20054 gen_rtx_REG (V4SImode
, i
));
20057 rtx reg
= gen_rtx_REG (V4SImode
, i
);
20060 = gen_rtx_SET (VOIDmode
,
20062 gen_rtx_UNSPEC (V4SImode
,
20063 gen_rtvec (1, reg
), 27));
20067 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
20069 for (i
= 0; i
< nclobs
; ++i
)
20070 XVECEXP (insn
, 0, i
) = clobs
[i
];
20075 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
20076 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
20079 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
20080 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
20082 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
20083 rtx replacea
, replaceb
;
20085 int_rtx
= GEN_INT (offset
);
20087 /* Some cases that need register indexed addressing. */
20088 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
20089 || (TARGET_VSX
&& VSX_VECTOR_MODE (mode
))
20090 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
20092 && SPE_VECTOR_MODE (mode
)
20093 && !SPE_CONST_OFFSET_OK (offset
)))
20095 /* Whomever calls us must make sure r11 is available in the
20096 flow path of instructions in the prologue. */
20097 offset_rtx
= gen_rtx_REG (Pmode
, 11);
20098 emit_move_insn (offset_rtx
, int_rtx
);
20100 replacea
= offset_rtx
;
20101 replaceb
= int_rtx
;
20105 offset_rtx
= int_rtx
;
20106 replacea
= NULL_RTX
;
20107 replaceb
= NULL_RTX
;
20110 reg
= gen_rtx_REG (mode
, regno
);
20111 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
20112 mem
= gen_frame_mem (mode
, addr
);
20114 insn
= emit_move_insn (mem
, reg
);
20116 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
20119 /* Emit an offset memory reference suitable for a frame store, while
20120 converting to a valid addressing mode. */
20123 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
20125 rtx int_rtx
, offset_rtx
;
20127 int_rtx
= GEN_INT (offset
);
20129 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
20130 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
20132 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
20133 emit_move_insn (offset_rtx
, int_rtx
);
20136 offset_rtx
= int_rtx
;
20138 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
20141 /* Look for user-defined global regs. We should not save and restore these,
20142 and cannot use stmw/lmw if there are any in its range. */
20145 no_global_regs_above (int first
, bool gpr
)
20148 int last
= gpr
? 32 : 64;
20149 for (i
= first
; i
< last
; i
++)
20150 if (global_regs
[i
])
20155 #ifndef TARGET_FIX_AND_CONTINUE
20156 #define TARGET_FIX_AND_CONTINUE 0
20159 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20160 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20161 #define LAST_SAVRES_REGISTER 31
20162 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20164 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
20166 /* Temporary holding space for an out-of-line register save/restore
20168 static char savres_routine_name
[30];
20170 /* Return the name for an out-of-line register save/restore routine.
20171 We are saving/restoring GPRs if GPR is true. */
20174 rs6000_savres_routine_name (rs6000_stack_t
*info
, int regno
,
20175 bool savep
, bool gpr
, bool lr
)
20177 const char *prefix
= "";
20178 const char *suffix
= "";
20180 /* Different targets are supposed to define
20181 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20182 routine name could be defined with:
20184 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20186 This is a nice idea in practice, but in reality, things are
20187 complicated in several ways:
20189 - ELF targets have save/restore routines for GPRs.
20191 - SPE targets use different prefixes for 32/64-bit registers, and
20192 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20194 - PPC64 ELF targets have routines for save/restore of GPRs that
20195 differ in what they do with the link register, so having a set
20196 prefix doesn't work. (We only use one of the save routines at
20197 the moment, though.)
20199 - PPC32 elf targets have "exit" versions of the restore routines
20200 that restore the link register and can save some extra space.
20201 These require an extra suffix. (There are also "tail" versions
20202 of the restore routines and "GOT" versions of the save routines,
20203 but we don't generate those at present. Same problems apply,
20206 We deal with all this by synthesizing our own prefix/suffix and
20207 using that for the simple sprintf call shown above. */
20210 /* No floating point saves on the SPE. */
20214 prefix
= info
->spe_64bit_regs_used
? "_save64gpr_" : "_save32gpr_";
20216 prefix
= info
->spe_64bit_regs_used
? "_rest64gpr_" : "_rest32gpr_";
20221 else if (DEFAULT_ABI
== ABI_V4
)
20227 prefix
= savep
? "_savegpr_" : "_restgpr_";
20229 prefix
= savep
? "_savefpr_" : "_restfpr_";
20234 else if (DEFAULT_ABI
== ABI_AIX
)
20236 #ifndef POWERPC_LINUX
20237 /* No out-of-line save/restore routines for GPRs on AIX. */
20238 gcc_assert (!TARGET_AIX
|| !gpr
);
20244 ? (lr
? "_savegpr0_" : "_savegpr1_")
20245 : (lr
? "_restgpr0_" : "_restgpr1_"));
20246 #ifdef POWERPC_LINUX
20248 prefix
= (savep
? "_savefpr_" : "_restfpr_");
20252 prefix
= savep
? SAVE_FP_PREFIX
: RESTORE_FP_PREFIX
;
20253 suffix
= savep
? SAVE_FP_SUFFIX
: RESTORE_FP_SUFFIX
;
20256 else if (DEFAULT_ABI
== ABI_DARWIN
)
20257 sorry ("out-of-line save/restore routines not supported on Darwin");
20259 sprintf (savres_routine_name
, "%s%d%s", prefix
, regno
, suffix
);
20261 return savres_routine_name
;
20264 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20265 We are saving/restoring GPRs if GPR is true. */
20268 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
,
20271 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
20273 int select
= ((savep
? 1 : 0) << 2
20275 /* On the SPE, we never have any FPRs, but we do have
20276 32/64-bit versions of the routines. */
20277 ? (info
->spe_64bit_regs_used
? 1 : 0)
20278 : (gpr
? 1 : 0)) << 1)
20281 /* Don't generate bogus routine names. */
20282 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
20283 && regno
<= LAST_SAVRES_REGISTER
);
20285 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
20291 name
= rs6000_savres_routine_name (info
, regno
, savep
, gpr
, lr
);
20293 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
20294 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
20295 SYMBOL_REF_FLAGS (sym
) |= SYMBOL_FLAG_FUNCTION
;
20301 /* Emit a sequence of insns, including a stack tie if needed, for
20302 resetting the stack pointer. If SAVRES is true, then don't reset the
20303 stack pointer, but move the base of the frame into r11 for use by
20304 out-of-line register restore routines. */
20307 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
20308 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
20309 int sp_offset
, bool savres
)
20311 /* This blockage is needed so that sched doesn't decide to move
20312 the sp change before the register restores. */
20313 if (frame_reg_rtx
!= sp_reg_rtx
20315 && info
->spe_64bit_regs_used
!= 0
20316 && info
->first_gp_reg_save
!= 32))
20317 rs6000_emit_stack_tie ();
20319 if (frame_reg_rtx
!= sp_reg_rtx
)
20321 if (sp_offset
!= 0)
20323 rtx dest_reg
= savres
? gen_rtx_REG (Pmode
, 11) : sp_reg_rtx
;
20324 return emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
,
20325 GEN_INT (sp_offset
)));
20328 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
20330 else if (sp_offset
!= 0)
20332 /* If we are restoring registers out-of-line, we will be using the
20333 "exit" variants of the restore routines, which will reset the
20334 stack for us. But we do need to point r11 into the right place
20335 for those routines. */
20336 rtx dest_reg
= (savres
20337 ? gen_rtx_REG (Pmode
, 11)
20340 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
20341 GEN_INT (sp_offset
)));
20348 /* Construct a parallel rtx describing the effect of a call to an
20349 out-of-line register save/restore routine. */
20352 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
20353 rtx frame_reg_rtx
, int save_area_offset
,
20354 enum machine_mode reg_mode
,
20355 bool savep
, bool gpr
, bool lr
)
20358 int offset
, start_reg
, end_reg
, n_regs
;
20359 int reg_size
= GET_MODE_SIZE (reg_mode
);
20365 ? info
->first_gp_reg_save
20366 : info
->first_fp_reg_save
);
20367 end_reg
= gpr
? 32 : 64;
20368 n_regs
= end_reg
- start_reg
;
20369 p
= rtvec_alloc ((lr
? 4 : 3) + n_regs
);
20372 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
20374 RTVEC_ELT (p
, offset
++)
20375 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
20377 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, lr
);
20378 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
20379 RTVEC_ELT (p
, offset
++)
20380 = gen_rtx_USE (VOIDmode
,
20381 gen_rtx_REG (Pmode
, DEFAULT_ABI
!= ABI_AIX
? 11
20385 for (i
= 0; i
< end_reg
- start_reg
; i
++)
20387 rtx addr
, reg
, mem
;
20388 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
20389 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20390 GEN_INT (save_area_offset
+ reg_size
*i
));
20391 mem
= gen_frame_mem (reg_mode
, addr
);
20393 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
20395 savep
? reg
: mem
);
20400 rtx addr
, reg
, mem
;
20401 reg
= gen_rtx_REG (Pmode
, 0);
20402 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20403 GEN_INT (info
->lr_save_offset
));
20404 mem
= gen_frame_mem (Pmode
, addr
);
20405 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20408 return gen_rtx_PARALLEL (VOIDmode
, p
);
20411 /* Determine whether the gp REG is really used. */
20414 rs6000_reg_live_or_pic_offset_p (int reg
)
20416 /* If the function calls eh_return, claim used all the registers that would
20417 be checked for liveness otherwise. This is required for the PIC offset
20418 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20419 register allocation purposes in this case. */
20421 return (((crtl
->calls_eh_return
|| df_regs_ever_live_p (reg
))
20422 && (!call_used_regs
[reg
]
20423 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
20424 && !TARGET_SINGLE_PIC_BASE
20425 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
20426 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
20427 && !TARGET_SINGLE_PIC_BASE
20428 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
20429 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
20432 /* Emit function prologue as insns. */
20435 rs6000_emit_prologue (void)
20437 rs6000_stack_t
*info
= rs6000_stack_info ();
20438 enum machine_mode reg_mode
= Pmode
;
20439 int reg_size
= TARGET_32BIT
? 4 : 8;
20440 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
20441 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
20442 rtx frame_reg_rtx
= sp_reg_rtx
;
20443 rtx cr_save_rtx
= NULL_RTX
;
20446 int saving_FPRs_inline
;
20447 int saving_GPRs_inline
;
20448 int using_store_multiple
;
20449 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
20450 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
20451 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
20452 HOST_WIDE_INT sp_offset
= 0;
20454 if (flag_stack_usage
)
20455 current_function_static_stack_size
= info
->total_size
;
20457 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
&& info
->total_size
)
20458 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT
, info
->total_size
);
20460 if (TARGET_FIX_AND_CONTINUE
)
20462 /* gdb on darwin arranges to forward a function from the old
20463 address by modifying the first 5 instructions of the function
20464 to branch to the overriding function. This is necessary to
20465 permit function pointers that point to the old function to
20466 actually forward to the new function. */
20467 emit_insn (gen_nop ());
20468 emit_insn (gen_nop ());
20469 emit_insn (gen_nop ());
20470 emit_insn (gen_nop ());
20471 emit_insn (gen_nop ());
20474 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
20476 reg_mode
= V2SImode
;
20480 strategy
= info
->savres_strategy
;
20481 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
20482 saving_FPRs_inline
= strategy
& SAVE_INLINE_FPRS
;
20483 saving_GPRs_inline
= strategy
& SAVE_INLINE_GPRS
;
20485 /* For V.4, update stack before we do any saving and set back pointer. */
20486 if (! WORLD_SAVE_P (info
)
20488 && (DEFAULT_ABI
== ABI_V4
20489 || crtl
->calls_eh_return
))
20491 bool need_r11
= (TARGET_SPE
20492 ? (!saving_GPRs_inline
20493 && info
->spe_64bit_regs_used
== 0)
20494 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
20495 rtx copy_reg
= need_r11
? gen_rtx_REG (Pmode
, 11) : NULL
;
20497 if (info
->total_size
< 32767)
20498 sp_offset
= info
->total_size
;
20500 frame_reg_rtx
= copy_reg
;
20501 else if (info
->cr_save_p
20503 || info
->first_fp_reg_save
< 64
20504 || info
->first_gp_reg_save
< 32
20505 || info
->altivec_size
!= 0
20506 || info
->vrsave_mask
!= 0
20507 || crtl
->calls_eh_return
)
20509 copy_reg
= frame_ptr_rtx
;
20510 frame_reg_rtx
= copy_reg
;
20514 /* The prologue won't be saving any regs so there is no need
20515 to set up a frame register to access any frame save area.
20516 We also won't be using sp_offset anywhere below, but set
20517 the correct value anyway to protect against future
20518 changes to this function. */
20519 sp_offset
= info
->total_size
;
20521 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20522 if (frame_reg_rtx
!= sp_reg_rtx
)
20523 rs6000_emit_stack_tie ();
20526 /* Handle world saves specially here. */
20527 if (WORLD_SAVE_P (info
))
20534 /* save_world expects lr in r0. */
20535 reg0
= gen_rtx_REG (Pmode
, 0);
20536 if (info
->lr_save_p
)
20538 insn
= emit_move_insn (reg0
,
20539 gen_rtx_REG (Pmode
, LR_REGNO
));
20540 RTX_FRAME_RELATED_P (insn
) = 1;
20543 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20544 assumptions about the offsets of various bits of the stack
20546 gcc_assert (info
->gp_save_offset
== -220
20547 && info
->fp_save_offset
== -144
20548 && info
->lr_save_offset
== 8
20549 && info
->cr_save_offset
== 4
20552 && (!crtl
->calls_eh_return
20553 || info
->ehrd_offset
== -432)
20554 && info
->vrsave_save_offset
== -224
20555 && info
->altivec_save_offset
== -416);
20557 treg
= gen_rtx_REG (SImode
, 11);
20558 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
20560 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20561 in R11. It also clobbers R12, so beware! */
20563 /* Preserve CR2 for save_world prologues */
20565 sz
+= 32 - info
->first_gp_reg_save
;
20566 sz
+= 64 - info
->first_fp_reg_save
;
20567 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
20568 p
= rtvec_alloc (sz
);
20570 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
20571 gen_rtx_REG (SImode
,
20573 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
20574 gen_rtx_SYMBOL_REF (Pmode
,
20576 /* We do floats first so that the instruction pattern matches
20578 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20580 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20581 ? DFmode
: SFmode
),
20582 info
->first_fp_reg_save
+ i
);
20583 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20584 GEN_INT (info
->fp_save_offset
20585 + sp_offset
+ 8 * i
));
20586 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20587 ? DFmode
: SFmode
), addr
);
20589 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20591 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
20593 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
20594 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20595 GEN_INT (info
->altivec_save_offset
20596 + sp_offset
+ 16 * i
));
20597 rtx mem
= gen_frame_mem (V4SImode
, addr
);
20599 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20601 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20603 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20604 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20605 GEN_INT (info
->gp_save_offset
20606 + sp_offset
+ reg_size
* i
));
20607 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20609 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20613 /* CR register traditionally saved as CR2. */
20614 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
20615 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20616 GEN_INT (info
->cr_save_offset
20618 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20620 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20622 /* Explain about use of R0. */
20623 if (info
->lr_save_p
)
20625 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20626 GEN_INT (info
->lr_save_offset
20628 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20630 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
20632 /* Explain what happens to the stack pointer. */
20634 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
20635 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
20638 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20639 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20640 treg
, GEN_INT (-info
->total_size
));
20641 sp_offset
= info
->total_size
;
20644 /* If we use the link register, get it into r0. */
20645 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
20647 rtx addr
, reg
, mem
;
20649 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
20650 gen_rtx_REG (Pmode
, LR_REGNO
));
20651 RTX_FRAME_RELATED_P (insn
) = 1;
20653 if (!(strategy
& (SAVE_NOINLINE_GPRS_SAVES_LR
20654 | SAVE_NOINLINE_FPRS_SAVES_LR
)))
20656 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20657 GEN_INT (info
->lr_save_offset
+ sp_offset
));
20658 reg
= gen_rtx_REG (Pmode
, 0);
20659 mem
= gen_rtx_MEM (Pmode
, addr
);
20660 /* This should not be of rs6000_sr_alias_set, because of
20661 __builtin_return_address. */
20663 insn
= emit_move_insn (mem
, reg
);
20664 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20665 NULL_RTX
, NULL_RTX
);
20669 /* If we need to save CR, put it into r12 or r11. */
20670 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
20675 = gen_rtx_REG (SImode
, DEFAULT_ABI
== ABI_AIX
&& !saving_GPRs_inline
20677 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20678 RTX_FRAME_RELATED_P (insn
) = 1;
20679 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20680 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20681 But that's OK. All we have to do is specify that _one_ condition
20682 code register is saved in this stack slot. The thrower's epilogue
20683 will then restore all the call-saved registers.
20684 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20685 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
20686 gen_rtx_REG (SImode
, CR2_REGNO
));
20687 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20690 /* Do any required saving of fpr's. If only one or two to save, do
20691 it ourselves. Otherwise, call function. */
20692 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
20695 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20696 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
20697 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
20698 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
20699 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20701 info
->first_fp_reg_save
+ i
,
20702 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
20705 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
20709 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20710 info
->fp_save_offset
+ sp_offset
,
20712 /*savep=*/true, /*gpr=*/false,
20714 & SAVE_NOINLINE_FPRS_SAVES_LR
)
20716 insn
= emit_insn (par
);
20717 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20718 NULL_RTX
, NULL_RTX
);
20721 /* Save GPRs. This is done as a PARALLEL if we are using
20722 the store-multiple instructions. */
20723 if (!WORLD_SAVE_P (info
)
20725 && info
->spe_64bit_regs_used
!= 0
20726 && info
->first_gp_reg_save
!= 32)
20729 rtx spe_save_area_ptr
;
20731 /* Determine whether we can address all of the registers that need
20732 to be saved with an offset from the stack pointer that fits in
20733 the small const field for SPE memory instructions. */
20734 int spe_regs_addressable_via_sp
20735 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
20736 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
20737 && saving_GPRs_inline
);
20740 if (spe_regs_addressable_via_sp
)
20742 spe_save_area_ptr
= frame_reg_rtx
;
20743 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
20747 /* Make r11 point to the start of the SPE save area. We need
20748 to be careful here if r11 is holding the static chain. If
20749 it is, then temporarily save it in r0. We would use r0 as
20750 our base register here, but using r0 as a base register in
20751 loads and stores means something different from what we
20753 int ool_adjust
= (saving_GPRs_inline
20755 : (info
->first_gp_reg_save
20756 - (FIRST_SAVRES_REGISTER
+1))*8);
20757 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
20758 + sp_offset
- ool_adjust
);
20760 if (using_static_chain_p
)
20762 rtx r0
= gen_rtx_REG (Pmode
, 0);
20763 gcc_assert (info
->first_gp_reg_save
> 11);
20765 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
20768 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
20769 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
20771 GEN_INT (offset
)));
20772 /* We need to make sure the move to r11 gets noted for
20773 properly outputting unwind information. */
20774 if (!saving_GPRs_inline
)
20775 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
20776 NULL_RTX
, NULL_RTX
);
20780 if (saving_GPRs_inline
)
20782 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20783 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20785 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20786 rtx offset
, addr
, mem
;
20788 /* We're doing all this to ensure that the offset fits into
20789 the immediate offset of 'evstdd'. */
20790 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
20792 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
20793 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
20794 mem
= gen_rtx_MEM (V2SImode
, addr
);
20796 insn
= emit_move_insn (mem
, reg
);
20798 rs6000_frame_related (insn
, spe_save_area_ptr
,
20799 info
->spe_gp_save_offset
20800 + sp_offset
+ reg_size
* i
,
20801 offset
, const0_rtx
);
20808 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
20810 /*savep=*/true, /*gpr=*/true,
20812 insn
= emit_insn (par
);
20813 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20814 NULL_RTX
, NULL_RTX
);
20818 /* Move the static chain pointer back. */
20819 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
20820 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
20822 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
20826 /* Need to adjust r11 (r12) if we saved any FPRs. */
20827 if (info
->first_fp_reg_save
!= 64)
20829 rtx dest_reg
= gen_rtx_REG (reg_mode
, DEFAULT_ABI
== ABI_AIX
20831 rtx offset
= GEN_INT (sp_offset
20832 + (-8 * (64-info
->first_fp_reg_save
)));
20833 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
20836 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20837 info
->gp_save_offset
+ sp_offset
,
20839 /*savep=*/true, /*gpr=*/true,
20841 & SAVE_NOINLINE_GPRS_SAVES_LR
)
20843 insn
= emit_insn (par
);
20844 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20845 NULL_RTX
, NULL_RTX
);
20847 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
20851 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
20852 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20854 rtx addr
, reg
, mem
;
20855 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20856 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20857 GEN_INT (info
->gp_save_offset
20860 mem
= gen_frame_mem (reg_mode
, addr
);
20862 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20864 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20865 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20866 NULL_RTX
, NULL_RTX
);
20868 else if (!WORLD_SAVE_P (info
))
20871 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20872 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20874 rtx addr
, reg
, mem
;
20875 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20877 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20878 GEN_INT (info
->gp_save_offset
20881 mem
= gen_frame_mem (reg_mode
, addr
);
20883 insn
= emit_move_insn (mem
, reg
);
20884 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20885 NULL_RTX
, NULL_RTX
);
20889 /* ??? There's no need to emit actual instructions here, but it's the
20890 easiest way to get the frame unwind information emitted. */
20891 if (crtl
->calls_eh_return
)
20893 unsigned int i
, regno
;
20897 regno
= EH_RETURN_DATA_REGNO (i
);
20898 if (regno
== INVALID_REGNUM
)
20901 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
20902 info
->ehrd_offset
+ sp_offset
20903 + reg_size
* (int) i
,
20908 /* In AIX ABI we need to make sure r2 is really saved. */
20909 if (TARGET_AIX
&& crtl
->calls_eh_return
)
20911 rtx tmp_reg
, tmp_reg_si
, hi
, lo
, compare_result
, toc_save_done
, jump
;
20912 long toc_restore_insn
;
20914 gcc_assert (frame_reg_rtx
== frame_ptr_rtx
20915 || frame_reg_rtx
== sp_reg_rtx
);
20916 tmp_reg
= gen_rtx_REG (Pmode
, 11);
20917 tmp_reg_si
= gen_rtx_REG (SImode
, 11);
20918 if (using_static_chain_p
)
20919 emit_move_insn (gen_rtx_REG (Pmode
, 0), tmp_reg
);
20920 gcc_assert (saving_GPRs_inline
&& saving_FPRs_inline
);
20921 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, LR_REGNO
));
20922 /* Peek at instruction to which this function returns. If it's
20923 restoring r2, then we know we've already saved r2. We can't
20924 unconditionally save r2 because the value we have will already
20925 be updated if we arrived at this function via a plt call or
20926 toc adjusting stub. */
20927 emit_move_insn (tmp_reg_si
, gen_rtx_MEM (SImode
, tmp_reg
));
20928 toc_restore_insn
= TARGET_32BIT
? 0x80410014 : 0xE8410028;
20929 hi
= gen_int_mode (toc_restore_insn
& ~0xffff, SImode
);
20930 emit_insn (gen_xorsi3 (tmp_reg_si
, tmp_reg_si
, hi
));
20931 compare_result
= gen_rtx_REG (CCUNSmode
, CR0_REGNO
);
20932 validate_condition_mode (EQ
, CCUNSmode
);
20933 lo
= gen_int_mode (toc_restore_insn
& 0xffff, SImode
);
20934 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
20935 gen_rtx_COMPARE (CCUNSmode
, tmp_reg_si
, lo
)));
20936 toc_save_done
= gen_label_rtx ();
20937 jump
= gen_rtx_IF_THEN_ELSE (VOIDmode
,
20938 gen_rtx_EQ (VOIDmode
, compare_result
,
20940 gen_rtx_LABEL_REF (VOIDmode
, toc_save_done
),
20942 jump
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, jump
));
20943 JUMP_LABEL (jump
) = toc_save_done
;
20944 LABEL_NUSES (toc_save_done
) += 1;
20946 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, 2,
20947 sp_offset
+ 5 * reg_size
, info
->total_size
);
20948 emit_label (toc_save_done
);
20949 if (using_static_chain_p
)
20950 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, 0));
20953 /* Save CR if we use any that must be preserved. */
20954 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
20956 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20957 GEN_INT (info
->cr_save_offset
+ sp_offset
));
20958 rtx mem
= gen_frame_mem (SImode
, addr
);
20959 /* See the large comment above about why CR2_REGNO is used. */
20960 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
20962 /* If r12 was used to hold the original sp, copy cr into r0 now
20964 if (REGNO (frame_reg_rtx
) == 12)
20968 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
20969 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20970 RTX_FRAME_RELATED_P (insn
) = 1;
20971 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
20972 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20974 insn
= emit_move_insn (mem
, cr_save_rtx
);
20976 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20977 NULL_RTX
, NULL_RTX
);
20980 /* Update stack and set back pointer unless this is V.4,
20981 for which it was done previously. */
20982 if (!WORLD_SAVE_P (info
) && info
->push_p
20983 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
20985 rtx copy_reg
= NULL
;
20987 if (info
->total_size
< 32767)
20988 sp_offset
= info
->total_size
;
20989 else if (info
->altivec_size
!= 0
20990 || info
->vrsave_mask
!= 0)
20992 copy_reg
= frame_ptr_rtx
;
20993 frame_reg_rtx
= copy_reg
;
20996 sp_offset
= info
->total_size
;
20997 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20998 if (frame_reg_rtx
!= sp_reg_rtx
)
20999 rs6000_emit_stack_tie ();
21002 /* Set frame pointer, if needed. */
21003 if (frame_pointer_needed
)
21005 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
21007 RTX_FRAME_RELATED_P (insn
) = 1;
21010 /* Save AltiVec registers if needed. Save here because the red zone does
21011 not include AltiVec registers. */
21012 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
21016 /* There should be a non inline version of this, for when we
21017 are saving lots of vector registers. */
21018 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21019 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21021 rtx areg
, savereg
, mem
;
21024 offset
= info
->altivec_save_offset
+ sp_offset
21025 + 16 * (i
- info
->first_altivec_reg_save
);
21027 savereg
= gen_rtx_REG (V4SImode
, i
);
21029 areg
= gen_rtx_REG (Pmode
, 0);
21030 emit_move_insn (areg
, GEN_INT (offset
));
21032 /* AltiVec addressing mode is [reg+reg]. */
21033 mem
= gen_frame_mem (V4SImode
,
21034 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
21036 insn
= emit_move_insn (mem
, savereg
);
21038 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
21039 areg
, GEN_INT (offset
));
21043 /* VRSAVE is a bit vector representing which AltiVec registers
21044 are used. The OS uses this to determine which vector
21045 registers to save on a context switch. We need to save
21046 VRSAVE on the stack frame, add whatever AltiVec registers we
21047 used in this function, and do the corresponding magic in the
21050 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
21051 && info
->vrsave_mask
!= 0)
21053 rtx reg
, mem
, vrsave
;
21056 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
21057 as frame_reg_rtx and r11 as the static chain pointer for
21058 nested functions. */
21059 reg
= gen_rtx_REG (SImode
, 0);
21060 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
21062 emit_insn (gen_get_vrsave_internal (reg
));
21064 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
21066 if (!WORLD_SAVE_P (info
))
21069 offset
= info
->vrsave_save_offset
+ sp_offset
;
21070 mem
= gen_frame_mem (SImode
,
21071 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21072 GEN_INT (offset
)));
21073 insn
= emit_move_insn (mem
, reg
);
21076 /* Include the registers in the mask. */
21077 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
21079 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
21082 if (TARGET_SINGLE_PIC_BASE
)
21083 return; /* Do not set PIC register */
21085 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
21086 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
21087 || (DEFAULT_ABI
== ABI_V4
21088 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
21089 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
21091 /* If emit_load_toc_table will use the link register, we need to save
21092 it. We use R12 for this purpose because emit_load_toc_table
21093 can use register 0. This allows us to use a plain 'blr' to return
21094 from the procedure more often. */
21095 int save_LR_around_toc_setup
= (TARGET_ELF
21096 && DEFAULT_ABI
!= ABI_AIX
21098 && ! info
->lr_save_p
21099 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
21100 if (save_LR_around_toc_setup
)
21102 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
21104 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
21105 RTX_FRAME_RELATED_P (insn
) = 1;
21107 rs6000_emit_load_toc_table (TRUE
);
21109 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
21110 RTX_FRAME_RELATED_P (insn
) = 1;
21113 rs6000_emit_load_toc_table (TRUE
);
21117 if (DEFAULT_ABI
== ABI_DARWIN
21118 && flag_pic
&& crtl
->uses_pic_offset_table
)
21120 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
21121 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
21123 /* Save and restore LR locally around this call (in R0). */
21124 if (!info
->lr_save_p
)
21125 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
21127 emit_insn (gen_load_macho_picbase (src
));
21129 emit_move_insn (gen_rtx_REG (Pmode
,
21130 RS6000_PIC_OFFSET_TABLE_REGNUM
),
21133 if (!info
->lr_save_p
)
21134 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
21139 /* Write function prologue. */
21142 rs6000_output_function_prologue (FILE *file
,
21143 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
21145 rs6000_stack_t
*info
= rs6000_stack_info ();
21147 if (TARGET_DEBUG_STACK
)
21148 debug_stack_info (info
);
21150 /* Write .extern for any function we will call to save and restore
21152 if (info
->first_fp_reg_save
< 64)
21155 int regno
= info
->first_fp_reg_save
- 32;
21157 if ((info
->savres_strategy
& SAVE_INLINE_FPRS
) == 0)
21159 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/true,
21160 /*gpr=*/false, /*lr=*/false);
21161 fprintf (file
, "\t.extern %s\n", name
);
21163 if ((info
->savres_strategy
& REST_INLINE_FPRS
) == 0)
21165 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/false,
21166 /*gpr=*/false, /*lr=*/true);
21167 fprintf (file
, "\t.extern %s\n", name
);
21171 /* Write .extern for AIX common mode routines, if needed. */
21172 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
21174 fputs ("\t.extern __mulh\n", file
);
21175 fputs ("\t.extern __mull\n", file
);
21176 fputs ("\t.extern __divss\n", file
);
21177 fputs ("\t.extern __divus\n", file
);
21178 fputs ("\t.extern __quoss\n", file
);
21179 fputs ("\t.extern __quous\n", file
);
21180 common_mode_defined
= 1;
21183 if (! HAVE_prologue
)
21189 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21190 the "toplevel" insn chain. */
21191 emit_note (NOTE_INSN_DELETED
);
21192 rs6000_emit_prologue ();
21193 emit_note (NOTE_INSN_DELETED
);
21195 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21199 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
21201 INSN_ADDRESSES_NEW (insn
, addr
);
21206 prologue
= get_insns ();
21209 if (TARGET_DEBUG_STACK
)
21210 debug_rtx_list (prologue
, 100);
21212 emit_insn_before_noloc (prologue
, BB_HEAD (ENTRY_BLOCK_PTR
->next_bb
),
21216 rs6000_pic_labelno
++;
21219 /* Non-zero if vmx regs are restored before the frame pop, zero if
21220 we restore after the pop when possible. */
21221 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21223 /* Reload CR from REG. */
21226 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
21231 if (using_mfcr_multiple
)
21233 for (i
= 0; i
< 8; i
++)
21234 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21236 gcc_assert (count
);
21239 if (using_mfcr_multiple
&& count
> 1)
21244 p
= rtvec_alloc (count
);
21247 for (i
= 0; i
< 8; i
++)
21248 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21250 rtvec r
= rtvec_alloc (2);
21251 RTVEC_ELT (r
, 0) = reg
;
21252 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
21253 RTVEC_ELT (p
, ndx
) =
21254 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
21255 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
21258 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21259 gcc_assert (ndx
== count
);
21262 for (i
= 0; i
< 8; i
++)
21263 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
21265 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
21271 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21272 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21273 below stack pointer not cloberred by signals. */
21276 offset_below_red_zone_p (HOST_WIDE_INT offset
)
21278 return offset
< (DEFAULT_ABI
== ABI_V4
21280 : TARGET_32BIT
? -220 : -288);
21283 /* Emit function epilogue as insns. */
21286 rs6000_emit_epilogue (int sibcall
)
21288 rs6000_stack_t
*info
;
21289 int restoring_GPRs_inline
;
21290 int restoring_FPRs_inline
;
21291 int using_load_multiple
;
21292 int using_mtcr_multiple
;
21293 int use_backchain_to_restore_sp
;
21297 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
21298 rtx frame_reg_rtx
= sp_reg_rtx
;
21299 rtx cfa_restores
= NULL_RTX
;
21301 rtx cr_save_reg
= NULL_RTX
;
21302 enum machine_mode reg_mode
= Pmode
;
21303 int reg_size
= TARGET_32BIT
? 4 : 8;
21306 info
= rs6000_stack_info ();
21308 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
21310 reg_mode
= V2SImode
;
21314 strategy
= info
->savres_strategy
;
21315 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
21316 restoring_FPRs_inline
= sibcall
|| (strategy
& REST_INLINE_FPRS
);
21317 restoring_GPRs_inline
= sibcall
|| (strategy
& REST_INLINE_GPRS
);
21318 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
21319 || rs6000_cpu
== PROCESSOR_PPC603
21320 || rs6000_cpu
== PROCESSOR_PPC750
21322 /* Restore via the backchain when we have a large frame, since this
21323 is more efficient than an addis, addi pair. The second condition
21324 here will not trigger at the moment; We don't actually need a
21325 frame pointer for alloca, but the generic parts of the compiler
21326 give us one anyway. */
21327 use_backchain_to_restore_sp
= (info
->total_size
> 32767
21328 || info
->total_size
21329 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
21331 || (cfun
->calls_alloca
21332 && !frame_pointer_needed
));
21333 restore_lr
= (info
->lr_save_p
21334 && (restoring_FPRs_inline
21335 || (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
))
21336 && (restoring_GPRs_inline
21337 || info
->first_fp_reg_save
< 64));
21339 if (WORLD_SAVE_P (info
))
21343 const char *alloc_rname
;
21346 /* eh_rest_world_r10 will return to the location saved in the LR
21347 stack slot (which is not likely to be our caller.)
21348 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21349 rest_world is similar, except any R10 parameter is ignored.
21350 The exception-handling stuff that was here in 2.95 is no
21351 longer necessary. */
21355 + 32 - info
->first_gp_reg_save
21356 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
21357 + 63 + 1 - info
->first_fp_reg_save
);
21359 strcpy (rname
, ((crtl
->calls_eh_return
) ?
21360 "*eh_rest_world_r10" : "*rest_world"));
21361 alloc_rname
= ggc_strdup (rname
);
21364 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
21365 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
21366 gen_rtx_REG (Pmode
,
21369 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
21370 /* The instruction pattern requires a clobber here;
21371 it is shared with the restVEC helper. */
21373 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
21376 /* CR register traditionally saved as CR2. */
21377 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
21378 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21379 GEN_INT (info
->cr_save_offset
));
21380 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21382 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21385 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21387 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21388 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21389 GEN_INT (info
->gp_save_offset
21391 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21393 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21395 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
21397 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
21398 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21399 GEN_INT (info
->altivec_save_offset
21401 rtx mem
= gen_frame_mem (V4SImode
, addr
);
21403 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21405 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
21407 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21408 ? DFmode
: SFmode
),
21409 info
->first_fp_reg_save
+ i
);
21410 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21411 GEN_INT (info
->fp_save_offset
21413 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21414 ? DFmode
: SFmode
), addr
);
21416 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21419 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
21421 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
21423 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
21425 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
21427 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
21428 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21433 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21435 sp_offset
= info
->total_size
;
21437 /* Restore AltiVec registers if we must do so before adjusting the
21439 if (TARGET_ALTIVEC_ABI
21440 && info
->altivec_size
!= 0
21441 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21442 || (DEFAULT_ABI
!= ABI_V4
21443 && offset_below_red_zone_p (info
->altivec_save_offset
))))
21447 if (use_backchain_to_restore_sp
)
21449 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21450 emit_move_insn (frame_reg_rtx
,
21451 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21454 else if (frame_pointer_needed
)
21455 frame_reg_rtx
= hard_frame_pointer_rtx
;
21457 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21458 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21460 rtx addr
, areg
, mem
, reg
;
21462 areg
= gen_rtx_REG (Pmode
, 0);
21464 (areg
, GEN_INT (info
->altivec_save_offset
21466 + 16 * (i
- info
->first_altivec_reg_save
)));
21468 /* AltiVec addressing mode is [reg+reg]. */
21469 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
21470 mem
= gen_frame_mem (V4SImode
, addr
);
21472 reg
= gen_rtx_REG (V4SImode
, i
);
21473 emit_move_insn (reg
, mem
);
21474 if (offset_below_red_zone_p (info
->altivec_save_offset
21475 + (i
- info
->first_altivec_reg_save
)
21477 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21482 /* Restore VRSAVE if we must do so before adjusting the stack. */
21484 && TARGET_ALTIVEC_VRSAVE
21485 && info
->vrsave_mask
!= 0
21486 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21487 || (DEFAULT_ABI
!= ABI_V4
21488 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
21490 rtx addr
, mem
, reg
;
21492 if (frame_reg_rtx
== sp_reg_rtx
)
21494 if (use_backchain_to_restore_sp
)
21496 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21497 emit_move_insn (frame_reg_rtx
,
21498 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21501 else if (frame_pointer_needed
)
21502 frame_reg_rtx
= hard_frame_pointer_rtx
;
21505 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21506 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
21507 mem
= gen_frame_mem (SImode
, addr
);
21508 reg
= gen_rtx_REG (SImode
, 12);
21509 emit_move_insn (reg
, mem
);
21511 emit_insn (generate_set_vrsave (reg
, info
, 1));
21515 /* If we have a large stack frame, restore the old stack pointer
21516 using the backchain. */
21517 if (use_backchain_to_restore_sp
)
21519 if (frame_reg_rtx
== sp_reg_rtx
)
21521 /* Under V.4, don't reset the stack pointer until after we're done
21522 loading the saved registers. */
21523 if (DEFAULT_ABI
== ABI_V4
)
21524 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21526 insn
= emit_move_insn (frame_reg_rtx
,
21527 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
21530 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21531 && DEFAULT_ABI
== ABI_V4
)
21532 /* frame_reg_rtx has been set up by the altivec restore. */
21536 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
21537 frame_reg_rtx
= sp_reg_rtx
;
21540 /* If we have a frame pointer, we can restore the old stack pointer
21542 else if (frame_pointer_needed
)
21544 frame_reg_rtx
= sp_reg_rtx
;
21545 if (DEFAULT_ABI
== ABI_V4
)
21546 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21547 /* Prevent reordering memory accesses against stack pointer restore. */
21548 else if (cfun
->calls_alloca
21549 || offset_below_red_zone_p (-info
->total_size
))
21551 rtx mem1
= gen_rtx_MEM (BLKmode
, hard_frame_pointer_rtx
);
21552 rtx mem2
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
21553 MEM_NOTRAP_P (mem1
) = 1;
21554 MEM_NOTRAP_P (mem2
) = 1;
21555 emit_insn (gen_frame_tie (mem1
, mem2
));
21558 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
21559 GEN_INT (info
->total_size
)));
21562 else if (info
->push_p
21563 && DEFAULT_ABI
!= ABI_V4
21564 && !crtl
->calls_eh_return
)
21566 /* Prevent reordering memory accesses against stack pointer restore. */
21567 if (cfun
->calls_alloca
21568 || offset_below_red_zone_p (-info
->total_size
))
21570 rtx mem
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
21571 MEM_NOTRAP_P (mem
) = 1;
21572 emit_insn (gen_stack_tie (mem
));
21574 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
21575 GEN_INT (info
->total_size
)));
21578 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
21582 REG_NOTES (insn
) = cfa_restores
;
21583 cfa_restores
= NULL_RTX
;
21585 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21586 RTX_FRAME_RELATED_P (insn
) = 1;
21589 /* Restore AltiVec registers if we have not done so already. */
21590 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21591 && TARGET_ALTIVEC_ABI
21592 && info
->altivec_size
!= 0
21593 && (DEFAULT_ABI
== ABI_V4
21594 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
21598 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
21599 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
21601 rtx addr
, areg
, mem
, reg
;
21603 areg
= gen_rtx_REG (Pmode
, 0);
21605 (areg
, GEN_INT (info
->altivec_save_offset
21607 + 16 * (i
- info
->first_altivec_reg_save
)));
21609 /* AltiVec addressing mode is [reg+reg]. */
21610 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
21611 mem
= gen_frame_mem (V4SImode
, addr
);
21613 reg
= gen_rtx_REG (V4SImode
, i
);
21614 emit_move_insn (reg
, mem
);
21615 if (DEFAULT_ABI
== ABI_V4
)
21616 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21621 /* Restore VRSAVE if we have not done so already. */
21622 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21624 && TARGET_ALTIVEC_VRSAVE
21625 && info
->vrsave_mask
!= 0
21626 && (DEFAULT_ABI
== ABI_V4
21627 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
21629 rtx addr
, mem
, reg
;
21631 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21632 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
21633 mem
= gen_frame_mem (SImode
, addr
);
21634 reg
= gen_rtx_REG (SImode
, 12);
21635 emit_move_insn (reg
, mem
);
21637 emit_insn (generate_set_vrsave (reg
, info
, 1));
21640 /* Get the old lr if we saved it. If we are restoring registers
21641 out-of-line, then the out-of-line routines can do this for us. */
21642 if (restore_lr
&& restoring_GPRs_inline
)
21644 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21645 info
->lr_save_offset
+ sp_offset
);
21647 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21650 /* Get the old cr if we saved it. */
21651 if (info
->cr_save_p
)
21653 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21654 GEN_INT (info
->cr_save_offset
+ sp_offset
));
21655 rtx mem
= gen_frame_mem (SImode
, addr
);
21657 cr_save_reg
= gen_rtx_REG (SImode
,
21658 DEFAULT_ABI
== ABI_AIX
21659 && !restoring_GPRs_inline
21660 && info
->first_fp_reg_save
< 64
21662 emit_move_insn (cr_save_reg
, mem
);
21665 /* Set LR here to try to overlap restores below. LR is always saved
21666 above incoming stack, so it never needs REG_CFA_RESTORE. */
21667 if (restore_lr
&& restoring_GPRs_inline
)
21668 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21669 gen_rtx_REG (Pmode
, 0));
21671 /* Load exception handler data registers, if needed. */
21672 if (crtl
->calls_eh_return
)
21674 unsigned int i
, regno
;
21678 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21679 GEN_INT (sp_offset
+ 5 * reg_size
));
21680 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21682 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
21689 regno
= EH_RETURN_DATA_REGNO (i
);
21690 if (regno
== INVALID_REGNUM
)
21693 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
21694 info
->ehrd_offset
+ sp_offset
21695 + reg_size
* (int) i
);
21697 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
21701 /* Restore GPRs. This is done as a PARALLEL if we are using
21702 the load-multiple instructions. */
21704 && info
->spe_64bit_regs_used
!= 0
21705 && info
->first_gp_reg_save
!= 32)
21707 /* Determine whether we can address all of the registers that need
21708 to be saved with an offset from the stack pointer that fits in
21709 the small const field for SPE memory instructions. */
21710 int spe_regs_addressable_via_sp
21711 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
21712 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
21713 && restoring_GPRs_inline
);
21716 if (spe_regs_addressable_via_sp
)
21717 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
21720 rtx old_frame_reg_rtx
= frame_reg_rtx
;
21721 /* Make r11 point to the start of the SPE save area. We worried about
21722 not clobbering it when we were saving registers in the prologue.
21723 There's no need to worry here because the static chain is passed
21724 anew to every function. */
21725 int ool_adjust
= (restoring_GPRs_inline
21727 : (info
->first_gp_reg_save
21728 - (FIRST_SAVRES_REGISTER
+1))*8);
21730 if (frame_reg_rtx
== sp_reg_rtx
)
21731 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21732 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
21733 GEN_INT (info
->spe_gp_save_offset
21736 /* Keep the invariant that frame_reg_rtx + sp_offset points
21737 at the top of the stack frame. */
21738 sp_offset
= -info
->spe_gp_save_offset
;
21743 if (restoring_GPRs_inline
)
21745 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21746 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21748 rtx offset
, addr
, mem
, reg
;
21750 /* We're doing all this to ensure that the immediate offset
21751 fits into the immediate field of 'evldd'. */
21752 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
21754 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
21755 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
21756 mem
= gen_rtx_MEM (V2SImode
, addr
);
21757 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21759 insn
= emit_move_insn (reg
, mem
);
21760 if (DEFAULT_ABI
== ABI_V4
)
21762 if (frame_pointer_needed
21763 && info
->first_gp_reg_save
+ i
21764 == HARD_FRAME_POINTER_REGNUM
)
21766 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21767 plus_constant (frame_reg_rtx
,
21769 RTX_FRAME_RELATED_P (insn
) = 1;
21772 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21781 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
21783 /*savep=*/false, /*gpr=*/true,
21785 emit_jump_insn (par
);
21786 /* We don't want anybody else emitting things after we jumped
21791 else if (!restoring_GPRs_inline
)
21793 /* We are jumping to an out-of-line function. */
21794 bool can_use_exit
= info
->first_fp_reg_save
== 64;
21797 /* Emit stack reset code if we need it. */
21799 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21800 sp_offset
, can_use_exit
);
21803 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode
, DEFAULT_ABI
== ABI_AIX
21806 GEN_INT (sp_offset
- info
->fp_size
)));
21807 if (REGNO (frame_reg_rtx
) == 11)
21808 sp_offset
+= info
->fp_size
;
21811 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
21812 info
->gp_save_offset
, reg_mode
,
21813 /*savep=*/false, /*gpr=*/true,
21814 /*lr=*/can_use_exit
);
21818 if (info
->cr_save_p
)
21820 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21821 if (DEFAULT_ABI
== ABI_V4
)
21823 = alloc_reg_note (REG_CFA_RESTORE
,
21824 gen_rtx_REG (SImode
, CR2_REGNO
),
21828 emit_jump_insn (par
);
21830 /* We don't want anybody else emitting things after we jumped
21835 insn
= emit_insn (par
);
21836 if (DEFAULT_ABI
== ABI_V4
)
21838 if (frame_pointer_needed
)
21840 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21841 plus_constant (frame_reg_rtx
, sp_offset
));
21842 RTX_FRAME_RELATED_P (insn
) = 1;
21845 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
21847 = alloc_reg_note (REG_CFA_RESTORE
,
21848 gen_rtx_REG (reg_mode
, i
), cfa_restores
);
21851 else if (using_load_multiple
)
21854 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
21855 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21857 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21858 GEN_INT (info
->gp_save_offset
21861 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21862 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21864 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21865 if (DEFAULT_ABI
== ABI_V4
)
21866 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21869 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21870 if (DEFAULT_ABI
== ABI_V4
&& frame_pointer_needed
)
21872 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21873 plus_constant (frame_reg_rtx
, sp_offset
));
21874 RTX_FRAME_RELATED_P (insn
) = 1;
21879 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21880 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21882 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21883 GEN_INT (info
->gp_save_offset
21886 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21887 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21889 insn
= emit_move_insn (reg
, mem
);
21890 if (DEFAULT_ABI
== ABI_V4
)
21892 if (frame_pointer_needed
21893 && info
->first_gp_reg_save
+ i
21894 == HARD_FRAME_POINTER_REGNUM
)
21896 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21897 plus_constant (frame_reg_rtx
, sp_offset
));
21898 RTX_FRAME_RELATED_P (insn
) = 1;
21901 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21907 if (restore_lr
&& !restoring_GPRs_inline
)
21909 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21910 info
->lr_save_offset
+ sp_offset
);
21912 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21913 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21914 gen_rtx_REG (Pmode
, 0));
21917 /* Restore fpr's if we need to do it without calling a function. */
21918 if (restoring_FPRs_inline
)
21919 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21920 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
21921 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
21923 rtx addr
, mem
, reg
;
21924 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21925 GEN_INT (info
->fp_save_offset
21928 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21929 ? DFmode
: SFmode
), addr
);
21930 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21931 ? DFmode
: SFmode
),
21932 info
->first_fp_reg_save
+ i
);
21934 emit_move_insn (reg
, mem
);
21935 if (DEFAULT_ABI
== ABI_V4
)
21936 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21940 /* If we saved cr, restore it here. Just those that were used. */
21941 if (info
->cr_save_p
)
21943 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21944 if (DEFAULT_ABI
== ABI_V4
)
21946 = alloc_reg_note (REG_CFA_RESTORE
, gen_rtx_REG (SImode
, CR2_REGNO
),
21950 /* If this is V.4, unwind the stack pointer after all of the loads
21952 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21953 sp_offset
, !restoring_FPRs_inline
);
21958 REG_NOTES (insn
) = cfa_restores
;
21959 cfa_restores
= NULL_RTX
;
21961 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21962 RTX_FRAME_RELATED_P (insn
) = 1;
21965 if (crtl
->calls_eh_return
)
21967 rtx sa
= EH_RETURN_STACKADJ_RTX
;
21968 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
21974 bool lr
= (strategy
& REST_NOINLINE_FPRS_DOESNT_RESTORE_LR
) == 0;
21975 if (! restoring_FPRs_inline
)
21976 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
21978 p
= rtvec_alloc (2);
21980 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
21981 RTVEC_ELT (p
, 1) = ((restoring_FPRs_inline
|| !lr
)
21982 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
21983 : gen_rtx_CLOBBER (VOIDmode
,
21984 gen_rtx_REG (Pmode
, 65)));
21986 /* If we have to restore more than two FP registers, branch to the
21987 restore function. It will return to our caller. */
21988 if (! restoring_FPRs_inline
)
21993 sym
= rs6000_savres_routine_sym (info
,
21997 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
21998 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
21999 gen_rtx_REG (Pmode
,
22000 DEFAULT_ABI
== ABI_AIX
22002 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
22005 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
22006 GEN_INT (info
->fp_save_offset
+ 8*i
));
22007 mem
= gen_frame_mem (DFmode
, addr
);
22009 RTVEC_ELT (p
, i
+4) =
22010 gen_rtx_SET (VOIDmode
,
22011 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
22016 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
22020 /* Write function epilogue. */
22023 rs6000_output_function_epilogue (FILE *file
,
22024 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
22026 if (! HAVE_epilogue
)
22028 rtx insn
= get_last_insn ();
22029 /* If the last insn was a BARRIER, we don't have to write anything except
22030 the trace table. */
22031 if (GET_CODE (insn
) == NOTE
)
22032 insn
= prev_nonnote_insn (insn
);
22033 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
22035 /* This is slightly ugly, but at least we don't have two
22036 copies of the epilogue-emitting code. */
22039 /* A NOTE_INSN_DELETED is supposed to be at the start
22040 and end of the "toplevel" insn chain. */
22041 emit_note (NOTE_INSN_DELETED
);
22042 rs6000_emit_epilogue (FALSE
);
22043 emit_note (NOTE_INSN_DELETED
);
22045 /* Expand INSN_ADDRESSES so final() doesn't crash. */
22049 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
22051 INSN_ADDRESSES_NEW (insn
, addr
);
22056 if (TARGET_DEBUG_STACK
)
22057 debug_rtx_list (get_insns (), 100);
22058 final (get_insns (), file
, FALSE
);
22064 macho_branch_islands ();
22065 /* Mach-O doesn't support labels at the end of objects, so if
22066 it looks like we might want one, insert a NOP. */
22068 rtx insn
= get_last_insn ();
22071 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
22072 insn
= PREV_INSN (insn
);
22076 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
22077 fputs ("\tnop\n", file
);
22081 /* Output a traceback table here. See /usr/include/sys/debug.h for info
22084 We don't output a traceback table if -finhibit-size-directive was
22085 used. The documentation for -finhibit-size-directive reads
22086 ``don't output a @code{.size} assembler directive, or anything
22087 else that would cause trouble if the function is split in the
22088 middle, and the two halves are placed at locations far apart in
22089 memory.'' The traceback table has this property, since it
22090 includes the offset from the start of the function to the
22091 traceback table itself.
22093 System V.4 Powerpc's (and the embedded ABI derived from it) use a
22094 different traceback table. */
22095 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
22096 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
22098 const char *fname
= NULL
;
22099 const char *language_string
= lang_hooks
.name
;
22100 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
22102 int optional_tbtab
;
22103 rs6000_stack_t
*info
= rs6000_stack_info ();
22105 if (rs6000_traceback
== traceback_full
)
22106 optional_tbtab
= 1;
22107 else if (rs6000_traceback
== traceback_part
)
22108 optional_tbtab
= 0;
22110 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
22112 if (optional_tbtab
)
22114 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
22115 while (*fname
== '.') /* V.4 encodes . in the name */
22118 /* Need label immediately before tbtab, so we can compute
22119 its offset from the function start. */
22120 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
22121 ASM_OUTPUT_LABEL (file
, fname
);
22124 /* The .tbtab pseudo-op can only be used for the first eight
22125 expressions, since it can't handle the possibly variable
22126 length fields that follow. However, if you omit the optional
22127 fields, the assembler outputs zeros for all optional fields
22128 anyways, giving each variable length field is minimum length
22129 (as defined in sys/debug.h). Thus we can not use the .tbtab
22130 pseudo-op at all. */
22132 /* An all-zero word flags the start of the tbtab, for debuggers
22133 that have to find it by searching forward from the entry
22134 point or from the current pc. */
22135 fputs ("\t.long 0\n", file
);
22137 /* Tbtab format type. Use format type 0. */
22138 fputs ("\t.byte 0,", file
);
22140 /* Language type. Unfortunately, there does not seem to be any
22141 official way to discover the language being compiled, so we
22142 use language_string.
22143 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22144 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22145 a number, so for now use 9. LTO and Go aren't assigned numbers
22146 either, so for now use 0. */
22147 if (! strcmp (language_string
, "GNU C")
22148 || ! strcmp (language_string
, "GNU GIMPLE")
22149 || ! strcmp (language_string
, "GNU Go"))
22151 else if (! strcmp (language_string
, "GNU F77")
22152 || ! strcmp (language_string
, "GNU Fortran"))
22154 else if (! strcmp (language_string
, "GNU Pascal"))
22156 else if (! strcmp (language_string
, "GNU Ada"))
22158 else if (! strcmp (language_string
, "GNU C++")
22159 || ! strcmp (language_string
, "GNU Objective-C++"))
22161 else if (! strcmp (language_string
, "GNU Java"))
22163 else if (! strcmp (language_string
, "GNU Objective-C"))
22166 gcc_unreachable ();
22167 fprintf (file
, "%d,", i
);
22169 /* 8 single bit fields: global linkage (not set for C extern linkage,
22170 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22171 from start of procedure stored in tbtab, internal function, function
22172 has controlled storage, function has no toc, function uses fp,
22173 function logs/aborts fp operations. */
22174 /* Assume that fp operations are used if any fp reg must be saved. */
22175 fprintf (file
, "%d,",
22176 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
22178 /* 6 bitfields: function is interrupt handler, name present in
22179 proc table, function calls alloca, on condition directives
22180 (controls stack walks, 3 bits), saves condition reg, saves
22182 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22183 set up as a frame pointer, even when there is no alloca call. */
22184 fprintf (file
, "%d,",
22185 ((optional_tbtab
<< 6)
22186 | ((optional_tbtab
& frame_pointer_needed
) << 5)
22187 | (info
->cr_save_p
<< 1)
22188 | (info
->lr_save_p
)));
22190 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22192 fprintf (file
, "%d,",
22193 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
22195 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22196 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
22198 if (optional_tbtab
)
22200 /* Compute the parameter info from the function decl argument
22203 int next_parm_info_bit
= 31;
22205 for (decl
= DECL_ARGUMENTS (current_function_decl
);
22206 decl
; decl
= DECL_CHAIN (decl
))
22208 rtx parameter
= DECL_INCOMING_RTL (decl
);
22209 enum machine_mode mode
= GET_MODE (parameter
);
22211 if (GET_CODE (parameter
) == REG
)
22213 if (SCALAR_FLOAT_MODE_P (mode
))
22234 gcc_unreachable ();
22237 /* If only one bit will fit, don't or in this entry. */
22238 if (next_parm_info_bit
> 0)
22239 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
22240 next_parm_info_bit
-= 2;
22244 fixed_parms
+= ((GET_MODE_SIZE (mode
)
22245 + (UNITS_PER_WORD
- 1))
22247 next_parm_info_bit
-= 1;
22253 /* Number of fixed point parameters. */
22254 /* This is actually the number of words of fixed point parameters; thus
22255 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22256 fprintf (file
, "%d,", fixed_parms
);
22258 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22260 /* This is actually the number of fp registers that hold parameters;
22261 and thus the maximum value is 13. */
22262 /* Set parameters on stack bit if parameters are not in their original
22263 registers, regardless of whether they are on the stack? Xlc
22264 seems to set the bit when not optimizing. */
22265 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
22267 if (! optional_tbtab
)
22270 /* Optional fields follow. Some are variable length. */
22272 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22273 11 double float. */
22274 /* There is an entry for each parameter in a register, in the order that
22275 they occur in the parameter list. Any intervening arguments on the
22276 stack are ignored. If the list overflows a long (max possible length
22277 34 bits) then completely leave off all elements that don't fit. */
22278 /* Only emit this long if there was at least one parameter. */
22279 if (fixed_parms
|| float_parms
)
22280 fprintf (file
, "\t.long %d\n", parm_info
);
22282 /* Offset from start of code to tb table. */
22283 fputs ("\t.long ", file
);
22284 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
22285 RS6000_OUTPUT_BASENAME (file
, fname
);
22287 rs6000_output_function_entry (file
, fname
);
22290 /* Interrupt handler mask. */
22291 /* Omit this long, since we never set the interrupt handler bit
22294 /* Number of CTL (controlled storage) anchors. */
22295 /* Omit this long, since the has_ctl bit is never set above. */
22297 /* Displacement into stack of each CTL anchor. */
22298 /* Omit this list of longs, because there are no CTL anchors. */
22300 /* Length of function name. */
22303 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
22305 /* Function name. */
22306 assemble_string (fname
, strlen (fname
));
22308 /* Register for alloca automatic storage; this is always reg 31.
22309 Only emit this if the alloca bit was set above. */
22310 if (frame_pointer_needed
)
22311 fputs ("\t.byte 31\n", file
);
22313 fputs ("\t.align 2\n", file
);
22317 /* A C compound statement that outputs the assembler code for a thunk
22318 function, used to implement C++ virtual function calls with
22319 multiple inheritance. The thunk acts as a wrapper around a virtual
22320 function, adjusting the implicit object parameter before handing
22321 control off to the real function.
22323 First, emit code to add the integer DELTA to the location that
22324 contains the incoming first argument. Assume that this argument
22325 contains a pointer, and is the one used to pass the `this' pointer
22326 in C++. This is the incoming argument *before* the function
22327 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22328 values of all other incoming arguments.
22330 After the addition, emit code to jump to FUNCTION, which is a
22331 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22332 not touch the return address. Hence returning from FUNCTION will
22333 return to whoever called the current `thunk'.
22335 The effect must be as if FUNCTION had been called directly with the
22336 adjusted first argument. This macro is responsible for emitting
22337 all of the code for a thunk function; output_function_prologue()
22338 and output_function_epilogue() are not invoked.
22340 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22341 been extracted from it.) It might possibly be useful on some
22342 targets, but probably not.
22344 If you do not define this macro, the target-independent code in the
22345 C++ frontend will generate a less efficient heavyweight thunk that
22346 calls FUNCTION instead of jumping to it. The generic approach does
22347 not support varargs. */
22350 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
22351 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
22354 rtx this_rtx
, insn
, funexp
;
22356 reload_completed
= 1;
22357 epilogue_completed
= 1;
22359 /* Mark the end of the (empty) prologue. */
22360 emit_note (NOTE_INSN_PROLOGUE_END
);
22362 /* Find the "this" pointer. If the function returns a structure,
22363 the structure return pointer is in r3. */
22364 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
22365 this_rtx
= gen_rtx_REG (Pmode
, 4);
22367 this_rtx
= gen_rtx_REG (Pmode
, 3);
22369 /* Apply the constant offset, if required. */
22371 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
22373 /* Apply the offset from the vtable, if required. */
22376 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
22377 rtx tmp
= gen_rtx_REG (Pmode
, 12);
22379 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
22380 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
22382 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
22383 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
22387 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
22389 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
22391 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
22394 /* Generate a tail call to the target function. */
22395 if (!TREE_USED (function
))
22397 assemble_external (function
);
22398 TREE_USED (function
) = 1;
22400 funexp
= XEXP (DECL_RTL (function
), 0);
22401 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
22404 if (MACHOPIC_INDIRECT
)
22405 funexp
= machopic_indirect_call_target (funexp
);
22408 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22409 generate sibcall RTL explicitly. */
22410 insn
= emit_call_insn (
22411 gen_rtx_PARALLEL (VOIDmode
,
22413 gen_rtx_CALL (VOIDmode
,
22414 funexp
, const0_rtx
),
22415 gen_rtx_USE (VOIDmode
, const0_rtx
),
22416 gen_rtx_USE (VOIDmode
,
22417 gen_rtx_REG (SImode
,
22419 gen_rtx_RETURN (VOIDmode
))));
22420 SIBLING_CALL_P (insn
) = 1;
22423 /* Run just enough of rest_of_compilation to get the insns emitted.
22424 There's not really enough bulk here to make other passes such as
22425 instruction scheduling worth while. Note that use_thunk calls
22426 assemble_start_function and assemble_end_function. */
22427 insn
= get_insns ();
22428 insn_locators_alloc ();
22429 shorten_branches (insn
);
22430 final_start_function (insn
, file
, 1);
22431 final (insn
, file
, 1);
22432 final_end_function ();
22434 reload_completed
= 0;
22435 epilogue_completed
= 0;
22438 /* A quick summary of the various types of 'constant-pool tables'
22441 Target Flags Name One table per
22442 AIX (none) AIX TOC object file
22443 AIX -mfull-toc AIX TOC object file
22444 AIX -mminimal-toc AIX minimal TOC translation unit
22445 SVR4/EABI (none) SVR4 SDATA object file
22446 SVR4/EABI -fpic SVR4 pic object file
22447 SVR4/EABI -fPIC SVR4 PIC translation unit
22448 SVR4/EABI -mrelocatable EABI TOC function
22449 SVR4/EABI -maix AIX TOC object file
22450 SVR4/EABI -maix -mminimal-toc
22451 AIX minimal TOC translation unit
22453 Name Reg. Set by entries contains:
22454 made by addrs? fp? sum?
22456 AIX TOC 2 crt0 as Y option option
22457 AIX minimal TOC 30 prolog gcc Y Y option
22458 SVR4 SDATA 13 crt0 gcc N Y N
22459 SVR4 pic 30 prolog ld Y not yet N
22460 SVR4 PIC 30 prolog gcc Y option option
22461 EABI TOC 30 prolog gcc Y option option
22465 /* Hash functions for the hash table. */
22468 rs6000_hash_constant (rtx k
)
22470 enum rtx_code code
= GET_CODE (k
);
22471 enum machine_mode mode
= GET_MODE (k
);
22472 unsigned result
= (code
<< 3) ^ mode
;
22473 const char *format
;
22476 format
= GET_RTX_FORMAT (code
);
22477 flen
= strlen (format
);
22483 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
22486 if (mode
!= VOIDmode
)
22487 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
22499 for (; fidx
< flen
; fidx
++)
22500 switch (format
[fidx
])
22505 const char *str
= XSTR (k
, fidx
);
22506 len
= strlen (str
);
22507 result
= result
* 613 + len
;
22508 for (i
= 0; i
< len
; i
++)
22509 result
= result
* 613 + (unsigned) str
[i
];
22514 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
22518 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
22521 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
22522 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
22526 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
22527 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
22534 gcc_unreachable ();
22541 toc_hash_function (const void *hash_entry
)
22543 const struct toc_hash_struct
*thc
=
22544 (const struct toc_hash_struct
*) hash_entry
;
22545 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
22548 /* Compare H1 and H2 for equivalence. */
22551 toc_hash_eq (const void *h1
, const void *h2
)
22553 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
22554 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
22556 if (((const struct toc_hash_struct
*) h1
)->key_mode
22557 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
22560 return rtx_equal_p (r1
, r2
);
22563 /* These are the names given by the C++ front-end to vtables, and
22564 vtable-like objects. Ideally, this logic should not be here;
22565 instead, there should be some programmatic way of inquiring as
22566 to whether or not an object is a vtable. */
22568 #define VTABLE_NAME_P(NAME) \
22569 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22570 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22571 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22572 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22573 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22575 #ifdef NO_DOLLAR_IN_LABEL
22576 /* Return a GGC-allocated character string translating dollar signs in
22577 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22580 rs6000_xcoff_strip_dollar (const char *name
)
22585 p
= strchr (name
, '$');
22587 if (p
== 0 || p
== name
)
22590 len
= strlen (name
);
22591 strip
= (char *) alloca (len
+ 1);
22592 strcpy (strip
, name
);
22593 p
= strchr (strip
, '$');
22597 p
= strchr (p
+ 1, '$');
22600 return ggc_alloc_string (strip
, len
);
22605 rs6000_output_symbol_ref (FILE *file
, rtx x
)
22607 /* Currently C++ toc references to vtables can be emitted before it
22608 is decided whether the vtable is public or private. If this is
22609 the case, then the linker will eventually complain that there is
22610 a reference to an unknown section. Thus, for vtables only,
22611 we emit the TOC reference to reference the symbol and not the
22613 const char *name
= XSTR (x
, 0);
22615 if (VTABLE_NAME_P (name
))
22617 RS6000_OUTPUT_BASENAME (file
, name
);
22620 assemble_name (file
, name
);
22623 /* Output a TOC entry. We derive the entry name from what is being
22627 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
22630 const char *name
= buf
;
22632 HOST_WIDE_INT offset
= 0;
22634 gcc_assert (!TARGET_NO_TOC
);
22636 /* When the linker won't eliminate them, don't output duplicate
22637 TOC entries (this happens on AIX if there is any kind of TOC,
22638 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22640 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
22642 struct toc_hash_struct
*h
;
22645 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22646 time because GGC is not initialized at that point. */
22647 if (toc_hash_table
== NULL
)
22648 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
22649 toc_hash_eq
, NULL
);
22651 h
= ggc_alloc_toc_hash_struct ();
22653 h
->key_mode
= mode
;
22654 h
->labelno
= labelno
;
22656 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
22657 if (*found
== NULL
)
22659 else /* This is indeed a duplicate.
22660 Set this label equal to that label. */
22662 fputs ("\t.set ", file
);
22663 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22664 fprintf (file
, "%d,", labelno
);
22665 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22666 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
22672 /* If we're going to put a double constant in the TOC, make sure it's
22673 aligned properly when strict alignment is on. */
22674 if (GET_CODE (x
) == CONST_DOUBLE
22675 && STRICT_ALIGNMENT
22676 && GET_MODE_BITSIZE (mode
) >= 64
22677 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
22678 ASM_OUTPUT_ALIGN (file
, 3);
22681 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
22683 /* Handle FP constants specially. Note that if we have a minimal
22684 TOC, things we put here aren't actually in the TOC, so we can allow
22686 if (GET_CODE (x
) == CONST_DOUBLE
&&
22687 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
22689 REAL_VALUE_TYPE rv
;
22692 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22693 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22694 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
22696 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
22700 if (TARGET_MINIMAL_TOC
)
22701 fputs (DOUBLE_INT_ASM_OP
, file
);
22703 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22704 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22705 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22706 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
22707 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22708 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22713 if (TARGET_MINIMAL_TOC
)
22714 fputs ("\t.long ", file
);
22716 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22717 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22718 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22719 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22720 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22721 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22725 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22726 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
22728 REAL_VALUE_TYPE rv
;
22731 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22733 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22734 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
22736 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
22740 if (TARGET_MINIMAL_TOC
)
22741 fputs (DOUBLE_INT_ASM_OP
, file
);
22743 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22744 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22745 fprintf (file
, "0x%lx%08lx\n",
22746 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22751 if (TARGET_MINIMAL_TOC
)
22752 fputs ("\t.long ", file
);
22754 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22755 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22756 fprintf (file
, "0x%lx,0x%lx\n",
22757 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22761 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22762 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
22764 REAL_VALUE_TYPE rv
;
22767 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22768 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22769 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
22771 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
22775 if (TARGET_MINIMAL_TOC
)
22776 fputs (DOUBLE_INT_ASM_OP
, file
);
22778 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22779 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
22784 if (TARGET_MINIMAL_TOC
)
22785 fputs ("\t.long ", file
);
22787 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22788 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
22792 else if (GET_MODE (x
) == VOIDmode
22793 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
22795 unsigned HOST_WIDE_INT low
;
22796 HOST_WIDE_INT high
;
22798 if (GET_CODE (x
) == CONST_DOUBLE
)
22800 low
= CONST_DOUBLE_LOW (x
);
22801 high
= CONST_DOUBLE_HIGH (x
);
22804 #if HOST_BITS_PER_WIDE_INT == 32
22807 high
= (low
& 0x80000000) ? ~0 : 0;
22811 low
= INTVAL (x
) & 0xffffffff;
22812 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
22816 /* TOC entries are always Pmode-sized, but since this
22817 is a bigendian machine then if we're putting smaller
22818 integer constants in the TOC we have to pad them.
22819 (This is still a win over putting the constants in
22820 a separate constant pool, because then we'd have
22821 to have both a TOC entry _and_ the actual constant.)
22823 For a 32-bit target, CONST_INT values are loaded and shifted
22824 entirely within `low' and can be stored in one TOC entry. */
22826 /* It would be easy to make this work, but it doesn't now. */
22827 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
22829 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
22831 #if HOST_BITS_PER_WIDE_INT == 32
22832 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
22833 POINTER_SIZE
, &low
, &high
, 0);
22836 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
22837 high
= (HOST_WIDE_INT
) low
>> 32;
22844 if (TARGET_MINIMAL_TOC
)
22845 fputs (DOUBLE_INT_ASM_OP
, file
);
22847 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22848 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22849 fprintf (file
, "0x%lx%08lx\n",
22850 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22855 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
22857 if (TARGET_MINIMAL_TOC
)
22858 fputs ("\t.long ", file
);
22860 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22861 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22862 fprintf (file
, "0x%lx,0x%lx\n",
22863 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22867 if (TARGET_MINIMAL_TOC
)
22868 fputs ("\t.long ", file
);
22870 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
22871 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
22877 if (GET_CODE (x
) == CONST
)
22879 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
22880 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
22882 base
= XEXP (XEXP (x
, 0), 0);
22883 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
22886 switch (GET_CODE (base
))
22889 name
= XSTR (base
, 0);
22893 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
22894 CODE_LABEL_NUMBER (XEXP (base
, 0)));
22898 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
22902 gcc_unreachable ();
22905 if (TARGET_MINIMAL_TOC
)
22906 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
22909 fputs ("\t.tc ", file
);
22910 RS6000_OUTPUT_BASENAME (file
, name
);
22913 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
22915 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
22917 fputs ("[TC],", file
);
22920 /* Currently C++ toc references to vtables can be emitted before it
22921 is decided whether the vtable is public or private. If this is
22922 the case, then the linker will eventually complain that there is
22923 a TOC reference to an unknown section. Thus, for vtables only,
22924 we emit the TOC reference to reference the symbol and not the
22926 if (VTABLE_NAME_P (name
))
22928 RS6000_OUTPUT_BASENAME (file
, name
);
22930 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
22931 else if (offset
> 0)
22932 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
22935 output_addr_const (file
, x
);
22939 /* Output an assembler pseudo-op to write an ASCII string of N characters
22940 starting at P to FILE.
22942 On the RS/6000, we have to do this using the .byte operation and
22943 write out special characters outside the quoted string.
22944 Also, the assembler is broken; very long strings are truncated,
22945 so we must artificially break them up early. */
22948 output_ascii (FILE *file
, const char *p
, int n
)
22951 int i
, count_string
;
22952 const char *for_string
= "\t.byte \"";
22953 const char *for_decimal
= "\t.byte ";
22954 const char *to_close
= NULL
;
22957 for (i
= 0; i
< n
; i
++)
22960 if (c
>= ' ' && c
< 0177)
22963 fputs (for_string
, file
);
22966 /* Write two quotes to get one. */
22974 for_decimal
= "\"\n\t.byte ";
22978 if (count_string
>= 512)
22980 fputs (to_close
, file
);
22982 for_string
= "\t.byte \"";
22983 for_decimal
= "\t.byte ";
22991 fputs (for_decimal
, file
);
22992 fprintf (file
, "%d", c
);
22994 for_string
= "\n\t.byte \"";
22995 for_decimal
= ", ";
23001 /* Now close the string if we have written one. Then end the line. */
23003 fputs (to_close
, file
);
23006 /* Generate a unique section name for FILENAME for a section type
23007 represented by SECTION_DESC. Output goes into BUF.
23009 SECTION_DESC can be any string, as long as it is different for each
23010 possible section type.
23012 We name the section in the same manner as xlc. The name begins with an
23013 underscore followed by the filename (after stripping any leading directory
23014 names) with the last period replaced by the string SECTION_DESC. If
23015 FILENAME does not contain a period, SECTION_DESC is appended to the end of
23019 rs6000_gen_section_name (char **buf
, const char *filename
,
23020 const char *section_desc
)
23022 const char *q
, *after_last_slash
, *last_period
= 0;
23026 after_last_slash
= filename
;
23027 for (q
= filename
; *q
; q
++)
23030 after_last_slash
= q
+ 1;
23031 else if (*q
== '.')
23035 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
23036 *buf
= (char *) xmalloc (len
);
23041 for (q
= after_last_slash
; *q
; q
++)
23043 if (q
== last_period
)
23045 strcpy (p
, section_desc
);
23046 p
+= strlen (section_desc
);
23050 else if (ISALNUM (*q
))
23054 if (last_period
== 0)
23055 strcpy (p
, section_desc
);
23060 /* Emit profile function. */
23063 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
23065 /* Non-standard profiling for kernels, which just saves LR then calls
23066 _mcount without worrying about arg saves. The idea is to change
23067 the function prologue as little as possible as it isn't easy to
23068 account for arg save/restore code added just for _mcount. */
23069 if (TARGET_PROFILE_KERNEL
)
23072 if (DEFAULT_ABI
== ABI_AIX
)
23074 #ifndef NO_PROFILE_COUNTERS
23075 # define NO_PROFILE_COUNTERS 0
23077 if (NO_PROFILE_COUNTERS
)
23078 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
23079 LCT_NORMAL
, VOIDmode
, 0);
23083 const char *label_name
;
23086 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
23087 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
23088 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
23090 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
23091 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
23094 else if (DEFAULT_ABI
== ABI_DARWIN
)
23096 const char *mcount_name
= RS6000_MCOUNT
;
23097 int caller_addr_regno
= LR_REGNO
;
23099 /* Be conservative and always set this, at least for now. */
23100 crtl
->uses_pic_offset_table
= 1;
23103 /* For PIC code, set up a stub and collect the caller's address
23104 from r0, which is where the prologue puts it. */
23105 if (MACHOPIC_INDIRECT
23106 && crtl
->uses_pic_offset_table
)
23107 caller_addr_regno
= 0;
23109 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
23110 LCT_NORMAL
, VOIDmode
, 1,
23111 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
23115 /* Write function profiler code. */
23118 output_function_profiler (FILE *file
, int labelno
)
23122 switch (DEFAULT_ABI
)
23125 gcc_unreachable ();
23130 warning (0, "no profiling of 64-bit code for this ABI");
23133 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
23134 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
23135 if (NO_PROFILE_COUNTERS
)
23137 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23138 reg_names
[0], reg_names
[1]);
23140 else if (TARGET_SECURE_PLT
&& flag_pic
)
23142 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23143 reg_names
[0], reg_names
[1]);
23144 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
23145 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
23146 reg_names
[12], reg_names
[12]);
23147 assemble_name (file
, buf
);
23148 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
23149 assemble_name (file
, buf
);
23150 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
23152 else if (flag_pic
== 1)
23154 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
23155 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23156 reg_names
[0], reg_names
[1]);
23157 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
23158 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
23159 assemble_name (file
, buf
);
23160 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
23162 else if (flag_pic
> 1)
23164 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23165 reg_names
[0], reg_names
[1]);
23166 /* Now, we need to get the address of the label. */
23167 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
23168 assemble_name (file
, buf
);
23169 fputs ("-.\n1:", file
);
23170 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
23171 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
23172 reg_names
[0], reg_names
[11]);
23173 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
23174 reg_names
[0], reg_names
[0], reg_names
[11]);
23178 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
23179 assemble_name (file
, buf
);
23180 fputs ("@ha\n", file
);
23181 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
23182 reg_names
[0], reg_names
[1]);
23183 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
23184 assemble_name (file
, buf
);
23185 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
23188 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23189 fprintf (file
, "\tbl %s%s\n",
23190 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
23195 if (!TARGET_PROFILE_KERNEL
)
23197 /* Don't do anything, done in output_profile_hook (). */
23201 gcc_assert (!TARGET_32BIT
);
23203 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
23204 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
23206 if (cfun
->static_chain_decl
!= NULL
)
23208 asm_fprintf (file
, "\tstd %s,24(%s)\n",
23209 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
23210 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
23211 asm_fprintf (file
, "\tld %s,24(%s)\n",
23212 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
23215 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
23223 /* The following variable value is the last issued insn. */
23225 static rtx last_scheduled_insn
;
23227 /* The following variable helps to balance issuing of load and
23228 store instructions */
23230 static int load_store_pendulum
;
23232 /* Power4 load update and store update instructions are cracked into a
23233 load or store and an integer insn which are executed in the same cycle.
23234 Branches have their own dispatch slot which does not count against the
23235 GCC issue rate, but it changes the program flow so there are no other
23236 instructions to issue in this cycle. */
23239 rs6000_variable_issue_1 (rtx insn
, int more
)
23241 last_scheduled_insn
= insn
;
23242 if (GET_CODE (PATTERN (insn
)) == USE
23243 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23245 cached_can_issue_more
= more
;
23246 return cached_can_issue_more
;
23249 if (insn_terminates_group_p (insn
, current_group
))
23251 cached_can_issue_more
= 0;
23252 return cached_can_issue_more
;
23255 /* If no reservation, but reach here */
23256 if (recog_memoized (insn
) < 0)
23259 if (rs6000_sched_groups
)
23261 if (is_microcoded_insn (insn
))
23262 cached_can_issue_more
= 0;
23263 else if (is_cracked_insn (insn
))
23264 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
23266 cached_can_issue_more
= more
- 1;
23268 return cached_can_issue_more
;
23271 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
23274 cached_can_issue_more
= more
- 1;
23275 return cached_can_issue_more
;
23279 rs6000_variable_issue (FILE *stream
, int verbose
, rtx insn
, int more
)
23281 int r
= rs6000_variable_issue_1 (insn
, more
);
23283 fprintf (stream
, "// rs6000_variable_issue (more = %d) = %d\n", more
, r
);
23287 /* Adjust the cost of a scheduling dependency. Return the new cost of
23288 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23291 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
23293 enum attr_type attr_type
;
23295 if (! recog_memoized (insn
))
23298 switch (REG_NOTE_KIND (link
))
23302 /* Data dependency; DEP_INSN writes a register that INSN reads
23303 some cycles later. */
23305 /* Separate a load from a narrower, dependent store. */
23306 if (rs6000_sched_groups
23307 && GET_CODE (PATTERN (insn
)) == SET
23308 && GET_CODE (PATTERN (dep_insn
)) == SET
23309 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
23310 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
23311 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
23312 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
23315 attr_type
= get_attr_type (insn
);
23320 /* Tell the first scheduling pass about the latency between
23321 a mtctr and bctr (and mtlr and br/blr). The first
23322 scheduling pass will not know about this latency since
23323 the mtctr instruction, which has the latency associated
23324 to it, will be generated by reload. */
23325 return TARGET_POWER
? 5 : 4;
23327 /* Leave some extra cycles between a compare and its
23328 dependent branch, to inhibit expensive mispredicts. */
23329 if ((rs6000_cpu_attr
== CPU_PPC603
23330 || rs6000_cpu_attr
== CPU_PPC604
23331 || rs6000_cpu_attr
== CPU_PPC604E
23332 || rs6000_cpu_attr
== CPU_PPC620
23333 || rs6000_cpu_attr
== CPU_PPC630
23334 || rs6000_cpu_attr
== CPU_PPC750
23335 || rs6000_cpu_attr
== CPU_PPC7400
23336 || rs6000_cpu_attr
== CPU_PPC7450
23337 || rs6000_cpu_attr
== CPU_POWER4
23338 || rs6000_cpu_attr
== CPU_POWER5
23339 || rs6000_cpu_attr
== CPU_POWER7
23340 || rs6000_cpu_attr
== CPU_CELL
)
23341 && recog_memoized (dep_insn
)
23342 && (INSN_CODE (dep_insn
) >= 0))
23344 switch (get_attr_type (dep_insn
))
23348 case TYPE_DELAYED_COMPARE
:
23349 case TYPE_IMUL_COMPARE
:
23350 case TYPE_LMUL_COMPARE
:
23351 case TYPE_FPCOMPARE
:
23352 case TYPE_CR_LOGICAL
:
23353 case TYPE_DELAYED_CR
:
23362 case TYPE_STORE_UX
:
23364 case TYPE_FPSTORE_U
:
23365 case TYPE_FPSTORE_UX
:
23366 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23367 && recog_memoized (dep_insn
)
23368 && (INSN_CODE (dep_insn
) >= 0))
23371 if (GET_CODE (PATTERN (insn
)) != SET
)
23372 /* If this happens, we have to extend this to schedule
23373 optimally. Return default for now. */
23376 /* Adjust the cost for the case where the value written
23377 by a fixed point operation is used as the address
23378 gen value on a store. */
23379 switch (get_attr_type (dep_insn
))
23386 if (! store_data_bypass_p (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 (! store_data_bypass_p (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 (! store_data_bypass_p (dep_insn
, insn
))
23422 case TYPE_IMUL_COMPARE
:
23423 case TYPE_LMUL_COMPARE
:
23425 if (! store_data_bypass_p (dep_insn
, insn
))
23431 if (! store_data_bypass_p (dep_insn
, insn
))
23437 if (! store_data_bypass_p (dep_insn
, insn
))
23450 case TYPE_LOAD_EXT
:
23451 case TYPE_LOAD_EXT_U
:
23452 case TYPE_LOAD_EXT_UX
:
23453 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23454 && recog_memoized (dep_insn
)
23455 && (INSN_CODE (dep_insn
) >= 0))
23458 /* Adjust the cost for the case where the value written
23459 by a fixed point instruction is used within the address
23460 gen portion of a subsequent load(u)(x) */
23461 switch (get_attr_type (dep_insn
))
23468 if (set_to_load_agen (dep_insn
, insn
))
23472 case TYPE_LOAD_EXT
:
23473 case TYPE_LOAD_EXT_U
:
23474 case TYPE_LOAD_EXT_UX
:
23475 case TYPE_VAR_SHIFT_ROTATE
:
23476 case TYPE_VAR_DELAYED_COMPARE
:
23478 if (set_to_load_agen (dep_insn
, insn
))
23484 case TYPE_FAST_COMPARE
:
23487 case TYPE_INSERT_WORD
:
23488 case TYPE_INSERT_DWORD
:
23489 case TYPE_FPLOAD_U
:
23490 case TYPE_FPLOAD_UX
:
23492 case TYPE_STORE_UX
:
23493 case TYPE_FPSTORE_U
:
23494 case TYPE_FPSTORE_UX
:
23496 if (set_to_load_agen (dep_insn
, insn
))
23504 case TYPE_IMUL_COMPARE
:
23505 case TYPE_LMUL_COMPARE
:
23507 if (set_to_load_agen (dep_insn
, insn
))
23513 if (set_to_load_agen (dep_insn
, insn
))
23519 if (set_to_load_agen (dep_insn
, insn
))
23530 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23531 && recog_memoized (dep_insn
)
23532 && (INSN_CODE (dep_insn
) >= 0)
23533 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
23540 /* Fall out to return default cost. */
23544 case REG_DEP_OUTPUT
:
23545 /* Output dependency; DEP_INSN writes a register that INSN writes some
23547 if ((rs6000_cpu
== PROCESSOR_POWER6
)
23548 && recog_memoized (dep_insn
)
23549 && (INSN_CODE (dep_insn
) >= 0))
23551 attr_type
= get_attr_type (insn
);
23556 if (get_attr_type (dep_insn
) == TYPE_FP
)
23560 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
23568 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23573 gcc_unreachable ();
23579 /* Debug version of rs6000_adjust_cost. */
23582 rs6000_debug_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
23584 int ret
= rs6000_adjust_cost (insn
, link
, dep_insn
, cost
);
23590 switch (REG_NOTE_KIND (link
))
23592 default: dep
= "unknown depencency"; break;
23593 case REG_DEP_TRUE
: dep
= "data dependency"; break;
23594 case REG_DEP_OUTPUT
: dep
= "output dependency"; break;
23595 case REG_DEP_ANTI
: dep
= "anti depencency"; break;
23599 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23600 "%s, insn:\n", ret
, cost
, dep
);
23608 /* The function returns a true if INSN is microcoded.
23609 Return false otherwise. */
23612 is_microcoded_insn (rtx insn
)
23614 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23615 || GET_CODE (PATTERN (insn
)) == USE
23616 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23619 if (rs6000_cpu_attr
== CPU_CELL
)
23620 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
23622 if (rs6000_sched_groups
)
23624 enum attr_type type
= get_attr_type (insn
);
23625 if (type
== TYPE_LOAD_EXT_U
23626 || type
== TYPE_LOAD_EXT_UX
23627 || type
== TYPE_LOAD_UX
23628 || type
== TYPE_STORE_UX
23629 || type
== TYPE_MFCR
)
23636 /* The function returns true if INSN is cracked into 2 instructions
23637 by the processor (and therefore occupies 2 issue slots). */
23640 is_cracked_insn (rtx insn
)
23642 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23643 || GET_CODE (PATTERN (insn
)) == USE
23644 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23647 if (rs6000_sched_groups
)
23649 enum attr_type type
= get_attr_type (insn
);
23650 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
23651 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
23652 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
23653 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
23654 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
23655 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
23656 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
23657 || type
== TYPE_INSERT_WORD
)
23664 /* The function returns true if INSN can be issued only from
23665 the branch slot. */
23668 is_branch_slot_insn (rtx insn
)
23670 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23671 || GET_CODE (PATTERN (insn
)) == USE
23672 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23675 if (rs6000_sched_groups
)
23677 enum attr_type type
= get_attr_type (insn
);
23678 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
23686 /* The function returns true if out_inst sets a value that is
23687 used in the address generation computation of in_insn */
23689 set_to_load_agen (rtx out_insn
, rtx in_insn
)
23691 rtx out_set
, in_set
;
23693 /* For performance reasons, only handle the simple case where
23694 both loads are a single_set. */
23695 out_set
= single_set (out_insn
);
23698 in_set
= single_set (in_insn
);
23700 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
23706 /* The function returns true if the target storage location of
23707 out_insn is adjacent to the target storage location of in_insn */
23708 /* Return 1 if memory locations are adjacent. */
23711 adjacent_mem_locations (rtx insn1
, rtx insn2
)
23714 rtx a
= get_store_dest (PATTERN (insn1
));
23715 rtx b
= get_store_dest (PATTERN (insn2
));
23717 if ((GET_CODE (XEXP (a
, 0)) == REG
23718 || (GET_CODE (XEXP (a
, 0)) == PLUS
23719 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
23720 && (GET_CODE (XEXP (b
, 0)) == REG
23721 || (GET_CODE (XEXP (b
, 0)) == PLUS
23722 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
23724 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
23727 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
23729 reg0
= XEXP (XEXP (a
, 0), 0);
23730 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
23733 reg0
= XEXP (a
, 0);
23735 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
23737 reg1
= XEXP (XEXP (b
, 0), 0);
23738 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
23741 reg1
= XEXP (b
, 0);
23743 val_diff
= val1
- val0
;
23745 return ((REGNO (reg0
) == REGNO (reg1
))
23746 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
23747 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
23753 /* A C statement (sans semicolon) to update the integer scheduling
23754 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23755 INSN earlier, reduce the priority to execute INSN later. Do not
23756 define this macro if you do not need to adjust the scheduling
23757 priorities of insns. */
23760 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
23762 /* On machines (like the 750) which have asymmetric integer units,
23763 where one integer unit can do multiply and divides and the other
23764 can't, reduce the priority of multiply/divide so it is scheduled
23765 before other integer operations. */
23768 if (! INSN_P (insn
))
23771 if (GET_CODE (PATTERN (insn
)) == USE
)
23774 switch (rs6000_cpu_attr
) {
23776 switch (get_attr_type (insn
))
23783 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
23784 priority
, priority
);
23785 if (priority
>= 0 && priority
< 0x01000000)
23792 if (insn_must_be_first_in_group (insn
)
23793 && reload_completed
23794 && current_sched_info
->sched_max_insns_priority
23795 && rs6000_sched_restricted_insns_priority
)
23798 /* Prioritize insns that can be dispatched only in the first
23800 if (rs6000_sched_restricted_insns_priority
== 1)
23801 /* Attach highest priority to insn. This means that in
23802 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23803 precede 'priority' (critical path) considerations. */
23804 return current_sched_info
->sched_max_insns_priority
;
23805 else if (rs6000_sched_restricted_insns_priority
== 2)
23806 /* Increase priority of insn by a minimal amount. This means that in
23807 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23808 considerations precede dispatch-slot restriction considerations. */
23809 return (priority
+ 1);
23812 if (rs6000_cpu
== PROCESSOR_POWER6
23813 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
23814 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
23815 /* Attach highest priority to insn if the scheduler has just issued two
23816 stores and this instruction is a load, or two loads and this instruction
23817 is a store. Power6 wants loads and stores scheduled alternately
23819 return current_sched_info
->sched_max_insns_priority
;
23824 /* Return true if the instruction is nonpipelined on the Cell. */
23826 is_nonpipeline_insn (rtx insn
)
23828 enum attr_type type
;
23829 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23830 || GET_CODE (PATTERN (insn
)) == USE
23831 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23834 type
= get_attr_type (insn
);
23835 if (type
== TYPE_IMUL
23836 || type
== TYPE_IMUL2
23837 || type
== TYPE_IMUL3
23838 || type
== TYPE_LMUL
23839 || type
== TYPE_IDIV
23840 || type
== TYPE_LDIV
23841 || type
== TYPE_SDIV
23842 || type
== TYPE_DDIV
23843 || type
== TYPE_SSQRT
23844 || type
== TYPE_DSQRT
23845 || type
== TYPE_MFCR
23846 || type
== TYPE_MFCRF
23847 || type
== TYPE_MFJMPR
)
23855 /* Return how many instructions the machine can issue per cycle. */
23858 rs6000_issue_rate (void)
23860 /* Unless scheduling for register pressure, use issue rate of 1 for
23861 first scheduling pass to decrease degradation. */
23862 if (!reload_completed
&& !flag_sched_pressure
)
23865 switch (rs6000_cpu_attr
) {
23866 case CPU_RIOS1
: /* ? */
23868 case CPU_PPC601
: /* ? */
23877 case CPU_PPCE300C2
:
23878 case CPU_PPCE300C3
:
23879 case CPU_PPCE500MC
:
23880 case CPU_PPCE500MC64
:
23900 /* Return how many instructions to look ahead for better insn
23904 rs6000_use_sched_lookahead (void)
23906 if (rs6000_cpu_attr
== CPU_PPC8540
)
23908 if (rs6000_cpu_attr
== CPU_CELL
)
23909 return (reload_completed
? 8 : 0);
23913 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23915 rs6000_use_sched_lookahead_guard (rtx insn
)
23917 if (rs6000_cpu_attr
!= CPU_CELL
)
23920 if (insn
== NULL_RTX
|| !INSN_P (insn
))
23923 if (!reload_completed
23924 || is_nonpipeline_insn (insn
)
23925 || is_microcoded_insn (insn
))
23931 /* Determine is PAT refers to memory. */
23934 is_mem_ref (rtx pat
)
23940 /* stack_tie does not produce any real memory traffic. */
23941 if (GET_CODE (pat
) == UNSPEC
23942 && XINT (pat
, 1) == UNSPEC_TIE
)
23945 if (GET_CODE (pat
) == MEM
)
23948 /* Recursively process the pattern. */
23949 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
23951 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
23954 ret
|= is_mem_ref (XEXP (pat
, i
));
23955 else if (fmt
[i
] == 'E')
23956 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
23957 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
23963 /* Determine if PAT is a PATTERN of a load insn. */
23966 is_load_insn1 (rtx pat
)
23968 if (!pat
|| pat
== NULL_RTX
)
23971 if (GET_CODE (pat
) == SET
)
23972 return is_mem_ref (SET_SRC (pat
));
23974 if (GET_CODE (pat
) == PARALLEL
)
23978 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23979 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
23986 /* Determine if INSN loads from memory. */
23989 is_load_insn (rtx insn
)
23991 if (!insn
|| !INSN_P (insn
))
23994 if (GET_CODE (insn
) == CALL_INSN
)
23997 return is_load_insn1 (PATTERN (insn
));
24000 /* Determine if PAT is a PATTERN of a store insn. */
24003 is_store_insn1 (rtx pat
)
24005 if (!pat
|| pat
== NULL_RTX
)
24008 if (GET_CODE (pat
) == SET
)
24009 return is_mem_ref (SET_DEST (pat
));
24011 if (GET_CODE (pat
) == PARALLEL
)
24015 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
24016 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
24023 /* Determine if INSN stores to memory. */
24026 is_store_insn (rtx insn
)
24028 if (!insn
|| !INSN_P (insn
))
24031 return is_store_insn1 (PATTERN (insn
));
24034 /* Return the dest of a store insn. */
24037 get_store_dest (rtx pat
)
24039 gcc_assert (is_store_insn1 (pat
));
24041 if (GET_CODE (pat
) == SET
)
24042 return SET_DEST (pat
);
24043 else if (GET_CODE (pat
) == PARALLEL
)
24047 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
24049 rtx inner_pat
= XVECEXP (pat
, 0, i
);
24050 if (GET_CODE (inner_pat
) == SET
24051 && is_mem_ref (SET_DEST (inner_pat
)))
24055 /* We shouldn't get here, because we should have either a simple
24056 store insn or a store with update which are covered above. */
24060 /* Returns whether the dependence between INSN and NEXT is considered
24061 costly by the given target. */
24064 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
24069 /* If the flag is not enabled - no dependence is considered costly;
24070 allow all dependent insns in the same group.
24071 This is the most aggressive option. */
24072 if (rs6000_sched_costly_dep
== no_dep_costly
)
24075 /* If the flag is set to 1 - a dependence is always considered costly;
24076 do not allow dependent instructions in the same group.
24077 This is the most conservative option. */
24078 if (rs6000_sched_costly_dep
== all_deps_costly
)
24081 insn
= DEP_PRO (dep
);
24082 next
= DEP_CON (dep
);
24084 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
24085 && is_load_insn (next
)
24086 && is_store_insn (insn
))
24087 /* Prevent load after store in the same group. */
24090 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
24091 && is_load_insn (next
)
24092 && is_store_insn (insn
)
24093 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
24094 /* Prevent load after store in the same group if it is a true
24098 /* The flag is set to X; dependences with latency >= X are considered costly,
24099 and will not be scheduled in the same group. */
24100 if (rs6000_sched_costly_dep
<= max_dep_latency
24101 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
24107 /* Return the next insn after INSN that is found before TAIL is reached,
24108 skipping any "non-active" insns - insns that will not actually occupy
24109 an issue slot. Return NULL_RTX if such an insn is not found. */
24112 get_next_active_insn (rtx insn
, rtx tail
)
24114 if (insn
== NULL_RTX
|| insn
== tail
)
24119 insn
= NEXT_INSN (insn
);
24120 if (insn
== NULL_RTX
|| insn
== tail
)
24125 || (NONJUMP_INSN_P (insn
)
24126 && GET_CODE (PATTERN (insn
)) != USE
24127 && GET_CODE (PATTERN (insn
)) != CLOBBER
24128 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
24134 /* We are about to begin issuing insns for this clock cycle. */
24137 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
24138 rtx
*ready ATTRIBUTE_UNUSED
,
24139 int *pn_ready ATTRIBUTE_UNUSED
,
24140 int clock_var ATTRIBUTE_UNUSED
)
24142 int n_ready
= *pn_ready
;
24145 fprintf (dump
, "// rs6000_sched_reorder :\n");
24147 /* Reorder the ready list, if the second to last ready insn
24148 is a nonepipeline insn. */
24149 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
24151 if (is_nonpipeline_insn (ready
[n_ready
- 1])
24152 && (recog_memoized (ready
[n_ready
- 2]) > 0))
24153 /* Simply swap first two insns. */
24155 rtx tmp
= ready
[n_ready
- 1];
24156 ready
[n_ready
- 1] = ready
[n_ready
- 2];
24157 ready
[n_ready
- 2] = tmp
;
24161 if (rs6000_cpu
== PROCESSOR_POWER6
)
24162 load_store_pendulum
= 0;
24164 return rs6000_issue_rate ();
24167 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24170 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
24171 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
24174 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
24176 /* For Power6, we need to handle some special cases to try and keep the
24177 store queue from overflowing and triggering expensive flushes.
24179 This code monitors how load and store instructions are being issued
24180 and skews the ready list one way or the other to increase the likelihood
24181 that a desired instruction is issued at the proper time.
24183 A couple of things are done. First, we maintain a "load_store_pendulum"
24184 to track the current state of load/store issue.
24186 - If the pendulum is at zero, then no loads or stores have been
24187 issued in the current cycle so we do nothing.
24189 - If the pendulum is 1, then a single load has been issued in this
24190 cycle and we attempt to locate another load in the ready list to
24193 - If the pendulum is -2, then two stores have already been
24194 issued in this cycle, so we increase the priority of the first load
24195 in the ready list to increase it's likelihood of being chosen first
24198 - If the pendulum is -1, then a single store has been issued in this
24199 cycle and we attempt to locate another store in the ready list to
24200 issue with it, preferring a store to an adjacent memory location to
24201 facilitate store pairing in the store queue.
24203 - If the pendulum is 2, then two loads have already been
24204 issued in this cycle, so we increase the priority of the first store
24205 in the ready list to increase it's likelihood of being chosen first
24208 - If the pendulum < -2 or > 2, then do nothing.
24210 Note: This code covers the most common scenarios. There exist non
24211 load/store instructions which make use of the LSU and which
24212 would need to be accounted for to strictly model the behavior
24213 of the machine. Those instructions are currently unaccounted
24214 for to help minimize compile time overhead of this code.
24216 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
24222 if (is_store_insn (last_scheduled_insn
))
24223 /* Issuing a store, swing the load_store_pendulum to the left */
24224 load_store_pendulum
--;
24225 else if (is_load_insn (last_scheduled_insn
))
24226 /* Issuing a load, swing the load_store_pendulum to the right */
24227 load_store_pendulum
++;
24229 return cached_can_issue_more
;
24231 /* If the pendulum is balanced, or there is only one instruction on
24232 the ready list, then all is well, so return. */
24233 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
24234 return cached_can_issue_more
;
24236 if (load_store_pendulum
== 1)
24238 /* A load has been issued in this cycle. Scan the ready list
24239 for another load to issue with it */
24244 if (is_load_insn (ready
[pos
]))
24246 /* Found a load. Move it to the head of the ready list,
24247 and adjust it's priority so that it is more likely to
24250 for (i
=pos
; i
<*pn_ready
-1; i
++)
24251 ready
[i
] = ready
[i
+ 1];
24252 ready
[*pn_ready
-1] = tmp
;
24254 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24255 INSN_PRIORITY (tmp
)++;
24261 else if (load_store_pendulum
== -2)
24263 /* Two stores have been issued in this cycle. Increase the
24264 priority of the first load in the ready list to favor it for
24265 issuing in the next cycle. */
24270 if (is_load_insn (ready
[pos
])
24272 && INSN_PRIORITY_KNOWN (ready
[pos
]))
24274 INSN_PRIORITY (ready
[pos
])++;
24276 /* Adjust the pendulum to account for the fact that a load
24277 was found and increased in priority. This is to prevent
24278 increasing the priority of multiple loads */
24279 load_store_pendulum
--;
24286 else if (load_store_pendulum
== -1)
24288 /* A store has been issued in this cycle. Scan the ready list for
24289 another store to issue with it, preferring a store to an adjacent
24291 int first_store_pos
= -1;
24297 if (is_store_insn (ready
[pos
]))
24299 /* Maintain the index of the first store found on the
24301 if (first_store_pos
== -1)
24302 first_store_pos
= pos
;
24304 if (is_store_insn (last_scheduled_insn
)
24305 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
24307 /* Found an adjacent store. Move it to the head of the
24308 ready list, and adjust it's priority so that it is
24309 more likely to stay there */
24311 for (i
=pos
; i
<*pn_ready
-1; i
++)
24312 ready
[i
] = ready
[i
+ 1];
24313 ready
[*pn_ready
-1] = tmp
;
24315 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24316 INSN_PRIORITY (tmp
)++;
24318 first_store_pos
= -1;
24326 if (first_store_pos
>= 0)
24328 /* An adjacent store wasn't found, but a non-adjacent store was,
24329 so move the non-adjacent store to the front of the ready
24330 list, and adjust its priority so that it is more likely to
24332 tmp
= ready
[first_store_pos
];
24333 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
24334 ready
[i
] = ready
[i
+ 1];
24335 ready
[*pn_ready
-1] = tmp
;
24336 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
24337 INSN_PRIORITY (tmp
)++;
24340 else if (load_store_pendulum
== 2)
24342 /* Two loads have been issued in this cycle. Increase the priority
24343 of the first store in the ready list to favor it for issuing in
24349 if (is_store_insn (ready
[pos
])
24351 && INSN_PRIORITY_KNOWN (ready
[pos
]))
24353 INSN_PRIORITY (ready
[pos
])++;
24355 /* Adjust the pendulum to account for the fact that a store
24356 was found and increased in priority. This is to prevent
24357 increasing the priority of multiple stores */
24358 load_store_pendulum
++;
24367 return cached_can_issue_more
;
24370 /* Return whether the presence of INSN causes a dispatch group termination
24371 of group WHICH_GROUP.
24373 If WHICH_GROUP == current_group, this function will return true if INSN
24374 causes the termination of the current group (i.e, the dispatch group to
24375 which INSN belongs). This means that INSN will be the last insn in the
24376 group it belongs to.
24378 If WHICH_GROUP == previous_group, this function will return true if INSN
24379 causes the termination of the previous group (i.e, the dispatch group that
24380 precedes the group to which INSN belongs). This means that INSN will be
24381 the first insn in the group it belongs to). */
24384 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
24391 first
= insn_must_be_first_in_group (insn
);
24392 last
= insn_must_be_last_in_group (insn
);
24397 if (which_group
== current_group
)
24399 else if (which_group
== previous_group
)
24407 insn_must_be_first_in_group (rtx insn
)
24409 enum attr_type type
;
24412 || GET_CODE (insn
) == NOTE
24413 || DEBUG_INSN_P (insn
)
24414 || GET_CODE (PATTERN (insn
)) == USE
24415 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
24418 switch (rs6000_cpu
)
24420 case PROCESSOR_POWER5
:
24421 if (is_cracked_insn (insn
))
24423 case PROCESSOR_POWER4
:
24424 if (is_microcoded_insn (insn
))
24427 if (!rs6000_sched_groups
)
24430 type
= get_attr_type (insn
);
24437 case TYPE_DELAYED_CR
:
24438 case TYPE_CR_LOGICAL
:
24452 case PROCESSOR_POWER6
:
24453 type
= get_attr_type (insn
);
24457 case TYPE_INSERT_DWORD
:
24461 case TYPE_VAR_SHIFT_ROTATE
:
24468 case TYPE_INSERT_WORD
:
24469 case TYPE_DELAYED_COMPARE
:
24470 case TYPE_IMUL_COMPARE
:
24471 case TYPE_LMUL_COMPARE
:
24472 case TYPE_FPCOMPARE
:
24483 case TYPE_LOAD_EXT_UX
:
24485 case TYPE_STORE_UX
:
24486 case TYPE_FPLOAD_U
:
24487 case TYPE_FPLOAD_UX
:
24488 case TYPE_FPSTORE_U
:
24489 case TYPE_FPSTORE_UX
:
24495 case PROCESSOR_POWER7
:
24496 type
= get_attr_type (insn
);
24500 case TYPE_CR_LOGICAL
:
24507 case TYPE_DELAYED_COMPARE
:
24508 case TYPE_VAR_DELAYED_COMPARE
:
24514 case TYPE_LOAD_EXT
:
24515 case TYPE_LOAD_EXT_U
:
24516 case TYPE_LOAD_EXT_UX
:
24518 case TYPE_STORE_UX
:
24519 case TYPE_FPLOAD_U
:
24520 case TYPE_FPLOAD_UX
:
24521 case TYPE_FPSTORE_U
:
24522 case TYPE_FPSTORE_UX
:
24538 insn_must_be_last_in_group (rtx insn
)
24540 enum attr_type type
;
24543 || GET_CODE (insn
) == NOTE
24544 || DEBUG_INSN_P (insn
)
24545 || GET_CODE (PATTERN (insn
)) == USE
24546 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
24549 switch (rs6000_cpu
) {
24550 case PROCESSOR_POWER4
:
24551 case PROCESSOR_POWER5
:
24552 if (is_microcoded_insn (insn
))
24555 if (is_branch_slot_insn (insn
))
24559 case PROCESSOR_POWER6
:
24560 type
= get_attr_type (insn
);
24567 case TYPE_VAR_SHIFT_ROTATE
:
24574 case TYPE_DELAYED_COMPARE
:
24575 case TYPE_IMUL_COMPARE
:
24576 case TYPE_LMUL_COMPARE
:
24577 case TYPE_FPCOMPARE
:
24591 case PROCESSOR_POWER7
:
24592 type
= get_attr_type (insn
);
24600 case TYPE_LOAD_EXT_U
:
24601 case TYPE_LOAD_EXT_UX
:
24602 case TYPE_STORE_UX
:
24615 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24616 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24619 is_costly_group (rtx
*group_insns
, rtx next_insn
)
24622 int issue_rate
= rs6000_issue_rate ();
24624 for (i
= 0; i
< issue_rate
; i
++)
24626 sd_iterator_def sd_it
;
24628 rtx insn
= group_insns
[i
];
24633 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
24635 rtx next
= DEP_CON (dep
);
24637 if (next
== next_insn
24638 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
24646 /* Utility of the function redefine_groups.
24647 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24648 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24649 to keep it "far" (in a separate group) from GROUP_INSNS, following
24650 one of the following schemes, depending on the value of the flag
24651 -minsert_sched_nops = X:
24652 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24653 in order to force NEXT_INSN into a separate group.
24654 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24655 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24656 insertion (has a group just ended, how many vacant issue slots remain in the
24657 last group, and how many dispatch groups were encountered so far). */
24660 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
24661 rtx next_insn
, bool *group_end
, int can_issue_more
,
24666 int issue_rate
= rs6000_issue_rate ();
24667 bool end
= *group_end
;
24670 if (next_insn
== NULL_RTX
|| DEBUG_INSN_P (next_insn
))
24671 return can_issue_more
;
24673 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
24674 return can_issue_more
;
24676 force
= is_costly_group (group_insns
, next_insn
);
24678 return can_issue_more
;
24680 if (sched_verbose
> 6)
24681 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
24682 *group_count
,can_issue_more
);
24684 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
24687 can_issue_more
= 0;
24689 /* Since only a branch can be issued in the last issue_slot, it is
24690 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24691 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24692 in this case the last nop will start a new group and the branch
24693 will be forced to the new group. */
24694 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
24697 while (can_issue_more
> 0)
24700 emit_insn_before (nop
, next_insn
);
24708 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
24710 int n_nops
= rs6000_sched_insert_nops
;
24712 /* Nops can't be issued from the branch slot, so the effective
24713 issue_rate for nops is 'issue_rate - 1'. */
24714 if (can_issue_more
== 0)
24715 can_issue_more
= issue_rate
;
24717 if (can_issue_more
== 0)
24719 can_issue_more
= issue_rate
- 1;
24722 for (i
= 0; i
< issue_rate
; i
++)
24724 group_insns
[i
] = 0;
24731 emit_insn_before (nop
, next_insn
);
24732 if (can_issue_more
== issue_rate
- 1) /* new group begins */
24735 if (can_issue_more
== 0)
24737 can_issue_more
= issue_rate
- 1;
24740 for (i
= 0; i
< issue_rate
; i
++)
24742 group_insns
[i
] = 0;
24748 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24751 /* Is next_insn going to start a new group? */
24754 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24755 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24756 || (can_issue_more
< issue_rate
&&
24757 insn_terminates_group_p (next_insn
, previous_group
)));
24758 if (*group_end
&& end
)
24761 if (sched_verbose
> 6)
24762 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
24763 *group_count
, can_issue_more
);
24764 return can_issue_more
;
24767 return can_issue_more
;
24770 /* This function tries to synch the dispatch groups that the compiler "sees"
24771 with the dispatch groups that the processor dispatcher is expected to
24772 form in practice. It tries to achieve this synchronization by forcing the
24773 estimated processor grouping on the compiler (as opposed to the function
24774 'pad_goups' which tries to force the scheduler's grouping on the processor).
24776 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24777 examines the (estimated) dispatch groups that will be formed by the processor
24778 dispatcher. It marks these group boundaries to reflect the estimated
24779 processor grouping, overriding the grouping that the scheduler had marked.
24780 Depending on the value of the flag '-minsert-sched-nops' this function can
24781 force certain insns into separate groups or force a certain distance between
24782 them by inserting nops, for example, if there exists a "costly dependence"
24785 The function estimates the group boundaries that the processor will form as
24786 follows: It keeps track of how many vacant issue slots are available after
24787 each insn. A subsequent insn will start a new group if one of the following
24789 - no more vacant issue slots remain in the current dispatch group.
24790 - only the last issue slot, which is the branch slot, is vacant, but the next
24791 insn is not a branch.
24792 - only the last 2 or less issue slots, including the branch slot, are vacant,
24793 which means that a cracked insn (which occupies two issue slots) can't be
24794 issued in this group.
24795 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24796 start a new group. */
24799 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24801 rtx insn
, next_insn
;
24803 int can_issue_more
;
24806 int group_count
= 0;
24810 issue_rate
= rs6000_issue_rate ();
24811 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
24812 for (i
= 0; i
< issue_rate
; i
++)
24814 group_insns
[i
] = 0;
24816 can_issue_more
= issue_rate
;
24818 insn
= get_next_active_insn (prev_head_insn
, tail
);
24821 while (insn
!= NULL_RTX
)
24823 slot
= (issue_rate
- can_issue_more
);
24824 group_insns
[slot
] = insn
;
24826 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24827 if (insn_terminates_group_p (insn
, current_group
))
24828 can_issue_more
= 0;
24830 next_insn
= get_next_active_insn (insn
, tail
);
24831 if (next_insn
== NULL_RTX
)
24832 return group_count
+ 1;
24834 /* Is next_insn going to start a new group? */
24836 = (can_issue_more
== 0
24837 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24838 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24839 || (can_issue_more
< issue_rate
&&
24840 insn_terminates_group_p (next_insn
, previous_group
)));
24842 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
24843 next_insn
, &group_end
, can_issue_more
,
24849 can_issue_more
= 0;
24850 for (i
= 0; i
< issue_rate
; i
++)
24852 group_insns
[i
] = 0;
24856 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
24857 PUT_MODE (next_insn
, VOIDmode
);
24858 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
24859 PUT_MODE (next_insn
, TImode
);
24862 if (can_issue_more
== 0)
24863 can_issue_more
= issue_rate
;
24866 return group_count
;
24869 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24870 dispatch group boundaries that the scheduler had marked. Pad with nops
24871 any dispatch groups which have vacant issue slots, in order to force the
24872 scheduler's grouping on the processor dispatcher. The function
24873 returns the number of dispatch groups found. */
24876 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24878 rtx insn
, next_insn
;
24881 int can_issue_more
;
24883 int group_count
= 0;
24885 /* Initialize issue_rate. */
24886 issue_rate
= rs6000_issue_rate ();
24887 can_issue_more
= issue_rate
;
24889 insn
= get_next_active_insn (prev_head_insn
, tail
);
24890 next_insn
= get_next_active_insn (insn
, tail
);
24892 while (insn
!= NULL_RTX
)
24895 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24897 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
24899 if (next_insn
== NULL_RTX
)
24904 /* If the scheduler had marked group termination at this location
24905 (between insn and next_insn), and neither insn nor next_insn will
24906 force group termination, pad the group with nops to force group
24909 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24910 && !insn_terminates_group_p (insn
, current_group
)
24911 && !insn_terminates_group_p (next_insn
, previous_group
))
24913 if (!is_branch_slot_insn (next_insn
))
24916 while (can_issue_more
)
24919 emit_insn_before (nop
, next_insn
);
24924 can_issue_more
= issue_rate
;
24929 next_insn
= get_next_active_insn (insn
, tail
);
24932 return group_count
;
24935 /* We're beginning a new block. Initialize data structures as necessary. */
24938 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
24939 int sched_verbose ATTRIBUTE_UNUSED
,
24940 int max_ready ATTRIBUTE_UNUSED
)
24942 last_scheduled_insn
= NULL_RTX
;
24943 load_store_pendulum
= 0;
24946 /* The following function is called at the end of scheduling BB.
24947 After reload, it inserts nops at insn group bundling. */
24950 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
24955 fprintf (dump
, "=== Finishing schedule.\n");
24957 if (reload_completed
&& rs6000_sched_groups
)
24959 /* Do not run sched_finish hook when selective scheduling enabled. */
24960 if (sel_sched_p ())
24963 if (rs6000_sched_insert_nops
== sched_finish_none
)
24966 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24967 n_groups
= pad_groups (dump
, sched_verbose
,
24968 current_sched_info
->prev_head
,
24969 current_sched_info
->next_tail
);
24971 n_groups
= redefine_groups (dump
, sched_verbose
,
24972 current_sched_info
->prev_head
,
24973 current_sched_info
->next_tail
);
24975 if (sched_verbose
>= 6)
24977 fprintf (dump
, "ngroups = %d\n", n_groups
);
24978 print_rtl (dump
, current_sched_info
->prev_head
);
24979 fprintf (dump
, "Done finish_sched\n");
24984 struct _rs6000_sched_context
24986 short cached_can_issue_more
;
24987 rtx last_scheduled_insn
;
24988 int load_store_pendulum
;
24991 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
24992 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
24994 /* Allocate store for new scheduling context. */
24996 rs6000_alloc_sched_context (void)
24998 return xmalloc (sizeof (rs6000_sched_context_def
));
25001 /* If CLEAN_P is true then initializes _SC with clean data,
25002 and from the global context otherwise. */
25004 rs6000_init_sched_context (void *_sc
, bool clean_p
)
25006 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
25010 sc
->cached_can_issue_more
= 0;
25011 sc
->last_scheduled_insn
= NULL_RTX
;
25012 sc
->load_store_pendulum
= 0;
25016 sc
->cached_can_issue_more
= cached_can_issue_more
;
25017 sc
->last_scheduled_insn
= last_scheduled_insn
;
25018 sc
->load_store_pendulum
= load_store_pendulum
;
25022 /* Sets the global scheduling context to the one pointed to by _SC. */
25024 rs6000_set_sched_context (void *_sc
)
25026 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
25028 gcc_assert (sc
!= NULL
);
25030 cached_can_issue_more
= sc
->cached_can_issue_more
;
25031 last_scheduled_insn
= sc
->last_scheduled_insn
;
25032 load_store_pendulum
= sc
->load_store_pendulum
;
25037 rs6000_free_sched_context (void *_sc
)
25039 gcc_assert (_sc
!= NULL
);
25045 /* Length in units of the trampoline for entering a nested function. */
25048 rs6000_trampoline_size (void)
25052 switch (DEFAULT_ABI
)
25055 gcc_unreachable ();
25058 ret
= (TARGET_32BIT
) ? 12 : 24;
25063 ret
= (TARGET_32BIT
) ? 40 : 48;
25070 /* Emit RTL insns to initialize the variable parts of a trampoline.
25071 FNADDR is an RTX for the address of the function's pure code.
25072 CXT is an RTX for the static chain value for the function. */
25075 rs6000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
25077 int regsize
= (TARGET_32BIT
) ? 4 : 8;
25078 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
25079 rtx ctx_reg
= force_reg (Pmode
, cxt
);
25080 rtx addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
25082 switch (DEFAULT_ABI
)
25085 gcc_unreachable ();
25087 /* Under AIX, just build the 3 word function descriptor */
25090 rtx fnmem
= gen_const_mem (Pmode
, force_reg (Pmode
, fnaddr
));
25091 rtx fn_reg
= gen_reg_rtx (Pmode
);
25092 rtx toc_reg
= gen_reg_rtx (Pmode
);
25094 /* Macro to shorten the code expansions below. */
25095 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25097 m_tramp
= replace_equiv_address (m_tramp
, addr
);
25099 emit_move_insn (fn_reg
, MEM_PLUS (fnmem
, 0));
25100 emit_move_insn (toc_reg
, MEM_PLUS (fnmem
, regsize
));
25101 emit_move_insn (MEM_PLUS (m_tramp
, 0), fn_reg
);
25102 emit_move_insn (MEM_PLUS (m_tramp
, regsize
), toc_reg
);
25103 emit_move_insn (MEM_PLUS (m_tramp
, 2*regsize
), ctx_reg
);
25109 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25112 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
25113 LCT_NORMAL
, VOIDmode
, 4,
25115 GEN_INT (rs6000_trampoline_size ()), SImode
,
25123 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25124 identifier as an argument, so the front end shouldn't look it up. */
25127 rs6000_attribute_takes_identifier_p (const_tree attr_id
)
25129 return is_attribute_p ("altivec", attr_id
);
25132 /* Handle the "altivec" attribute. The attribute may have
25133 arguments as follows:
25135 __attribute__((altivec(vector__)))
25136 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25137 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25139 and may appear more than once (e.g., 'vector bool char') in a
25140 given declaration. */
25143 rs6000_handle_altivec_attribute (tree
*node
,
25144 tree name ATTRIBUTE_UNUSED
,
25146 int flags ATTRIBUTE_UNUSED
,
25147 bool *no_add_attrs
)
25149 tree type
= *node
, result
= NULL_TREE
;
25150 enum machine_mode mode
;
25153 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
25154 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
25155 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
25158 while (POINTER_TYPE_P (type
)
25159 || TREE_CODE (type
) == FUNCTION_TYPE
25160 || TREE_CODE (type
) == METHOD_TYPE
25161 || TREE_CODE (type
) == ARRAY_TYPE
)
25162 type
= TREE_TYPE (type
);
25164 mode
= TYPE_MODE (type
);
25166 /* Check for invalid AltiVec type qualifiers. */
25167 if (type
== long_double_type_node
)
25168 error ("use of %<long double%> in AltiVec types is invalid");
25169 else if (type
== boolean_type_node
)
25170 error ("use of boolean types in AltiVec types is invalid");
25171 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
25172 error ("use of %<complex%> in AltiVec types is invalid");
25173 else if (DECIMAL_FLOAT_MODE_P (mode
))
25174 error ("use of decimal floating point types in AltiVec types is invalid");
25175 else if (!TARGET_VSX
)
25177 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
25180 error ("use of %<long%> in AltiVec types is invalid for "
25181 "64-bit code without -mvsx");
25182 else if (rs6000_warn_altivec_long
)
25183 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25186 else if (type
== long_long_unsigned_type_node
25187 || type
== long_long_integer_type_node
)
25188 error ("use of %<long long%> in AltiVec types is invalid without "
25190 else if (type
== double_type_node
)
25191 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25194 switch (altivec_type
)
25197 unsigned_p
= TYPE_UNSIGNED (type
);
25201 result
= (unsigned_p
? unsigned_V2DI_type_node
: V2DI_type_node
);
25204 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
25207 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
25210 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
25212 case SFmode
: result
= V4SF_type_node
; break;
25213 case DFmode
: result
= V2DF_type_node
; break;
25214 /* If the user says 'vector int bool', we may be handed the 'bool'
25215 attribute _before_ the 'vector' attribute, and so select the
25216 proper type in the 'b' case below. */
25217 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
25218 case V2DImode
: case V2DFmode
:
25226 case DImode
: case V2DImode
: result
= bool_V2DI_type_node
; break;
25227 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
25228 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
25229 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
25236 case V8HImode
: result
= pixel_V8HI_type_node
;
25242 /* Propagate qualifiers attached to the element type
25243 onto the vector type. */
25244 if (result
&& result
!= type
&& TYPE_QUALS (type
))
25245 result
= build_qualified_type (result
, TYPE_QUALS (type
));
25247 *no_add_attrs
= true; /* No need to hang on to the attribute. */
25250 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
25255 /* AltiVec defines four built-in scalar types that serve as vector
25256 elements; we must teach the compiler how to mangle them. */
25258 static const char *
25259 rs6000_mangle_type (const_tree type
)
25261 type
= TYPE_MAIN_VARIANT (type
);
25263 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
25264 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
25267 if (type
== bool_char_type_node
) return "U6__boolc";
25268 if (type
== bool_short_type_node
) return "U6__bools";
25269 if (type
== pixel_type_node
) return "u7__pixel";
25270 if (type
== bool_int_type_node
) return "U6__booli";
25271 if (type
== bool_long_type_node
) return "U6__booll";
25273 /* Mangle IBM extended float long double as `g' (__float128) on
25274 powerpc*-linux where long-double-64 previously was the default. */
25275 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
25277 && TARGET_LONG_DOUBLE_128
25278 && !TARGET_IEEEQUAD
)
25281 /* For all other types, use normal C++ mangling. */
25285 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25286 struct attribute_spec.handler. */
25289 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
25290 tree args ATTRIBUTE_UNUSED
,
25291 int flags ATTRIBUTE_UNUSED
,
25292 bool *no_add_attrs
)
25294 if (TREE_CODE (*node
) != FUNCTION_TYPE
25295 && TREE_CODE (*node
) != FIELD_DECL
25296 && TREE_CODE (*node
) != TYPE_DECL
)
25298 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
25300 *no_add_attrs
= true;
25306 /* Set longcall attributes on all functions declared when
25307 rs6000_default_long_calls is true. */
25309 rs6000_set_default_type_attributes (tree type
)
25311 if (rs6000_default_long_calls
25312 && (TREE_CODE (type
) == FUNCTION_TYPE
25313 || TREE_CODE (type
) == METHOD_TYPE
))
25314 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
25316 TYPE_ATTRIBUTES (type
));
25319 darwin_set_default_type_attributes (type
);
25323 /* Return a reference suitable for calling a function with the
25324 longcall attribute. */
25327 rs6000_longcall_ref (rtx call_ref
)
25329 const char *call_name
;
25332 if (GET_CODE (call_ref
) != SYMBOL_REF
)
25335 /* System V adds '.' to the internal name, so skip them. */
25336 call_name
= XSTR (call_ref
, 0);
25337 if (*call_name
== '.')
25339 while (*call_name
== '.')
25342 node
= get_identifier (call_name
);
25343 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
25346 return force_reg (Pmode
, call_ref
);
25349 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25350 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25353 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25354 struct attribute_spec.handler. */
25356 rs6000_handle_struct_attribute (tree
*node
, tree name
,
25357 tree args ATTRIBUTE_UNUSED
,
25358 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
25361 if (DECL_P (*node
))
25363 if (TREE_CODE (*node
) == TYPE_DECL
)
25364 type
= &TREE_TYPE (*node
);
25369 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
25370 || TREE_CODE (*type
) == UNION_TYPE
)))
25372 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
25373 *no_add_attrs
= true;
25376 else if ((is_attribute_p ("ms_struct", name
)
25377 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
25378 || ((is_attribute_p ("gcc_struct", name
)
25379 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
25381 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
25383 *no_add_attrs
= true;
25390 rs6000_ms_bitfield_layout_p (const_tree record_type
)
25392 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
25393 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
25394 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
25397 #ifdef USING_ELFOS_H
25399 /* A get_unnamed_section callback, used for switching to toc_section. */
25402 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
25404 if (DEFAULT_ABI
== ABI_AIX
25405 && TARGET_MINIMAL_TOC
25406 && !TARGET_RELOCATABLE
)
25408 if (!toc_initialized
)
25410 toc_initialized
= 1;
25411 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
25412 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
25413 fprintf (asm_out_file
, "\t.tc ");
25414 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
25415 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25416 fprintf (asm_out_file
, "\n");
25418 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25419 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25420 fprintf (asm_out_file
, " = .+32768\n");
25423 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25425 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
25426 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
25429 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25430 if (!toc_initialized
)
25432 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
25433 fprintf (asm_out_file
, " = .+32768\n");
25434 toc_initialized
= 1;
25439 /* Implement TARGET_ASM_INIT_SECTIONS. */
25442 rs6000_elf_asm_init_sections (void)
25445 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
25448 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
25449 SDATA2_SECTION_ASM_OP
);
25452 /* Implement TARGET_SELECT_RTX_SECTION. */
25455 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
25456 unsigned HOST_WIDE_INT align
)
25458 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
25459 return toc_section
;
25461 return default_elf_select_rtx_section (mode
, x
, align
);
25464 /* For a SYMBOL_REF, set generic flags and then perform some
25465 target-specific processing.
25467 When the AIX ABI is requested on a non-AIX system, replace the
25468 function name with the real name (with a leading .) rather than the
25469 function descriptor name. This saves a lot of overriding code to
25470 read the prefixes. */
25473 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
25475 default_encode_section_info (decl
, rtl
, first
);
25478 && TREE_CODE (decl
) == FUNCTION_DECL
25480 && DEFAULT_ABI
== ABI_AIX
)
25482 rtx sym_ref
= XEXP (rtl
, 0);
25483 size_t len
= strlen (XSTR (sym_ref
, 0));
25484 char *str
= XALLOCAVEC (char, len
+ 2);
25486 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
25487 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
25492 compare_section_name (const char *section
, const char *templ
)
25496 len
= strlen (templ
);
25497 return (strncmp (section
, templ
, len
) == 0
25498 && (section
[len
] == 0 || section
[len
] == '.'));
25502 rs6000_elf_in_small_data_p (const_tree decl
)
25504 if (rs6000_sdata
== SDATA_NONE
)
25507 /* We want to merge strings, so we never consider them small data. */
25508 if (TREE_CODE (decl
) == STRING_CST
)
25511 /* Functions are never in the small data area. */
25512 if (TREE_CODE (decl
) == FUNCTION_DECL
)
25515 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
25517 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
25518 if (compare_section_name (section
, ".sdata")
25519 || compare_section_name (section
, ".sdata2")
25520 || compare_section_name (section
, ".gnu.linkonce.s")
25521 || compare_section_name (section
, ".sbss")
25522 || compare_section_name (section
, ".sbss2")
25523 || compare_section_name (section
, ".gnu.linkonce.sb")
25524 || strcmp (section
, ".PPC.EMB.sdata0") == 0
25525 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
25530 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
25533 && size
<= g_switch_value
25534 /* If it's not public, and we're not going to reference it there,
25535 there's no need to put it in the small data section. */
25536 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
25543 #endif /* USING_ELFOS_H */
25545 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25548 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
25550 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
25553 /* Return a REG that occurs in ADDR with coefficient 1.
25554 ADDR can be effectively incremented by incrementing REG.
25556 r0 is special and we must not select it as an address
25557 register by this routine since our caller will try to
25558 increment the returned register via an "la" instruction. */
25561 find_addr_reg (rtx addr
)
25563 while (GET_CODE (addr
) == PLUS
)
25565 if (GET_CODE (XEXP (addr
, 0)) == REG
25566 && REGNO (XEXP (addr
, 0)) != 0)
25567 addr
= XEXP (addr
, 0);
25568 else if (GET_CODE (XEXP (addr
, 1)) == REG
25569 && REGNO (XEXP (addr
, 1)) != 0)
25570 addr
= XEXP (addr
, 1);
25571 else if (CONSTANT_P (XEXP (addr
, 0)))
25572 addr
= XEXP (addr
, 1);
25573 else if (CONSTANT_P (XEXP (addr
, 1)))
25574 addr
= XEXP (addr
, 0);
25576 gcc_unreachable ();
25578 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
25583 rs6000_fatal_bad_address (rtx op
)
25585 fatal_insn ("bad address", op
);
25590 typedef struct branch_island_d
{
25591 tree function_name
;
25596 DEF_VEC_O(branch_island
);
25597 DEF_VEC_ALLOC_O(branch_island
,gc
);
25599 static VEC(branch_island
,gc
) *branch_islands
;
25601 /* Remember to generate a branch island for far calls to the given
25605 add_compiler_branch_island (tree label_name
, tree function_name
,
25608 branch_island
*bi
= VEC_safe_push (branch_island
, gc
, branch_islands
, NULL
);
25610 bi
->function_name
= function_name
;
25611 bi
->label_name
= label_name
;
25612 bi
->line_number
= line_number
;
25615 /* Generate far-jump branch islands for everything recorded in
25616 branch_islands. Invoked immediately after the last instruction of
25617 the epilogue has been emitted; the branch islands must be appended
25618 to, and contiguous with, the function body. Mach-O stubs are
25619 generated in machopic_output_stub(). */
25622 macho_branch_islands (void)
25626 while (!VEC_empty (branch_island
, branch_islands
))
25628 branch_island
*bi
= VEC_last (branch_island
, branch_islands
);
25629 const char *label
= IDENTIFIER_POINTER (bi
->label_name
);
25630 const char *name
= IDENTIFIER_POINTER (bi
->function_name
);
25631 char name_buf
[512];
25632 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25633 if (name
[0] == '*' || name
[0] == '&')
25634 strcpy (name_buf
, name
+1);
25638 strcpy (name_buf
+1, name
);
25640 strcpy (tmp_buf
, "\n");
25641 strcat (tmp_buf
, label
);
25642 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25643 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25644 dbxout_stabd (N_SLINE
, bi
->line_number
);
25645 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25648 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
25649 strcat (tmp_buf
, label
);
25650 strcat (tmp_buf
, "_pic\n");
25651 strcat (tmp_buf
, label
);
25652 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
25654 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
25655 strcat (tmp_buf
, name_buf
);
25656 strcat (tmp_buf
, " - ");
25657 strcat (tmp_buf
, label
);
25658 strcat (tmp_buf
, "_pic)\n");
25660 strcat (tmp_buf
, "\tmtlr r0\n");
25662 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
25663 strcat (tmp_buf
, name_buf
);
25664 strcat (tmp_buf
, " - ");
25665 strcat (tmp_buf
, label
);
25666 strcat (tmp_buf
, "_pic)\n");
25668 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
25672 strcat (tmp_buf
, ":\nlis r12,hi16(");
25673 strcat (tmp_buf
, name_buf
);
25674 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
25675 strcat (tmp_buf
, name_buf
);
25676 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
25678 output_asm_insn (tmp_buf
, 0);
25679 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25680 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25681 dbxout_stabd (N_SLINE
, bi
->line_number
);
25682 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25683 VEC_pop (branch_island
, branch_islands
);
25687 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25688 already there or not. */
25691 no_previous_def (tree function_name
)
25696 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25697 if (function_name
== bi
->function_name
)
25702 /* GET_PREV_LABEL gets the label name from the previous definition of
25706 get_prev_label (tree function_name
)
25711 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25712 if (function_name
== bi
->function_name
)
25713 return bi
->label_name
;
25717 /* INSN is either a function call or a millicode call. It may have an
25718 unconditional jump in its delay slot.
25720 CALL_DEST is the routine we are calling. */
25723 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
25724 int cookie_operand_number
)
25726 static char buf
[256];
25727 if (darwin_emit_branch_islands
25728 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
25729 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
25732 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
25734 if (no_previous_def (funname
))
25736 rtx label_rtx
= gen_label_rtx ();
25737 char *label_buf
, temp_buf
[256];
25738 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
25739 CODE_LABEL_NUMBER (label_rtx
));
25740 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
25741 labelname
= get_identifier (label_buf
);
25742 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
25745 labelname
= get_prev_label (funname
);
25747 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25748 instruction will reach 'foo', otherwise link as 'bl L42'".
25749 "L42" should be a 'branch island', that will do a far jump to
25750 'foo'. Branch islands are generated in
25751 macho_branch_islands(). */
25752 sprintf (buf
, "jbsr %%z%d,%.246s",
25753 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
25756 sprintf (buf
, "bl %%z%d", dest_operand_number
);
25760 /* Generate PIC and indirect symbol stubs. */
25763 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
25765 unsigned int length
;
25766 char *symbol_name
, *lazy_ptr_name
;
25767 char *local_label_0
;
25768 static int label
= 0;
25770 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25771 symb
= (*targetm
.strip_name_encoding
) (symb
);
25774 length
= strlen (symb
);
25775 symbol_name
= XALLOCAVEC (char, length
+ 32);
25776 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
25778 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
25779 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
25782 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
25784 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
25788 fprintf (file
, "\t.align 5\n");
25790 fprintf (file
, "%s:\n", stub
);
25791 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25794 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25795 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
25797 fprintf (file
, "\tmflr r0\n");
25798 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
25799 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
25800 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
25801 lazy_ptr_name
, local_label_0
);
25802 fprintf (file
, "\tmtlr r0\n");
25803 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
25804 (TARGET_64BIT
? "ldu" : "lwzu"),
25805 lazy_ptr_name
, local_label_0
);
25806 fprintf (file
, "\tmtctr r12\n");
25807 fprintf (file
, "\tbctr\n");
25811 fprintf (file
, "\t.align 4\n");
25813 fprintf (file
, "%s:\n", stub
);
25814 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25816 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
25817 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
25818 (TARGET_64BIT
? "ldu" : "lwzu"),
25820 fprintf (file
, "\tmtctr r12\n");
25821 fprintf (file
, "\tbctr\n");
25824 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
25825 fprintf (file
, "%s:\n", lazy_ptr_name
);
25826 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25827 fprintf (file
, "%sdyld_stub_binding_helper\n",
25828 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
25831 /* Legitimize PIC addresses. If the address is already
25832 position-independent, we return ORIG. Newly generated
25833 position-independent addresses go into a reg. This is REG if non
25834 zero, otherwise we allocate register(s) as necessary. */
25836 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25839 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
25844 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
25845 reg
= gen_reg_rtx (Pmode
);
25847 if (GET_CODE (orig
) == CONST
)
25851 if (GET_CODE (XEXP (orig
, 0)) == PLUS
25852 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
25855 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
25857 /* Use a different reg for the intermediate value, as
25858 it will be marked UNCHANGING. */
25859 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
25860 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
25863 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
25866 if (GET_CODE (offset
) == CONST_INT
)
25868 if (SMALL_INT (offset
))
25869 return plus_constant (base
, INTVAL (offset
));
25870 else if (! reload_in_progress
&& ! reload_completed
)
25871 offset
= force_reg (Pmode
, offset
);
25874 rtx mem
= force_const_mem (Pmode
, orig
);
25875 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
25878 return gen_rtx_PLUS (Pmode
, base
, offset
);
25881 /* Fall back on generic machopic code. */
25882 return machopic_legitimize_pic_address (orig
, mode
, reg
);
25885 /* Output a .machine directive for the Darwin assembler, and call
25886 the generic start_file routine. */
25889 rs6000_darwin_file_start (void)
25891 static const struct
25897 { "ppc64", "ppc64", MASK_64BIT
},
25898 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
25899 { "power4", "ppc970", 0 },
25900 { "G5", "ppc970", 0 },
25901 { "7450", "ppc7450", 0 },
25902 { "7400", "ppc7400", MASK_ALTIVEC
},
25903 { "G4", "ppc7400", 0 },
25904 { "750", "ppc750", 0 },
25905 { "740", "ppc750", 0 },
25906 { "G3", "ppc750", 0 },
25907 { "604e", "ppc604e", 0 },
25908 { "604", "ppc604", 0 },
25909 { "603e", "ppc603", 0 },
25910 { "603", "ppc603", 0 },
25911 { "601", "ppc601", 0 },
25912 { NULL
, "ppc", 0 } };
25913 const char *cpu_id
= "";
25916 rs6000_file_start ();
25917 darwin_file_start ();
25919 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25920 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
25921 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
25922 && rs6000_select
[i
].string
[0] != '\0')
25923 cpu_id
= rs6000_select
[i
].string
;
25925 /* Look through the mapping array. Pick the first name that either
25926 matches the argument, has a bit set in IF_SET that is also set
25927 in the target flags, or has a NULL name. */
25930 while (mapping
[i
].arg
!= NULL
25931 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
25932 && (mapping
[i
].if_set
& target_flags
) == 0)
25935 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
25938 #endif /* TARGET_MACHO */
25942 rs6000_elf_reloc_rw_mask (void)
25946 else if (DEFAULT_ABI
== ABI_AIX
)
25952 /* Record an element in the table of global constructors. SYMBOL is
25953 a SYMBOL_REF of the function to be called; PRIORITY is a number
25954 between 0 and MAX_INIT_PRIORITY.
25956 This differs from default_named_section_asm_out_constructor in
25957 that we have special handling for -mrelocatable. */
25960 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
25962 const char *section
= ".ctors";
25965 if (priority
!= DEFAULT_INIT_PRIORITY
)
25967 sprintf (buf
, ".ctors.%.5u",
25968 /* Invert the numbering so the linker puts us in the proper
25969 order; constructors are run from right to left, and the
25970 linker sorts in increasing order. */
25971 MAX_INIT_PRIORITY
- priority
);
25975 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25976 assemble_align (POINTER_SIZE
);
25978 if (TARGET_RELOCATABLE
)
25980 fputs ("\t.long (", asm_out_file
);
25981 output_addr_const (asm_out_file
, symbol
);
25982 fputs (")@fixup\n", asm_out_file
);
25985 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25989 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
25991 const char *section
= ".dtors";
25994 if (priority
!= DEFAULT_INIT_PRIORITY
)
25996 sprintf (buf
, ".dtors.%.5u",
25997 /* Invert the numbering so the linker puts us in the proper
25998 order; constructors are run from right to left, and the
25999 linker sorts in increasing order. */
26000 MAX_INIT_PRIORITY
- priority
);
26004 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
26005 assemble_align (POINTER_SIZE
);
26007 if (TARGET_RELOCATABLE
)
26009 fputs ("\t.long (", asm_out_file
);
26010 output_addr_const (asm_out_file
, symbol
);
26011 fputs (")@fixup\n", asm_out_file
);
26014 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
26018 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
26022 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
26023 ASM_OUTPUT_LABEL (file
, name
);
26024 fputs (DOUBLE_INT_ASM_OP
, file
);
26025 rs6000_output_function_entry (file
, name
);
26026 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
26029 fputs ("\t.size\t", file
);
26030 assemble_name (file
, name
);
26031 fputs (",24\n\t.type\t.", file
);
26032 assemble_name (file
, name
);
26033 fputs (",@function\n", file
);
26034 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
26036 fputs ("\t.globl\t.", file
);
26037 assemble_name (file
, name
);
26042 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
26043 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
26044 rs6000_output_function_entry (file
, name
);
26045 fputs (":\n", file
);
26049 if (TARGET_RELOCATABLE
26050 && !TARGET_SECURE_PLT
26051 && (get_pool_size () != 0 || crtl
->profile
)
26056 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
26058 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
26059 fprintf (file
, "\t.long ");
26060 assemble_name (file
, buf
);
26062 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
26063 assemble_name (file
, buf
);
26067 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
26068 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
26070 if (DEFAULT_ABI
== ABI_AIX
)
26072 const char *desc_name
, *orig_name
;
26074 orig_name
= (*targetm
.strip_name_encoding
) (name
);
26075 desc_name
= orig_name
;
26076 while (*desc_name
== '.')
26079 if (TREE_PUBLIC (decl
))
26080 fprintf (file
, "\t.globl %s\n", desc_name
);
26082 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
26083 fprintf (file
, "%s:\n", desc_name
);
26084 fprintf (file
, "\t.long %s\n", orig_name
);
26085 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
26086 if (DEFAULT_ABI
== ABI_AIX
)
26087 fputs ("\t.long 0\n", file
);
26088 fprintf (file
, "\t.previous\n");
26090 ASM_OUTPUT_LABEL (file
, name
);
26094 rs6000_elf_file_end (void)
26096 #ifdef HAVE_AS_GNU_ATTRIBUTE
26097 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
26099 if (rs6000_passes_float
)
26100 fprintf (asm_out_file
, "\t.gnu_attribute 4, %d\n",
26101 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
26102 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
26104 if (rs6000_passes_vector
)
26105 fprintf (asm_out_file
, "\t.gnu_attribute 8, %d\n",
26106 (TARGET_ALTIVEC_ABI
? 2
26107 : TARGET_SPE_ABI
? 3
26109 if (rs6000_returns_struct
)
26110 fprintf (asm_out_file
, "\t.gnu_attribute 12, %d\n",
26111 aix_struct_return
? 2 : 1);
26114 #ifdef POWERPC_LINUX
26116 file_end_indicate_exec_stack ();
26123 rs6000_xcoff_asm_output_anchor (rtx symbol
)
26127 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
26128 SYMBOL_REF_BLOCK_OFFSET (symbol
));
26129 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
26133 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
26135 fputs (GLOBAL_ASM_OP
, stream
);
26136 RS6000_OUTPUT_BASENAME (stream
, name
);
26137 putc ('\n', stream
);
26140 /* A get_unnamed_decl callback, used for read-only sections. PTR
26141 points to the section string variable. */
26144 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
26146 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
26147 *(const char *const *) directive
,
26148 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
26151 /* Likewise for read-write sections. */
26154 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
26156 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
26157 *(const char *const *) directive
,
26158 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
26161 /* A get_unnamed_section callback, used for switching to toc_section. */
26164 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
26166 if (TARGET_MINIMAL_TOC
)
26168 /* toc_section is always selected at least once from
26169 rs6000_xcoff_file_start, so this is guaranteed to
26170 always be defined once and only once in each file. */
26171 if (!toc_initialized
)
26173 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
26174 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
26175 toc_initialized
= 1;
26177 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
26178 (TARGET_32BIT
? "" : ",3"));
26181 fputs ("\t.toc\n", asm_out_file
);
26184 /* Implement TARGET_ASM_INIT_SECTIONS. */
26187 rs6000_xcoff_asm_init_sections (void)
26189 read_only_data_section
26190 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
26191 &xcoff_read_only_section_name
);
26193 private_data_section
26194 = get_unnamed_section (SECTION_WRITE
,
26195 rs6000_xcoff_output_readwrite_section_asm_op
,
26196 &xcoff_private_data_section_name
);
26198 read_only_private_data_section
26199 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
26200 &xcoff_private_data_section_name
);
26203 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
26205 readonly_data_section
= read_only_data_section
;
26206 exception_section
= data_section
;
26210 rs6000_xcoff_reloc_rw_mask (void)
26216 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
26217 tree decl ATTRIBUTE_UNUSED
)
26220 static const char * const suffix
[3] = { "PR", "RO", "RW" };
26222 if (flags
& SECTION_CODE
)
26224 else if (flags
& SECTION_WRITE
)
26229 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
26230 (flags
& SECTION_CODE
) ? "." : "",
26231 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
26235 rs6000_xcoff_select_section (tree decl
, int reloc
,
26236 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
26238 if (decl_readonly_section (decl
, reloc
))
26240 if (TREE_PUBLIC (decl
))
26241 return read_only_data_section
;
26243 return read_only_private_data_section
;
26247 if (TREE_PUBLIC (decl
))
26248 return data_section
;
26250 return private_data_section
;
26255 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
26259 /* Use select_section for private and uninitialized data. */
26260 if (!TREE_PUBLIC (decl
)
26261 || DECL_COMMON (decl
)
26262 || DECL_INITIAL (decl
) == NULL_TREE
26263 || DECL_INITIAL (decl
) == error_mark_node
26264 || (flag_zero_initialized_in_bss
26265 && initializer_zerop (DECL_INITIAL (decl
))))
26268 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
26269 name
= (*targetm
.strip_name_encoding
) (name
);
26270 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
26273 /* Select section for constant in constant pool.
26275 On RS/6000, all constants are in the private read-only data area.
26276 However, if this is being placed in the TOC it must be output as a
26280 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
26281 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
26283 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
26284 return toc_section
;
26286 return read_only_private_data_section
;
26289 /* Remove any trailing [DS] or the like from the symbol name. */
26291 static const char *
26292 rs6000_xcoff_strip_name_encoding (const char *name
)
26297 len
= strlen (name
);
26298 if (name
[len
- 1] == ']')
26299 return ggc_alloc_string (name
, len
- 4);
26304 /* Section attributes. AIX is always PIC. */
26306 static unsigned int
26307 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
26309 unsigned int align
;
26310 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
26312 /* Align to at least UNIT size. */
26313 if (flags
& SECTION_CODE
)
26314 align
= MIN_UNITS_PER_WORD
;
26316 /* Increase alignment of large objects if not already stricter. */
26317 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
26318 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
26319 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
26321 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
26324 /* Output at beginning of assembler file.
26326 Initialize the section names for the RS/6000 at this point.
26328 Specify filename, including full path, to assembler.
26330 We want to go into the TOC section so at least one .toc will be emitted.
26331 Also, in order to output proper .bs/.es pairs, we need at least one static
26332 [RW] section emitted.
26334 Finally, declare mcount when profiling to make the assembler happy. */
26337 rs6000_xcoff_file_start (void)
26339 rs6000_gen_section_name (&xcoff_bss_section_name
,
26340 main_input_filename
, ".bss_");
26341 rs6000_gen_section_name (&xcoff_private_data_section_name
,
26342 main_input_filename
, ".rw_");
26343 rs6000_gen_section_name (&xcoff_read_only_section_name
,
26344 main_input_filename
, ".ro_");
26346 fputs ("\t.file\t", asm_out_file
);
26347 output_quoted_string (asm_out_file
, main_input_filename
);
26348 fputc ('\n', asm_out_file
);
26349 if (write_symbols
!= NO_DEBUG
)
26350 switch_to_section (private_data_section
);
26351 switch_to_section (text_section
);
26353 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
26354 rs6000_file_start ();
26357 /* Output at end of assembler file.
26358 On the RS/6000, referencing data should automatically pull in text. */
26361 rs6000_xcoff_file_end (void)
26363 switch_to_section (text_section
);
26364 fputs ("_section_.text:\n", asm_out_file
);
26365 switch_to_section (data_section
);
26366 fputs (TARGET_32BIT
26367 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26370 #endif /* TARGET_XCOFF */
26372 /* Compute a (partial) cost for rtx X. Return true if the complete
26373 cost has been computed, and false if subexpressions should be
26374 scanned. In either case, *TOTAL contains the cost result. */
26377 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
26380 enum machine_mode mode
= GET_MODE (x
);
26384 /* On the RS/6000, if it is valid in the insn, it is free. */
26386 if (((outer_code
== SET
26387 || outer_code
== PLUS
26388 || outer_code
== MINUS
)
26389 && (satisfies_constraint_I (x
)
26390 || satisfies_constraint_L (x
)))
26391 || (outer_code
== AND
26392 && (satisfies_constraint_K (x
)
26394 ? satisfies_constraint_L (x
)
26395 : satisfies_constraint_J (x
))
26396 || mask_operand (x
, mode
)
26398 && mask64_operand (x
, DImode
))))
26399 || ((outer_code
== IOR
|| outer_code
== XOR
)
26400 && (satisfies_constraint_K (x
)
26402 ? satisfies_constraint_L (x
)
26403 : satisfies_constraint_J (x
))))
26404 || outer_code
== ASHIFT
26405 || outer_code
== ASHIFTRT
26406 || outer_code
== LSHIFTRT
26407 || outer_code
== ROTATE
26408 || outer_code
== ROTATERT
26409 || outer_code
== ZERO_EXTRACT
26410 || (outer_code
== MULT
26411 && satisfies_constraint_I (x
))
26412 || ((outer_code
== DIV
|| outer_code
== UDIV
26413 || outer_code
== MOD
|| outer_code
== UMOD
)
26414 && exact_log2 (INTVAL (x
)) >= 0)
26415 || (outer_code
== COMPARE
26416 && (satisfies_constraint_I (x
)
26417 || satisfies_constraint_K (x
)))
26418 || ((outer_code
== EQ
|| outer_code
== NE
)
26419 && (satisfies_constraint_I (x
)
26420 || satisfies_constraint_K (x
)
26422 ? satisfies_constraint_L (x
)
26423 : satisfies_constraint_J (x
))))
26424 || (outer_code
== GTU
26425 && satisfies_constraint_I (x
))
26426 || (outer_code
== LTU
26427 && satisfies_constraint_P (x
)))
26432 else if ((outer_code
== PLUS
26433 && reg_or_add_cint_operand (x
, VOIDmode
))
26434 || (outer_code
== MINUS
26435 && reg_or_sub_cint_operand (x
, VOIDmode
))
26436 || ((outer_code
== SET
26437 || outer_code
== IOR
26438 || outer_code
== XOR
)
26440 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
26442 *total
= COSTS_N_INSNS (1);
26448 if (mode
== DImode
&& code
== CONST_DOUBLE
)
26450 if ((outer_code
== IOR
|| outer_code
== XOR
)
26451 && CONST_DOUBLE_HIGH (x
) == 0
26452 && (CONST_DOUBLE_LOW (x
)
26453 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
26458 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
26459 || ((outer_code
== SET
26460 || outer_code
== IOR
26461 || outer_code
== XOR
)
26462 && CONST_DOUBLE_HIGH (x
) == 0))
26464 *total
= COSTS_N_INSNS (1);
26474 /* When optimizing for size, MEM should be slightly more expensive
26475 than generating address, e.g., (plus (reg) (const)).
26476 L1 cache latency is about two instructions. */
26477 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26486 if (FLOAT_MODE_P (mode
))
26487 *total
= rs6000_cost
->fp
;
26489 *total
= COSTS_N_INSNS (1);
26493 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
26494 && satisfies_constraint_I (XEXP (x
, 1)))
26496 if (INTVAL (XEXP (x
, 1)) >= -256
26497 && INTVAL (XEXP (x
, 1)) <= 255)
26498 *total
= rs6000_cost
->mulsi_const9
;
26500 *total
= rs6000_cost
->mulsi_const
;
26502 else if (mode
== SFmode
)
26503 *total
= rs6000_cost
->fp
;
26504 else if (FLOAT_MODE_P (mode
))
26505 *total
= rs6000_cost
->dmul
;
26506 else if (mode
== DImode
)
26507 *total
= rs6000_cost
->muldi
;
26509 *total
= rs6000_cost
->mulsi
;
26513 if (mode
== SFmode
)
26514 *total
= rs6000_cost
->fp
;
26516 *total
= rs6000_cost
->dmul
;
26521 if (FLOAT_MODE_P (mode
))
26523 *total
= mode
== DFmode
? rs6000_cost
->ddiv
26524 : rs6000_cost
->sdiv
;
26531 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
26532 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
26534 if (code
== DIV
|| code
== MOD
)
26536 *total
= COSTS_N_INSNS (2);
26539 *total
= COSTS_N_INSNS (1);
26543 if (GET_MODE (XEXP (x
, 1)) == DImode
)
26544 *total
= rs6000_cost
->divdi
;
26546 *total
= rs6000_cost
->divsi
;
26548 /* Add in shift and subtract for MOD. */
26549 if (code
== MOD
|| code
== UMOD
)
26550 *total
+= COSTS_N_INSNS (2);
26555 *total
= COSTS_N_INSNS (4);
26559 *total
= COSTS_N_INSNS (TARGET_POPCNTD
? 1 : 6);
26563 *total
= COSTS_N_INSNS (TARGET_CMPB
? 2 : 6);
26567 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
26579 *total
= COSTS_N_INSNS (1);
26587 /* Handle mul_highpart. */
26588 if (outer_code
== TRUNCATE
26589 && GET_CODE (XEXP (x
, 0)) == MULT
)
26591 if (mode
== DImode
)
26592 *total
= rs6000_cost
->muldi
;
26594 *total
= rs6000_cost
->mulsi
;
26597 else if (outer_code
== AND
)
26600 *total
= COSTS_N_INSNS (1);
26605 if (GET_CODE (XEXP (x
, 0)) == MEM
)
26608 *total
= COSTS_N_INSNS (1);
26614 if (!FLOAT_MODE_P (mode
))
26616 *total
= COSTS_N_INSNS (1);
26622 case UNSIGNED_FLOAT
:
26625 case FLOAT_TRUNCATE
:
26626 *total
= rs6000_cost
->fp
;
26630 if (mode
== DFmode
)
26633 *total
= rs6000_cost
->fp
;
26637 switch (XINT (x
, 1))
26640 *total
= rs6000_cost
->fp
;
26652 *total
= COSTS_N_INSNS (1);
26655 else if (FLOAT_MODE_P (mode
)
26656 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26658 *total
= rs6000_cost
->fp
;
26666 /* Carry bit requires mode == Pmode.
26667 NEG or PLUS already counted so only add one. */
26669 && (outer_code
== NEG
|| outer_code
== PLUS
))
26671 *total
= COSTS_N_INSNS (1);
26674 if (outer_code
== SET
)
26676 if (XEXP (x
, 1) == const0_rtx
)
26678 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26679 *total
= COSTS_N_INSNS (8);
26681 *total
= COSTS_N_INSNS (2);
26684 else if (mode
== Pmode
)
26686 *total
= COSTS_N_INSNS (3);
26695 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
26697 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26698 *total
= COSTS_N_INSNS (8);
26700 *total
= COSTS_N_INSNS (2);
26704 if (outer_code
== COMPARE
)
26718 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26721 rs6000_debug_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
26724 bool ret
= rs6000_rtx_costs (x
, code
, outer_code
, total
, speed
);
26727 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26728 "total = %d, speed = %s, x:\n",
26729 ret
? "complete" : "scan inner",
26730 GET_RTX_NAME (code
),
26731 GET_RTX_NAME (outer_code
),
26733 speed
? "true" : "false");
26740 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26743 rs6000_debug_address_cost (rtx x
, bool speed
)
26745 int ret
= TARGET_ADDRESS_COST (x
, speed
);
26747 fprintf (stderr
, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26748 ret
, speed
? "true" : "false");
26755 /* A C expression returning the cost of moving data from a register of class
26756 CLASS1 to one of CLASS2. */
26759 rs6000_register_move_cost (enum machine_mode mode
,
26760 reg_class_t from
, reg_class_t to
)
26764 /* Moves from/to GENERAL_REGS. */
26765 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
26766 || reg_classes_intersect_p (from
, GENERAL_REGS
))
26768 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
26771 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
|| from
== VSX_REGS
)
26772 ret
= (rs6000_memory_move_cost (mode
, from
, false)
26773 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, false));
26775 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26777 else if (from
== CR_REGS
)
26780 /* Power6 has slower LR/CTR moves so make them more expensive than
26781 memory in order to bias spills to memory .*/
26782 else if (rs6000_cpu
== PROCESSOR_POWER6
26783 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
26784 ret
= 6 * hard_regno_nregs
[0][mode
];
26787 /* A move will cost one instruction per GPR moved. */
26788 ret
= 2 * hard_regno_nregs
[0][mode
];
26791 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26792 else if (VECTOR_UNIT_VSX_P (mode
)
26793 && reg_classes_intersect_p (to
, VSX_REGS
)
26794 && reg_classes_intersect_p (from
, VSX_REGS
))
26795 ret
= 2 * hard_regno_nregs
[32][mode
];
26797 /* Moving between two similar registers is just one instruction. */
26798 else if (reg_classes_intersect_p (to
, from
))
26799 ret
= (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
26801 /* Everything else has to go through GENERAL_REGS. */
26803 ret
= (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
26804 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
26806 if (TARGET_DEBUG_COST
)
26808 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26809 ret
, GET_MODE_NAME (mode
), reg_class_names
[from
],
26810 reg_class_names
[to
]);
26815 /* A C expressions returning the cost of moving data of MODE from a register to
26819 rs6000_memory_move_cost (enum machine_mode mode
, reg_class_t rclass
,
26820 bool in ATTRIBUTE_UNUSED
)
26824 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
26825 ret
= 4 * hard_regno_nregs
[0][mode
];
26826 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
26827 ret
= 4 * hard_regno_nregs
[32][mode
];
26828 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
26829 ret
= 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
26831 ret
= 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
26833 if (TARGET_DEBUG_COST
)
26835 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26836 ret
, GET_MODE_NAME (mode
), reg_class_names
[rclass
], in
);
26841 /* Returns a code for a target-specific builtin that implements
26842 reciprocal of the function, or NULL_TREE if not available. */
26845 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
26846 bool sqrt ATTRIBUTE_UNUSED
)
26848 if (optimize_insn_for_size_p ())
26854 case VSX_BUILTIN_XVSQRTDP
:
26855 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode
))
26858 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
26860 case VSX_BUILTIN_XVSQRTSP
:
26861 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode
))
26864 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V4SF
];
26873 case BUILT_IN_SQRT
:
26874 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode
))
26877 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRT
];
26879 case BUILT_IN_SQRTF
:
26880 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode
))
26883 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
26890 /* Load up a constant. If the mode is a vector mode, splat the value across
26891 all of the vector elements. */
26894 rs6000_load_constant_and_splat (enum machine_mode mode
, REAL_VALUE_TYPE dconst
)
26898 if (mode
== SFmode
|| mode
== DFmode
)
26900 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, mode
);
26901 reg
= force_reg (mode
, d
);
26903 else if (mode
== V4SFmode
)
26905 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, SFmode
);
26906 rtvec v
= gen_rtvec (4, d
, d
, d
, d
);
26907 reg
= gen_reg_rtx (mode
);
26908 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26910 else if (mode
== V2DFmode
)
26912 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, DFmode
);
26913 rtvec v
= gen_rtvec (2, d
, d
);
26914 reg
= gen_reg_rtx (mode
);
26915 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26918 gcc_unreachable ();
26923 /* Generate an FMA instruction. */
26926 rs6000_emit_madd (rtx target
, rtx m1
, rtx m2
, rtx a
)
26928 enum machine_mode mode
= GET_MODE (target
);
26931 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26932 gcc_assert (dst
!= NULL
);
26935 emit_move_insn (target
, dst
);
26938 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26941 rs6000_emit_msub (rtx target
, rtx m1
, rtx m2
, rtx a
)
26943 enum machine_mode mode
= GET_MODE (target
);
26946 /* Altivec does not support fms directly;
26947 generate in terms of fma in that case. */
26948 if (optab_handler (fms_optab
, mode
) != CODE_FOR_nothing
)
26949 dst
= expand_ternary_op (mode
, fms_optab
, m1
, m2
, a
, target
, 0);
26952 a
= expand_unop (mode
, neg_optab
, a
, NULL_RTX
, 0);
26953 dst
= expand_ternary_op (mode
, fma_optab
, m1
, m2
, a
, target
, 0);
26955 gcc_assert (dst
!= NULL
);
26958 emit_move_insn (target
, dst
);
26961 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26964 rs6000_emit_nmsub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26966 enum machine_mode mode
= GET_MODE (dst
);
26969 /* This is a tad more complicated, since the fnma_optab is for
26970 a different expression: fma(-m1, m2, a), which is the same
26971 thing except in the case of signed zeros.
26973 Fortunately we know that if FMA is supported that FNMSUB is
26974 also supported in the ISA. Just expand it directly. */
26976 gcc_assert (optab_handler (fma_optab
, mode
) != CODE_FOR_nothing
);
26978 r
= gen_rtx_NEG (mode
, a
);
26979 r
= gen_rtx_FMA (mode
, m1
, m2
, r
);
26980 r
= gen_rtx_NEG (mode
, r
);
26981 emit_insn (gen_rtx_SET (VOIDmode
, dst
, r
));
26984 /* Newton-Raphson approximation of floating point divide with just 2 passes
26985 (either single precision floating point, or newer machines with higher
26986 accuracy estimates). Support both scalar and vector divide. Assumes no
26987 trapping math and finite arguments. */
26990 rs6000_emit_swdiv_high_precision (rtx dst
, rtx n
, rtx d
)
26992 enum machine_mode mode
= GET_MODE (dst
);
26993 rtx x0
, e0
, e1
, y1
, u0
, v0
;
26994 enum insn_code code
= optab_handler (smul_optab
, mode
);
26995 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26996 rtx one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26998 gcc_assert (code
!= CODE_FOR_nothing
);
27000 /* x0 = 1./d estimate */
27001 x0
= gen_reg_rtx (mode
);
27002 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
27003 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
27006 e0
= gen_reg_rtx (mode
);
27007 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - (d * x0) */
27009 e1
= gen_reg_rtx (mode
);
27010 rs6000_emit_madd (e1
, e0
, e0
, e0
); /* e1 = (e0 * e0) + e0 */
27012 y1
= gen_reg_rtx (mode
);
27013 rs6000_emit_madd (y1
, e1
, x0
, x0
); /* y1 = (e1 * x0) + x0 */
27015 u0
= gen_reg_rtx (mode
);
27016 emit_insn (gen_mul (u0
, n
, y1
)); /* u0 = n * y1 */
27018 v0
= gen_reg_rtx (mode
);
27019 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - (d * u0) */
27021 rs6000_emit_madd (dst
, v0
, y1
, u0
); /* dst = (v0 * y1) + u0 */
27024 /* Newton-Raphson approximation of floating point divide that has a low
27025 precision estimate. Assumes no trapping math and finite arguments. */
27028 rs6000_emit_swdiv_low_precision (rtx dst
, rtx n
, rtx d
)
27030 enum machine_mode mode
= GET_MODE (dst
);
27031 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
27032 enum insn_code code
= optab_handler (smul_optab
, mode
);
27033 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
27035 gcc_assert (code
!= CODE_FOR_nothing
);
27037 one
= rs6000_load_constant_and_splat (mode
, dconst1
);
27039 /* x0 = 1./d estimate */
27040 x0
= gen_reg_rtx (mode
);
27041 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
27042 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
27045 e0
= gen_reg_rtx (mode
);
27046 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - d * x0 */
27048 y1
= gen_reg_rtx (mode
);
27049 rs6000_emit_madd (y1
, e0
, x0
, x0
); /* y1 = x0 + e0 * x0 */
27051 e1
= gen_reg_rtx (mode
);
27052 emit_insn (gen_mul (e1
, e0
, e0
)); /* e1 = e0 * e0 */
27054 y2
= gen_reg_rtx (mode
);
27055 rs6000_emit_madd (y2
, e1
, y1
, y1
); /* y2 = y1 + e1 * y1 */
27057 e2
= gen_reg_rtx (mode
);
27058 emit_insn (gen_mul (e2
, e1
, e1
)); /* e2 = e1 * e1 */
27060 y3
= gen_reg_rtx (mode
);
27061 rs6000_emit_madd (y3
, e2
, y2
, y2
); /* y3 = y2 + e2 * y2 */
27063 u0
= gen_reg_rtx (mode
);
27064 emit_insn (gen_mul (u0
, n
, y3
)); /* u0 = n * y3 */
27066 v0
= gen_reg_rtx (mode
);
27067 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - d * u0 */
27069 rs6000_emit_madd (dst
, v0
, y3
, u0
); /* dst = u0 + v0 * y3 */
27072 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
27073 add a reg_note saying that this was a division. Support both scalar and
27074 vector divide. Assumes no trapping math and finite arguments. */
27077 rs6000_emit_swdiv (rtx dst
, rtx n
, rtx d
, bool note_p
)
27079 enum machine_mode mode
= GET_MODE (dst
);
27081 if (RS6000_RECIP_HIGH_PRECISION_P (mode
))
27082 rs6000_emit_swdiv_high_precision (dst
, n
, d
);
27084 rs6000_emit_swdiv_low_precision (dst
, n
, d
);
27087 add_reg_note (get_last_insn (), REG_EQUAL
, gen_rtx_DIV (mode
, n
, d
));
27090 /* Newton-Raphson approximation of single/double-precision floating point
27091 rsqrt. Assumes no trapping math and finite arguments. */
27094 rs6000_emit_swrsqrt (rtx dst
, rtx src
)
27096 enum machine_mode mode
= GET_MODE (src
);
27097 rtx x0
= gen_reg_rtx (mode
);
27098 rtx y
= gen_reg_rtx (mode
);
27099 int passes
= (TARGET_RECIP_PRECISION
) ? 2 : 3;
27100 REAL_VALUE_TYPE dconst3_2
;
27103 enum insn_code code
= optab_handler (smul_optab
, mode
);
27104 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
27106 gcc_assert (code
!= CODE_FOR_nothing
);
27108 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27109 real_from_integer (&dconst3_2
, VOIDmode
, 3, 0, 0);
27110 SET_REAL_EXP (&dconst3_2
, REAL_EXP (&dconst3_2
) - 1);
27112 halfthree
= rs6000_load_constant_and_splat (mode
, dconst3_2
);
27114 /* x0 = rsqrt estimate */
27115 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
27116 gen_rtx_UNSPEC (mode
, gen_rtvec (1, src
),
27119 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27120 rs6000_emit_msub (y
, src
, halfthree
, src
);
27122 for (i
= 0; i
< passes
; i
++)
27124 rtx x1
= gen_reg_rtx (mode
);
27125 rtx u
= gen_reg_rtx (mode
);
27126 rtx v
= gen_reg_rtx (mode
);
27128 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27129 emit_insn (gen_mul (u
, x0
, x0
));
27130 rs6000_emit_nmsub (v
, y
, u
, halfthree
);
27131 emit_insn (gen_mul (x1
, x0
, v
));
27135 emit_move_insn (dst
, x0
);
27139 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27140 (Power7) targets. DST is the target, and SRC is the argument operand. */
27143 rs6000_emit_popcount (rtx dst
, rtx src
)
27145 enum machine_mode mode
= GET_MODE (dst
);
27148 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27149 if (TARGET_POPCNTD
)
27151 if (mode
== SImode
)
27152 emit_insn (gen_popcntdsi2 (dst
, src
));
27154 emit_insn (gen_popcntddi2 (dst
, src
));
27158 tmp1
= gen_reg_rtx (mode
);
27160 if (mode
== SImode
)
27162 emit_insn (gen_popcntbsi2 (tmp1
, src
));
27163 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
27165 tmp2
= force_reg (SImode
, tmp2
);
27166 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
27170 emit_insn (gen_popcntbdi2 (tmp1
, src
));
27171 tmp2
= expand_mult (DImode
, tmp1
,
27172 GEN_INT ((HOST_WIDE_INT
)
27173 0x01010101 << 32 | 0x01010101),
27175 tmp2
= force_reg (DImode
, tmp2
);
27176 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
27181 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27182 target, and SRC is the argument operand. */
27185 rs6000_emit_parity (rtx dst
, rtx src
)
27187 enum machine_mode mode
= GET_MODE (dst
);
27190 tmp
= gen_reg_rtx (mode
);
27192 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27195 if (mode
== SImode
)
27197 emit_insn (gen_popcntbsi2 (tmp
, src
));
27198 emit_insn (gen_paritysi2_cmpb (dst
, tmp
));
27202 emit_insn (gen_popcntbdi2 (tmp
, src
));
27203 emit_insn (gen_paritydi2_cmpb (dst
, tmp
));
27208 if (mode
== SImode
)
27210 /* Is mult+shift >= shift+xor+shift+xor? */
27211 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
27213 rtx tmp1
, tmp2
, tmp3
, tmp4
;
27215 tmp1
= gen_reg_rtx (SImode
);
27216 emit_insn (gen_popcntbsi2 (tmp1
, src
));
27218 tmp2
= gen_reg_rtx (SImode
);
27219 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
27220 tmp3
= gen_reg_rtx (SImode
);
27221 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
27223 tmp4
= gen_reg_rtx (SImode
);
27224 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
27225 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
27228 rs6000_emit_popcount (tmp
, src
);
27229 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
27233 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27234 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
27236 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
27238 tmp1
= gen_reg_rtx (DImode
);
27239 emit_insn (gen_popcntbdi2 (tmp1
, src
));
27241 tmp2
= gen_reg_rtx (DImode
);
27242 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
27243 tmp3
= gen_reg_rtx (DImode
);
27244 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
27246 tmp4
= gen_reg_rtx (DImode
);
27247 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
27248 tmp5
= gen_reg_rtx (DImode
);
27249 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
27251 tmp6
= gen_reg_rtx (DImode
);
27252 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
27253 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
27256 rs6000_emit_popcount (tmp
, src
);
27257 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
27261 /* Return an RTX representing where to find the function value of a
27262 function returning MODE. */
27264 rs6000_complex_function_value (enum machine_mode mode
)
27266 unsigned int regno
;
27268 enum machine_mode inner
= GET_MODE_INNER (mode
);
27269 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
27271 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27272 regno
= FP_ARG_RETURN
;
27275 regno
= GP_ARG_RETURN
;
27277 /* 32-bit is OK since it'll go in r3/r4. */
27278 if (TARGET_32BIT
&& inner_bytes
>= 4)
27279 return gen_rtx_REG (mode
, regno
);
27282 if (inner_bytes
>= 8)
27283 return gen_rtx_REG (mode
, regno
);
27285 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
27287 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
27288 GEN_INT (inner_bytes
));
27289 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
27292 /* Target hook for TARGET_FUNCTION_VALUE.
27294 On the SPE, both FPs and vectors are returned in r3.
27296 On RS/6000 an integer value is in r3 and a floating-point value is in
27297 fp1, unless -msoft-float. */
27300 rs6000_function_value (const_tree valtype
,
27301 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
27302 bool outgoing ATTRIBUTE_UNUSED
)
27304 enum machine_mode mode
;
27305 unsigned int regno
;
27307 /* Special handling for structs in darwin64. */
27309 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype
), valtype
))
27311 CUMULATIVE_ARGS valcum
;
27315 valcum
.fregno
= FP_ARG_MIN_REG
;
27316 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
27317 /* Do a trial code generation as if this were going to be passed as
27318 an argument; if any part goes in memory, we return NULL. */
27319 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, true, /* retval= */ true);
27322 /* Otherwise fall through to standard ABI rules. */
27325 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
27327 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27328 return gen_rtx_PARALLEL (DImode
,
27330 gen_rtx_EXPR_LIST (VOIDmode
,
27331 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27333 gen_rtx_EXPR_LIST (VOIDmode
,
27334 gen_rtx_REG (SImode
,
27335 GP_ARG_RETURN
+ 1),
27338 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
27340 return gen_rtx_PARALLEL (DCmode
,
27342 gen_rtx_EXPR_LIST (VOIDmode
,
27343 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27345 gen_rtx_EXPR_LIST (VOIDmode
,
27346 gen_rtx_REG (SImode
,
27347 GP_ARG_RETURN
+ 1),
27349 gen_rtx_EXPR_LIST (VOIDmode
,
27350 gen_rtx_REG (SImode
,
27351 GP_ARG_RETURN
+ 2),
27353 gen_rtx_EXPR_LIST (VOIDmode
,
27354 gen_rtx_REG (SImode
,
27355 GP_ARG_RETURN
+ 3),
27359 mode
= TYPE_MODE (valtype
);
27360 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
27361 || POINTER_TYPE_P (valtype
))
27362 mode
= TARGET_32BIT
? SImode
: DImode
;
27364 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27365 /* _Decimal128 must use an even/odd register pair. */
27366 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
27367 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
27368 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
27369 regno
= FP_ARG_RETURN
;
27370 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
27371 && targetm
.calls
.split_complex_arg
)
27372 return rs6000_complex_function_value (mode
);
27373 else if (TREE_CODE (valtype
) == VECTOR_TYPE
27374 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
27375 && ALTIVEC_VECTOR_MODE (mode
))
27376 regno
= ALTIVEC_ARG_RETURN
;
27377 else if (TREE_CODE (valtype
) == VECTOR_TYPE
27378 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
27379 && VSX_VECTOR_MODE (mode
))
27380 regno
= ALTIVEC_ARG_RETURN
;
27381 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
27382 && (mode
== DFmode
|| mode
== DCmode
27383 || mode
== TFmode
|| mode
== TCmode
))
27384 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
27386 regno
= GP_ARG_RETURN
;
27388 return gen_rtx_REG (mode
, regno
);
27391 /* Define how to find the value returned by a library function
27392 assuming the value has mode MODE. */
27394 rs6000_libcall_value (enum machine_mode mode
)
27396 unsigned int regno
;
27398 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
27400 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27401 return gen_rtx_PARALLEL (DImode
,
27403 gen_rtx_EXPR_LIST (VOIDmode
,
27404 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
27406 gen_rtx_EXPR_LIST (VOIDmode
,
27407 gen_rtx_REG (SImode
,
27408 GP_ARG_RETURN
+ 1),
27412 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
27413 /* _Decimal128 must use an even/odd register pair. */
27414 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
27415 else if (SCALAR_FLOAT_MODE_P (mode
)
27416 && TARGET_HARD_FLOAT
&& TARGET_FPRS
27417 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
27418 regno
= FP_ARG_RETURN
;
27419 else if (ALTIVEC_VECTOR_MODE (mode
)
27420 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
27421 regno
= ALTIVEC_ARG_RETURN
;
27422 else if (VSX_VECTOR_MODE (mode
)
27423 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
)
27424 regno
= ALTIVEC_ARG_RETURN
;
27425 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
27426 return rs6000_complex_function_value (mode
);
27427 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
27428 && (mode
== DFmode
|| mode
== DCmode
27429 || mode
== TFmode
|| mode
== TCmode
))
27430 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
27432 regno
= GP_ARG_RETURN
;
27434 return gen_rtx_REG (mode
, regno
);
27438 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27439 Frame pointer elimination is automatically handled.
27441 For the RS/6000, if frame pointer elimination is being done, we would like
27442 to convert ap into fp, not sp.
27444 We need r30 if -mminimal-toc was specified, and there are constant pool
27448 rs6000_can_eliminate (const int from
, const int to
)
27450 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
27451 ? ! frame_pointer_needed
27452 : from
== RS6000_PIC_OFFSET_TABLE_REGNUM
27453 ? ! TARGET_MINIMAL_TOC
|| TARGET_NO_TOC
|| get_pool_size () == 0
27457 /* Define the offset between two registers, FROM to be eliminated and its
27458 replacement TO, at the start of a routine. */
27460 rs6000_initial_elimination_offset (int from
, int to
)
27462 rs6000_stack_t
*info
= rs6000_stack_info ();
27463 HOST_WIDE_INT offset
;
27465 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27466 offset
= info
->push_p
? 0 : -info
->total_size
;
27467 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27469 offset
= info
->push_p
? 0 : -info
->total_size
;
27470 if (FRAME_GROWS_DOWNWARD
)
27471 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
27473 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
27474 offset
= FRAME_GROWS_DOWNWARD
27475 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
27477 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
27478 offset
= info
->total_size
;
27479 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
27480 offset
= info
->push_p
? info
->total_size
: 0;
27481 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
27484 gcc_unreachable ();
27490 rs6000_dwarf_register_span (rtx reg
)
27494 unsigned regno
= REGNO (reg
);
27495 enum machine_mode mode
= GET_MODE (reg
);
27499 && (SPE_VECTOR_MODE (GET_MODE (reg
))
27500 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
27501 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
27506 regno
= REGNO (reg
);
27508 /* The duality of the SPE register size wreaks all kinds of havoc.
27509 This is a way of distinguishing r0 in 32-bits from r0 in
27511 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
27512 gcc_assert (words
<= 4);
27513 for (i
= 0; i
< words
; i
++, regno
++)
27515 if (BYTES_BIG_ENDIAN
)
27517 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
27518 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
27522 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
27523 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
27527 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
27530 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27533 rs6000_init_dwarf_reg_sizes_extra (tree address
)
27538 enum machine_mode mode
= TYPE_MODE (char_type_node
);
27539 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
27540 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
27541 rtx value
= gen_int_mode (4, mode
);
27543 for (i
= 1201; i
< 1232; i
++)
27545 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
27546 HOST_WIDE_INT offset
27547 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
27549 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
27554 /* Map internal gcc register numbers to DWARF2 register numbers. */
27557 rs6000_dbx_register_number (unsigned int regno
)
27559 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
27561 if (regno
== MQ_REGNO
)
27563 if (regno
== LR_REGNO
)
27565 if (regno
== CTR_REGNO
)
27567 if (CR_REGNO_P (regno
))
27568 return regno
- CR0_REGNO
+ 86;
27569 if (regno
== CA_REGNO
)
27570 return 101; /* XER */
27571 if (ALTIVEC_REGNO_P (regno
))
27572 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
27573 if (regno
== VRSAVE_REGNO
)
27575 if (regno
== VSCR_REGNO
)
27577 if (regno
== SPE_ACC_REGNO
)
27579 if (regno
== SPEFSCR_REGNO
)
27581 /* SPE high reg number. We get these values of regno from
27582 rs6000_dwarf_register_span. */
27583 gcc_assert (regno
>= 1200 && regno
< 1232);
27587 /* target hook eh_return_filter_mode */
27588 static enum machine_mode
27589 rs6000_eh_return_filter_mode (void)
27591 return TARGET_32BIT
? SImode
: word_mode
;
27594 /* Target hook for scalar_mode_supported_p. */
27596 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
27598 if (DECIMAL_FLOAT_MODE_P (mode
))
27599 return default_decimal_float_supported_p ();
27601 return default_scalar_mode_supported_p (mode
);
27604 /* Target hook for vector_mode_supported_p. */
27606 rs6000_vector_mode_supported_p (enum machine_mode mode
)
27609 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
27612 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
27615 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
27622 /* Target hook for invalid_arg_for_unprototyped_fn. */
27623 static const char *
27624 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
27626 return (!rs6000_darwin64_abi
27628 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
27629 && (funcdecl
== NULL_TREE
27630 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
27631 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
27632 ? N_("AltiVec argument passed to unprototyped function")
27636 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27637 setup by using __stack_chk_fail_local hidden function instead of
27638 calling __stack_chk_fail directly. Otherwise it is better to call
27639 __stack_chk_fail directly. */
27642 rs6000_stack_protect_fail (void)
27644 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
27645 ? default_hidden_stack_protect_fail ()
27646 : default_external_stack_protect_fail ();
27650 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
27651 int num_operands ATTRIBUTE_UNUSED
)
27653 if (rs6000_warn_cell_microcode
)
27656 int insn_code_number
= recog_memoized (insn
);
27657 location_t location
= locator_location (INSN_LOCATOR (insn
));
27659 /* Punt on insns we cannot recognize. */
27660 if (insn_code_number
< 0)
27663 temp
= get_insn_template (insn_code_number
, insn
);
27665 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
27666 warning_at (location
, OPT_mwarn_cell_microcode
,
27667 "emitting microcode insn %s\t[%s] #%d",
27668 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27669 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
27670 warning_at (location
, OPT_mwarn_cell_microcode
,
27671 "emitting conditional microcode insn %s\t[%s] #%d",
27672 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27677 /* Mask options that we want to support inside of attribute((target)) and
27678 #pragma GCC target operations. Note, we do not include things like
27679 64/32-bit, endianess, hard/soft floating point, etc. that would have
27680 different calling sequences. */
27682 struct rs6000_opt_mask
{
27683 const char *name
; /* option name */
27684 int mask
; /* mask to set */
27685 bool invert
; /* invert sense of mask */
27686 bool valid_target
; /* option is a target option */
27689 static struct rs6000_opt_mask
const rs6000_opt_masks
[] =
27691 { "altivec", MASK_ALTIVEC
, false, true },
27692 { "cmpb", MASK_CMPB
, false, true },
27693 { "dlmzb", MASK_DLMZB
, false, true },
27694 { "fprnd", MASK_FPRND
, false, true },
27695 { "hard-dfp", MASK_DFP
, false, true },
27696 { "isel", MASK_ISEL
, false, true },
27697 { "mfcrf", MASK_MFCRF
, false, true },
27698 { "mfpgpr", MASK_MFPGPR
, false, true },
27699 { "mulhw", MASK_MULHW
, false, true },
27700 { "multiple", MASK_MULTIPLE
, false, true },
27701 { "update", MASK_NO_UPDATE
, true , true },
27702 { "popcntb", MASK_POPCNTB
, false, true },
27703 { "popcntd", MASK_POPCNTD
, false, true },
27704 { "powerpc-gfxopt", MASK_PPC_GFXOPT
, false, true },
27705 { "powerpc-gpopt", MASK_PPC_GPOPT
, false, true },
27706 { "recip-precision", MASK_RECIP_PRECISION
, false, true },
27707 { "string", MASK_STRING
, false, true },
27708 { "vsx", MASK_VSX
, false, true },
27711 { "aix64", MASK_64BIT
, false, false },
27712 { "aix32", MASK_64BIT
, true, false },
27714 { "64", MASK_64BIT
, false, false },
27715 { "32", MASK_64BIT
, true, false },
27719 { "eabi", MASK_EABI
, false, false },
27721 #ifdef MASK_LITTLE_ENDIAN
27722 { "little", MASK_LITTLE_ENDIAN
, false, false },
27723 { "big", MASK_LITTLE_ENDIAN
, true, false },
27725 #ifdef MASK_RELOCATABLE
27726 { "relocatable", MASK_RELOCATABLE
, false, false },
27728 #ifdef MASK_STRICT_ALIGN
27729 { "strict-align", MASK_STRICT_ALIGN
, false, false },
27731 { "power", MASK_POWER
, false, false },
27732 { "power2", MASK_POWER2
, false, false },
27733 { "powerpc", MASK_POWERPC
, false, false },
27734 { "soft-float", MASK_SOFT_FLOAT
, false, false },
27735 { "string", MASK_STRING
, false, false },
27738 /* Option variables that we want to support inside attribute((target)) and
27739 #pragma GCC target operations. */
27741 struct rs6000_opt_var
{
27742 const char *name
; /* option name */
27743 size_t global_offset
; /* offset of the option in global_options. */
27744 size_t target_offset
; /* offset of the option in target optiosn. */
27747 static struct rs6000_opt_var
const rs6000_opt_vars
[] =
27750 offsetof (struct gcc_options
, x_TARGET_FRIZ
),
27751 offsetof (struct cl_target_option
, x_TARGET_FRIZ
), },
27752 { "avoid-indexed-addresses",
27753 offsetof (struct gcc_options
, x_TARGET_AVOID_XFORM
),
27754 offsetof (struct cl_target_option
, x_TARGET_AVOID_XFORM
) },
27756 offsetof (struct gcc_options
, x_rs6000_paired_float
),
27757 offsetof (struct cl_target_option
, x_rs6000_paired_float
), },
27759 offsetof (struct gcc_options
, x_rs6000_default_long_calls
),
27760 offsetof (struct cl_target_option
, x_rs6000_default_long_calls
), },
27763 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27764 parsing. Return true if there were no errors. */
27767 rs6000_inner_target_options (tree args
, bool attr_p
)
27771 if (args
== NULL_TREE
)
27774 else if (TREE_CODE (args
) == STRING_CST
)
27776 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27779 while ((q
= strtok (p
, ",")) != NULL
)
27781 bool error_p
= false;
27782 bool not_valid_p
= false;
27783 const char *cpu_opt
= NULL
;
27786 if (strncmp (q
, "cpu=", 4) == 0)
27788 int cpu_index
= rs6000_cpu_name_lookup (q
+4);
27789 if (cpu_index
>= 0)
27790 rs6000_cpu_index
= cpu_index
;
27797 else if (strncmp (q
, "tune=", 5) == 0)
27799 int tune_index
= rs6000_cpu_name_lookup (q
+5);
27800 if (tune_index
>= 0)
27801 rs6000_tune_index
= tune_index
;
27811 bool invert
= false;
27815 if (strncmp (r
, "no-", 3) == 0)
27821 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
27822 if (strcmp (r
, rs6000_opt_masks
[i
].name
) == 0)
27824 int mask
= rs6000_opt_masks
[i
].mask
;
27826 if (!rs6000_opt_masks
[i
].valid_target
)
27827 not_valid_p
= true;
27831 target_flags_explicit
|= mask
;
27833 if (rs6000_opt_masks
[i
].invert
)
27837 target_flags
&= ~mask
;
27839 target_flags
|= mask
;
27844 if (error_p
&& !not_valid_p
)
27846 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
27847 if (strcmp (r
, rs6000_opt_vars
[i
].name
) == 0)
27849 size_t j
= rs6000_opt_vars
[i
].global_offset
;
27850 ((int *) &global_options
)[j
] = !invert
;
27859 const char *eprefix
, *esuffix
;
27864 eprefix
= "__attribute__((__target__(";
27869 eprefix
= "#pragma GCC target ";
27874 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt
, eprefix
,
27876 else if (not_valid_p
)
27877 error ("%s\"%s\"%s is not allowed", eprefix
, q
, esuffix
);
27879 error ("%s\"%s\"%s is invalid", eprefix
, q
, esuffix
);
27884 else if (TREE_CODE (args
) == TREE_LIST
)
27888 tree value
= TREE_VALUE (args
);
27891 bool ret2
= rs6000_inner_target_options (value
, attr_p
);
27895 args
= TREE_CHAIN (args
);
27897 while (args
!= NULL_TREE
);
27901 gcc_unreachable ();
27906 /* Print out the target options as a list for -mdebug=target. */
27909 rs6000_debug_target_options (tree args
, const char *prefix
)
27911 if (args
== NULL_TREE
)
27912 fprintf (stderr
, "%s<NULL>", prefix
);
27914 else if (TREE_CODE (args
) == STRING_CST
)
27916 char *p
= ASTRDUP (TREE_STRING_POINTER (args
));
27919 while ((q
= strtok (p
, ",")) != NULL
)
27922 fprintf (stderr
, "%s\"%s\"", prefix
, q
);
27927 else if (TREE_CODE (args
) == TREE_LIST
)
27931 tree value
= TREE_VALUE (args
);
27934 rs6000_debug_target_options (value
, prefix
);
27937 args
= TREE_CHAIN (args
);
27939 while (args
!= NULL_TREE
);
27943 gcc_unreachable ();
27949 /* Hook to validate attribute((target("..."))). */
27952 rs6000_valid_attribute_p (tree fndecl
,
27953 tree
ARG_UNUSED (name
),
27957 struct cl_target_option cur_target
;
27959 tree old_optimize
= build_optimization_node ();
27960 tree new_target
, new_optimize
;
27961 tree func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27963 gcc_assert ((fndecl
!= NULL_TREE
) && (args
!= NULL_TREE
));
27965 if (TARGET_DEBUG_TARGET
)
27967 tree tname
= DECL_NAME (fndecl
);
27968 fprintf (stderr
, "\n==================== rs6000_valid_attribute_p:\n");
27970 fprintf (stderr
, "function: %.*s\n",
27971 (int) IDENTIFIER_LENGTH (tname
),
27972 IDENTIFIER_POINTER (tname
));
27974 fprintf (stderr
, "function: unknown\n");
27976 fprintf (stderr
, "args:");
27977 rs6000_debug_target_options (args
, " ");
27978 fprintf (stderr
, "\n");
27981 fprintf (stderr
, "flags: 0x%x\n", flags
);
27983 fprintf (stderr
, "--------------------\n");
27986 old_optimize
= build_optimization_node ();
27987 func_optimize
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
);
27989 /* If the function changed the optimization levels as well as setting target
27990 options, start with the optimizations specified. */
27991 if (func_optimize
&& func_optimize
!= old_optimize
)
27992 cl_optimization_restore (&global_options
,
27993 TREE_OPTIMIZATION (func_optimize
));
27995 /* The target attributes may also change some optimization flags, so update
27996 the optimization options if necessary. */
27997 cl_target_option_save (&cur_target
, &global_options
);
27998 rs6000_cpu_index
= rs6000_tune_index
= -1;
27999 ret
= rs6000_inner_target_options (args
, true);
28001 /* Set up any additional state. */
28004 ret
= rs6000_option_override_internal (false);
28005 new_target
= build_target_option_node ();
28010 new_optimize
= build_optimization_node ();
28017 DECL_FUNCTION_SPECIFIC_TARGET (fndecl
) = new_target
;
28019 if (old_optimize
!= new_optimize
)
28020 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl
) = new_optimize
;
28023 cl_target_option_restore (&global_options
, &cur_target
);
28025 if (old_optimize
!= new_optimize
)
28026 cl_optimization_restore (&global_options
,
28027 TREE_OPTIMIZATION (old_optimize
));
28033 /* Hook to validate the current #pragma GCC target and set the state, and
28034 update the macros based on what was changed. If ARGS is NULL, then
28035 POP_TARGET is used to reset the options. */
28038 rs6000_pragma_target_parse (tree args
, tree pop_target
)
28043 if (TARGET_DEBUG_TARGET
)
28045 fprintf (stderr
, "\n==================== rs6000_pragma_target_parse\n");
28046 fprintf (stderr
, "args:");
28047 rs6000_debug_target_options (args
, " ");
28048 fprintf (stderr
, "\n");
28052 fprintf (stderr
, "pop_target:\n");
28053 debug_tree (pop_target
);
28056 fprintf (stderr
, "pop_target: <NULL>\n");
28058 fprintf (stderr
, "--------------------\n");
28064 cur_tree
= ((pop_target
)
28066 : target_option_default_node
);
28067 cl_target_option_restore (&global_options
,
28068 TREE_TARGET_OPTION (cur_tree
));
28072 rs6000_cpu_index
= rs6000_tune_index
= -1;
28073 ret
= rs6000_inner_target_options (args
, false);
28074 cur_tree
= build_target_option_node ();
28081 target_option_current_node
= cur_tree
;
28087 /* Remember the last target of rs6000_set_current_function. */
28088 static GTY(()) tree rs6000_previous_fndecl
;
28090 /* Establish appropriate back-end context for processing the function
28091 FNDECL. The argument might be NULL to indicate processing at top
28092 level, outside of any function scope. */
28094 rs6000_set_current_function (tree fndecl
)
28096 tree old_tree
= (rs6000_previous_fndecl
28097 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl
)
28100 tree new_tree
= (fndecl
28101 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl
)
28104 if (TARGET_DEBUG_TARGET
)
28106 bool print_final
= false;
28107 fprintf (stderr
, "\n==================== rs6000_set_current_function");
28110 fprintf (stderr
, ", fndecl %s (%p)",
28111 (DECL_NAME (fndecl
)
28112 ? IDENTIFIER_POINTER (DECL_NAME (fndecl
))
28113 : "<unknown>"), (void *)fndecl
);
28115 if (rs6000_previous_fndecl
)
28116 fprintf (stderr
, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl
);
28118 fprintf (stderr
, "\n");
28121 fprintf (stderr
, "\nnew fndecl target specific options:\n");
28122 debug_tree (new_tree
);
28123 print_final
= true;
28128 fprintf (stderr
, "\nold fndecl target specific options:\n");
28129 debug_tree (old_tree
);
28130 print_final
= true;
28134 fprintf (stderr
, "--------------------\n");
28137 /* Only change the context if the function changes. This hook is called
28138 several times in the course of compiling a function, and we don't want to
28139 slow things down too much or call target_reinit when it isn't safe. */
28140 if (fndecl
&& fndecl
!= rs6000_previous_fndecl
)
28142 rs6000_previous_fndecl
= fndecl
;
28143 if (old_tree
== new_tree
)
28148 cl_target_option_restore (&global_options
,
28149 TREE_TARGET_OPTION (new_tree
));
28155 struct cl_target_option
*def
28156 = TREE_TARGET_OPTION (target_option_current_node
);
28158 cl_target_option_restore (&global_options
, def
);
28165 /* Save the current options */
28168 rs6000_function_specific_save (struct cl_target_option
*ptr
)
28170 ptr
->rs6000_target_flags_explicit
= target_flags_explicit
;
28173 /* Restore the current options */
28176 rs6000_function_specific_restore (struct cl_target_option
*ptr
)
28178 target_flags_explicit
= ptr
->rs6000_target_flags_explicit
;
28179 (void) rs6000_option_override_internal (false);
28182 /* Print the current options */
28185 rs6000_function_specific_print (FILE *file
, int indent
,
28186 struct cl_target_option
*ptr
)
28189 int flags
= ptr
->x_target_flags
;
28191 /* Print the various mask options. */
28192 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_masks
); i
++)
28193 if ((flags
& rs6000_opt_masks
[i
].mask
) != 0)
28195 flags
&= ~ rs6000_opt_masks
[i
].mask
;
28196 fprintf (file
, "%*s-m%s%s\n", indent
, "",
28197 rs6000_opt_masks
[i
].invert
? "no-" : "",
28198 rs6000_opt_masks
[i
].name
);
28201 /* Print the various options that are variables. */
28202 for (i
= 0; i
< ARRAY_SIZE (rs6000_opt_vars
); i
++)
28204 size_t j
= rs6000_opt_vars
[i
].target_offset
;
28205 if (((signed char *) ptr
)[j
])
28206 fprintf (file
, "%*s-m%s\n", indent
, "",
28207 rs6000_opt_vars
[i
].name
);
28212 /* Hook to determine if one function can safely inline another. */
28215 rs6000_can_inline_p (tree caller
, tree callee
)
28218 tree caller_tree
= DECL_FUNCTION_SPECIFIC_TARGET (caller
);
28219 tree callee_tree
= DECL_FUNCTION_SPECIFIC_TARGET (callee
);
28221 /* If callee has no option attributes, then it is ok to inline. */
28225 /* If caller has no option attributes, but callee does then it is not ok to
28227 else if (!caller_tree
)
28232 struct cl_target_option
*caller_opts
= TREE_TARGET_OPTION (caller_tree
);
28233 struct cl_target_option
*callee_opts
= TREE_TARGET_OPTION (callee_tree
);
28235 /* Callee's options should a subset of the caller's, i.e. a vsx function
28236 can inline an altivec function but a non-vsx function can't inline a
28238 if ((caller_opts
->x_target_flags
& callee_opts
->x_target_flags
)
28239 == callee_opts
->x_target_flags
)
28243 if (TARGET_DEBUG_TARGET
)
28244 fprintf (stderr
, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28245 (DECL_NAME (caller
)
28246 ? IDENTIFIER_POINTER (DECL_NAME (caller
))
28248 (DECL_NAME (callee
)
28249 ? IDENTIFIER_POINTER (DECL_NAME (callee
))
28251 (ret
? "can" : "cannot"));
28256 /* Allocate a stack temp and fixup the address so it meets the particular
28257 memory requirements (either offetable or REG+REG addressing). */
28260 rs6000_allocate_stack_temp (enum machine_mode mode
,
28261 bool offsettable_p
,
28264 rtx stack
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
28265 rtx addr
= XEXP (stack
, 0);
28266 int strict_p
= (reload_in_progress
|| reload_completed
);
28268 if (!legitimate_indirect_address_p (addr
, strict_p
))
28271 && !rs6000_legitimate_offset_address_p (mode
, addr
, strict_p
))
28272 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
28274 else if (reg_reg_p
&& !legitimate_indexed_address_p (addr
, strict_p
))
28275 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
28281 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28282 to such a form to deal with memory reference instructions like STFIWX that
28283 only take reg+reg addressing. */
28286 rs6000_address_for_fpconvert (rtx x
)
28288 int strict_p
= (reload_in_progress
|| reload_completed
);
28291 gcc_assert (MEM_P (x
));
28292 addr
= XEXP (x
, 0);
28293 if (! legitimate_indirect_address_p (addr
, strict_p
)
28294 && ! legitimate_indexed_address_p (addr
, strict_p
))
28296 if (GET_CODE (addr
) == PRE_INC
|| GET_CODE (addr
) == PRE_DEC
)
28298 rtx reg
= XEXP (addr
, 0);
28299 HOST_WIDE_INT size
= GET_MODE_SIZE (GET_MODE (x
));
28300 rtx size_rtx
= GEN_INT ((GET_CODE (addr
) == PRE_DEC
) ? -size
: size
);
28301 gcc_assert (REG_P (reg
));
28302 emit_insn (gen_add3_insn (reg
, reg
, size_rtx
));
28305 else if (GET_CODE (addr
) == PRE_MODIFY
)
28307 rtx reg
= XEXP (addr
, 0);
28308 rtx expr
= XEXP (addr
, 1);
28309 gcc_assert (REG_P (reg
));
28310 gcc_assert (GET_CODE (expr
) == PLUS
);
28311 emit_insn (gen_add3_insn (reg
, XEXP (expr
, 0), XEXP (expr
, 1)));
28315 x
= replace_equiv_address (x
, copy_addr_to_reg (addr
));
28321 /* Given a memory reference, if it is not in the form for altivec memory
28322 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28323 convert to the altivec format. */
28326 rs6000_address_for_altivec (rtx x
)
28328 gcc_assert (MEM_P (x
));
28329 if (!altivec_indexed_or_indirect_operand (x
, GET_MODE (x
)))
28331 rtx addr
= XEXP (x
, 0);
28332 int strict_p
= (reload_in_progress
|| reload_completed
);
28334 if (!legitimate_indexed_address_p (addr
, strict_p
)
28335 && !legitimate_indirect_address_p (addr
, strict_p
))
28336 addr
= copy_to_mode_reg (Pmode
, addr
);
28338 addr
= gen_rtx_AND (Pmode
, addr
, GEN_INT (-16));
28339 x
= change_address (x
, GET_MODE (x
), addr
);
28346 #include "gt-rs6000.h"